r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[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 2 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, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_RPC_PARSE
29
30
31 /*******************************************************************
32 This should be moved in a more generic lib.
33 ********************************************************************/  
34
35 BOOL spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
36 {
37         if(!prs_uint16("year", ps, depth, &systime->year))
38                 return False;
39         if(!prs_uint16("month", ps, depth, &systime->month))
40                 return False;
41         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
42                 return False;
43         if(!prs_uint16("day", ps, depth, &systime->day))
44                 return False;
45         if(!prs_uint16("hour", ps, depth, &systime->hour))
46                 return False;
47         if(!prs_uint16("minute", ps, depth, &systime->minute))
48                 return False;
49         if(!prs_uint16("second", ps, depth, &systime->second))
50                 return False;
51         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
52                 return False;
53
54         return True;
55 }
56
57 /*******************************************************************
58 ********************************************************************/  
59
60 BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
61 {
62         systime->year=unixtime->tm_year+1900;
63         systime->month=unixtime->tm_mon+1;
64         systime->dayofweek=unixtime->tm_wday;
65         systime->day=unixtime->tm_mday;
66         systime->hour=unixtime->tm_hour;
67         systime->minute=unixtime->tm_min;
68         systime->second=unixtime->tm_sec;
69         systime->milliseconds=0;
70
71         return True;
72 }
73
74 /*******************************************************************
75 reads or writes an DOC_INFO structure.
76 ********************************************************************/  
77
78 static BOOL smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
79 {
80         if (info_1 == NULL) return False;
81
82         prs_debug(ps, depth, desc, "smb_io_doc_info_1");
83         depth++;
84  
85         if(!prs_align(ps))
86                 return False;
87         
88         if(!prs_uint32("p_docname",    ps, depth, &info_1->p_docname))
89                 return False;
90         if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
91                 return False;
92         if(!prs_uint32("p_datatype",   ps, depth, &info_1->p_datatype))
93                 return False;
94
95         if(!smb_io_unistr2("", &info_1->docname,    info_1->p_docname,    ps, depth))
96                 return False;
97         if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
98                 return False;
99         if(!smb_io_unistr2("", &info_1->datatype,   info_1->p_datatype,   ps, depth))
100                 return False;
101
102         return True;
103 }
104
105 /*******************************************************************
106 reads or writes an DOC_INFO structure.
107 ********************************************************************/  
108
109 static BOOL smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
110 {
111         uint32 useless_ptr=0;
112         
113         if (info == NULL) return False;
114
115         prs_debug(ps, depth, desc, "smb_io_doc_info");
116         depth++;
117  
118         if(!prs_align(ps))
119                 return False;
120         
121         if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
122                 return False;
123         
124         if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
125                 return False;
126
127         switch (info->switch_value)
128         {
129                 case 1: 
130                         if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
131                                 return False;
132                         break;
133                 case 2:
134                         /*
135                           this is just a placeholder
136                           
137                           MSDN July 1998 says doc_info_2 is only on
138                           Windows 95, and as Win95 doesn't do RPC to print
139                           this case is nearly impossible
140                           
141                           Maybe one day with Windows for dishwasher 2037 ...
142                           
143                         */
144                         /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
145                         break;
146                 default:
147                         DEBUG(0,("Something is obviously wrong somewhere !\n"));
148                         break;
149         }
150
151         return True;
152 }
153
154 /*******************************************************************
155 reads or writes an DOC_INFO_CONTAINER structure.
156 ********************************************************************/  
157
158 static BOOL smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
159 {
160         if (cont == NULL) return False;
161
162         prs_debug(ps, depth, desc, "smb_io_doc_info_container");
163         depth++;
164  
165         if(!prs_align(ps))
166                 return False;
167         
168         if(!prs_uint32("level", ps, depth, &cont->level))
169                 return False;
170         
171         if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
172                 return False;
173
174         return True;
175 }
176
177 /*******************************************************************
178 reads or writes an NOTIFY OPTION TYPE structure.
179 ********************************************************************/  
180
181 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
182    structure.  The _TYPE structure is really the deferred referrants (i.e
183    the notify fields array) of the _TYPE structure. -tpot */
184
185 static BOOL smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
186 {
187         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
188         depth++;
189  
190         if (!prs_align(ps))
191                 return False;
192
193         if(!prs_uint16("type", ps, depth, &type->type))
194                 return False;
195         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
196                 return False;
197         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
198                 return False;
199         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
200                 return False;
201         if(!prs_uint32("count", ps, depth, &type->count))
202                 return False;
203         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
204                 return False;
205
206         return True;
207 }
208
209 /*******************************************************************
210 reads or writes an NOTIFY OPTION TYPE DATA.
211 ********************************************************************/  
212
213 static BOOL smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
214 {
215         int i;
216
217         prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
218         depth++;
219  
220         /* if there are no fields just return */
221         if (type->fields_ptr==0)
222                 return True;
223
224         if(!prs_align(ps))
225                 return False;
226
227         if(!prs_uint32("count2", ps, depth, &type->count2))
228                 return False;
229         
230         if (type->count2 != type->count)
231                 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
232
233         /* parse the option type data */
234         for(i=0;i<type->count2;i++)
235                 if(!prs_uint16("fields",ps,depth,&type->fields[i]))
236                         return False;
237         return True;
238 }
239
240 /*******************************************************************
241 reads or writes an NOTIFY OPTION structure.
242 ********************************************************************/  
243
244 static BOOL smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
245 {               
246         int i;
247         
248         prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
249         depth++;
250  
251         if(!prs_uint32("count", ps, depth, &ctr->count))
252                 return False;
253
254         /* reading */
255         if (UNMARSHALLING(ps))
256                 if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
257                         return False;
258                 
259         /* the option type struct */
260         for(i=0;i<ctr->count;i++)
261                 if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
262                         return False;
263
264         /* the type associated with the option type struct */
265         for(i=0;i<ctr->count;i++)
266                 if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
267                         return False;
268         
269         return True;
270 }
271
272 /*******************************************************************
273 reads or writes an NOTIFY OPTION structure.
274 ********************************************************************/  
275
276 static BOOL smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
277 {
278         prs_debug(ps, depth, desc, "smb_io_notify_option");
279         depth++;
280         
281         if(!prs_uint32("version", ps, depth, &option->version))
282                 return False;
283         if(!prs_uint32("flags", ps, depth, &option->flags))
284                 return False;
285         if(!prs_uint32("count", ps, depth, &option->count))
286                 return False;
287         if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
288                 return False;
289         
290         /* marshalling or unmarshalling, that would work */     
291         if (option->option_type_ptr!=0) {
292                 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
293                         return False;
294         }
295         else {
296                 option->ctr.type=NULL;
297                 option->ctr.count=0;
298         }
299         
300         return True;
301 }
302
303 /*******************************************************************
304 reads or writes an NOTIFY INFO DATA structure.
305 ********************************************************************/  
306
307 static BOOL smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
308 {
309         uint32 useless_ptr=0x0FF0ADDE;
310
311         prs_debug(ps, depth, desc, "smb_io_notify_info_data");
312         depth++;
313
314         if(!prs_align(ps))
315                 return False;
316         if(!prs_uint16("type",           ps, depth, &data->type))
317                 return False;
318         if(!prs_uint16("field",          ps, depth, &data->field))
319                 return False;
320
321         if(!prs_uint32("how many words", ps, depth, &data->size))
322                 return False;
323         if(!prs_uint32("id",             ps, depth, &data->id))
324                 return False;
325         if(!prs_uint32("how many words", ps, depth, &data->size))
326                 return False;
327
328         switch (data->enc_type) {
329
330                 /* One and two value data has two uint32 values */
331
332         case NOTIFY_ONE_VALUE:
333         case NOTIFY_TWO_VALUE:
334
335                 if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
336                         return False;
337                 if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
338                         return False;
339                 break;
340
341                 /* Pointers and strings have a string length and a
342                    pointer.  For a string the length is expressed as
343                    the number of uint16 characters plus a trailing
344                    \0\0. */
345
346         case NOTIFY_POINTER:
347
348                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
349                         return False;
350                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
351                         return False;
352
353                 break;
354
355         case NOTIFY_STRING:
356
357                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
358                         return False;
359
360                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
361                         return False;
362
363                 break;
364
365         case NOTIFY_SECDESC:
366                 if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
367                         return False;
368                 if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
369                         return False;
370                 
371                 break;
372
373         default:
374                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
375                           data->enc_type));
376                 break;
377         }
378
379         return True;
380 }
381
382 /*******************************************************************
383 reads or writes an NOTIFY INFO DATA structure.
384 ********************************************************************/  
385
386 BOOL smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
387                                      prs_struct *ps, int depth)
388 {
389         prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
390         depth++;
391         
392         if(!prs_align(ps))
393                 return False;
394
395         switch(data->enc_type) {
396
397                 /* No data for values */
398
399         case NOTIFY_ONE_VALUE:
400         case NOTIFY_TWO_VALUE:
401
402                 break;
403
404                 /* Strings start with a length in uint16s */
405
406         case NOTIFY_STRING:
407
408                 if (MARSHALLING(ps))
409                         data->notify_data.data.length /= 2;
410
411                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
412                         return False;
413
414                 if (UNMARSHALLING(ps)) {
415                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
416                                                                 data->notify_data.data.length);
417
418                         if (!data->notify_data.data.string) 
419                                 return False;
420                 }
421
422                 if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
423                                    data->notify_data.data.length))
424                         return False;
425
426                 if (MARSHALLING(ps))
427                         data->notify_data.data.length *= 2;
428
429                 break;
430
431         case NOTIFY_POINTER:
432
433                 if (UNMARSHALLING(ps)) {
434                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
435                                                                 data->notify_data.data.length);
436
437                         if (!data->notify_data.data.string) 
438                                 return False;
439                 }
440
441                 if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
442                         return False;
443
444                 break;
445
446         case NOTIFY_SECDESC:    
447                 if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
448                         return False;
449                 if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
450                         return False;
451                 break;
452
453         default:
454                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
455                           data->enc_type));
456                 break;
457         }
458
459 #if 0
460         if (isvalue==False) {
461
462                 /* length of string in unicode include \0 */
463                 x=data->notify_data.data.length+1;
464
465                 if (data->field != 16)
466                 if(!prs_uint32("string length", ps, depth, &x ))
467                         return False;
468
469                 if (MARSHALLING(ps)) {
470                         /* These are already in little endian format. Don't byte swap. */
471                         if (x == 1) {
472
473                                 /* No memory allocated for this string
474                                    therefore following the data.string
475                                    pointer is a bad idea.  Use a pointer to
476                                    the uint32 length union member to
477                                    provide a source for a unicode NULL */
478
479                                 if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) 
480                                         return False;
481                         } else {
482
483                                 if (data->field == 16)
484                                         x /= 2;
485
486                                 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
487                                         return False;
488                         }
489                 } else {
490
491                         /* Tallocate memory for string */
492
493                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
494                         if (!data->notify_data.data.string) 
495                                 return False;
496
497                         if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
498                                 return False;
499                 }
500         }
501
502 #endif
503
504 #if 0   /* JERRY */
505         /* Win2k does not seem to put this parse align here */
506         if(!prs_align(ps))
507                 return False;
508 #endif
509
510         return True;
511 }
512
513 /*******************************************************************
514 reads or writes an NOTIFY INFO structure.
515 ********************************************************************/  
516
517 static BOOL smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
518 {
519         int i;
520
521         prs_debug(ps, depth, desc, "smb_io_notify_info");
522         depth++;
523  
524         if(!prs_align(ps))
525                 return False;
526
527         if(!prs_uint32("count", ps, depth, &info->count))
528                 return False;
529         if(!prs_uint32("version", ps, depth, &info->version))
530                 return False;
531         if(!prs_uint32("flags", ps, depth, &info->flags))
532                 return False;
533         if(!prs_uint32("count", ps, depth, &info->count))
534                 return False;
535
536         for (i=0;i<info->count;i++) {
537                 if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
538                         return False;
539         }
540
541         /* now do the strings at the end of the stream */       
542         for (i=0;i<info->count;i++) {
543                 if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
544                         return False;
545         }
546
547         return True;
548 }
549
550 /*******************************************************************
551 ********************************************************************/  
552
553 BOOL spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
554 {
555         prs_debug(ps, depth, desc, "");
556         depth++;
557
558         if (!prs_align(ps))
559                 return False;
560
561         if (!prs_uint32("size", ps, depth, &q_u->size))
562                 return False;
563
564         if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
565                 return False;
566         if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
567                 return False;
568
569         if (!prs_uint32("build", ps, depth, &q_u->build))
570                 return False;
571         if (!prs_uint32("major", ps, depth, &q_u->major))
572                 return False;
573         if (!prs_uint32("minor", ps, depth, &q_u->minor))
574                 return False;
575         if (!prs_uint32("processor", ps, depth, &q_u->processor))
576                 return False;
577
578         if (!prs_io_unistr2("", ps, depth, q_u->client_name))
579                 return False;
580         if (!prs_align(ps))
581                 return False;
582
583         if (!prs_io_unistr2("", ps, depth, q_u->user_name))
584                 return False;
585
586         return True;
587 }
588
589 /*******************************************************************
590 ********************************************************************/  
591
592 static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
593 {
594         if (q_u==NULL)
595                 return False;
596
597         prs_debug(ps, depth, desc, "spool_io_user_level");
598         depth++;
599
600         if (!prs_align(ps))
601                 return False;
602
603         if (!prs_uint32("level", ps, depth, &q_u->level))
604                 return False;
605         
606         switch ( q_u->level ) 
607         {       
608                 case 1:
609                         if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, 
610                                 sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
611                         {
612                                 return False;
613                         }
614                         break;
615                 default:
616                         return False;   
617         }       
618
619         return True;
620 }
621
622 /*******************************************************************
623  * read or write a DEVICEMODE struct.
624  * on reading allocate memory for the private member
625  ********************************************************************/
626
627 #define DM_NUM_OPTIONAL_FIELDS          8
628
629 BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
630 {
631         int available_space;            /* size of the device mode left to parse */
632                                         /* only important on unmarshalling       */
633         int i = 0;
634         uint16 *unistr_buffer;
635         int j;
636                                         
637         struct optional_fields {
638                 fstring         name;
639                 uint32*         field;
640         } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
641                 { "icmmethod",          NULL },
642                 { "icmintent",          NULL },
643                 { "mediatype",          NULL },
644                 { "dithertype",         NULL },
645                 { "reserved1",          NULL },
646                 { "reserved2",          NULL },
647                 { "panningwidth",       NULL },
648                 { "panningheight",      NULL }
649         };
650
651         /* assign at run time to keep non-gcc compilers happy */
652
653         opt_fields[0].field = &devmode->icmmethod;
654         opt_fields[1].field = &devmode->icmintent;
655         opt_fields[2].field = &devmode->mediatype;
656         opt_fields[3].field = &devmode->dithertype;
657         opt_fields[4].field = &devmode->reserved1;
658         opt_fields[5].field = &devmode->reserved2;
659         opt_fields[6].field = &devmode->panningwidth;
660         opt_fields[7].field = &devmode->panningheight;
661                 
662         
663         prs_debug(ps, depth, desc, "spoolss_io_devmode");
664         depth++;
665
666         if (UNMARSHALLING(ps)) {
667                 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
668                 if (devmode->devicename.buffer == NULL)
669                         return False;
670                 unistr_buffer = devmode->devicename.buffer;
671         }
672         else {
673                 /* devicename is a static sized string but the buffer we set is not */
674                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
675                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
676                 for ( j=0; devmode->devicename.buffer[j]; j++ )
677                         unistr_buffer[j] = devmode->devicename.buffer[j];
678         }
679                 
680         if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
681                 return False;
682         
683         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
684                 return False;
685                 
686         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
687                 return False;
688         if (!prs_uint16("size",             ps, depth, &devmode->size))
689                 return False;
690         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
691                 return False;
692         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
693                 return False;
694         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
695                 return False;
696         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
697                 return False;
698         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
699                 return False;
700         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
701                 return False;
702         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
703                 return False;
704         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
705                 return False;
706         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
707                 return False;
708         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
709                 return False;
710         if (!prs_uint16("color",            ps, depth, &devmode->color))
711                 return False;
712         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
713                 return False;
714         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
715                 return False;
716         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
717                 return False;
718         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
719                 return False;
720
721         if (UNMARSHALLING(ps)) {
722                 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
723                 if (devmode->formname.buffer == NULL)
724                         return False;
725                 unistr_buffer = devmode->formname.buffer;
726         }
727         else {
728                 /* devicename is a static sized string but the buffer we set is not */
729                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
730                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
731                 for ( j=0; devmode->formname.buffer[j]; j++ )
732                         unistr_buffer[j] = devmode->formname.buffer[j];
733         }
734         
735         if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
736                 return False;
737         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
738                 return False;
739         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
740                 return False;
741         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
742                 return False;
743         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
744                 return False;
745         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
746                 return False;
747         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
748                 return False;
749         /* 
750          * every device mode I've ever seen on the wire at least has up 
751          * to the displayfrequency field.   --jerry (05-09-2002)
752          */
753          
754         /* add uint32's + uint16's + two UNICODE strings */
755          
756         available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
757         
758         /* Sanity check - we only have uint32's left tp parse */
759         
760         if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
761                 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
762                         available_space, devmode->size));
763                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
764                 return False;
765         }
766
767         /* 
768          * Conditional parsing.  Assume that the DeviceMode has been 
769          * zero'd by the caller. 
770          */
771         
772         while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
773         {
774                 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
775                 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
776                         return False;
777                 available_space -= sizeof(uint32);
778                 i++;
779         }        
780         
781         /* Sanity Check - we should no available space at this point unless 
782            MS changes the device mode structure */
783                 
784         if (available_space) {
785                 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
786                 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
787                         available_space, devmode->size));
788                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
789                 return False;
790         }
791
792
793         if (devmode->driverextra!=0) {
794                 if (UNMARSHALLING(ps)) {
795                         devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
796                         if(devmode->dev_private == NULL)
797                                 return False;
798                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
799                 }
800                         
801                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
802                 if (!prs_uint8s(False, "dev_private",  ps, depth,
803                                 devmode->dev_private, devmode->driverextra))
804                         return False;
805         }
806
807         return True;
808 }
809
810 /*******************************************************************
811  Read or write a DEVICEMODE container
812 ********************************************************************/  
813
814 static BOOL spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
815 {
816         if (dm_c==NULL)
817                 return False;
818
819         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
820         depth++;
821
822         if(!prs_align(ps))
823                 return False;
824         
825         if (!prs_uint32("size", ps, depth, &dm_c->size))
826                 return False;
827
828         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
829                 return False;
830
831         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
832                 if (UNMARSHALLING(ps))
833                         /* if while reading there is no DEVMODE ... */
834                         dm_c->devmode=NULL;
835                 return True;
836         }
837         
838         /* so we have a DEVICEMODE to follow */         
839         if (UNMARSHALLING(ps)) {
840                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
841                 dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
842                 if(dm_c->devmode == NULL)
843                         return False;
844         }
845         
846         /* this is bad code, shouldn't be there */
847         if (!prs_uint32("size", ps, depth, &dm_c->size))
848                 return False;
849                 
850         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
851                 return False;
852
853         return True;
854 }
855
856 /*******************************************************************
857 ********************************************************************/  
858
859 static BOOL spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
860 {
861         if (pd==NULL)
862                 return False;
863
864         prs_debug(ps, depth, desc, "spoolss_io_printer_default");
865         depth++;
866
867         if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
868                 return False;
869
870         if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
871                 return False;
872         
873         if (!prs_align(ps))
874                 return False;
875
876         if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
877                 return False;
878
879         if (!prs_align(ps))
880                 return False;
881
882         if (!prs_uint32("access_required", ps, depth, &pd->access_required))
883                 return False;
884
885         return True;
886 }
887
888 /*******************************************************************
889  * init a structure.
890  ********************************************************************/
891
892 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
893                 const fstring printername, 
894                 const fstring datatype, 
895                 uint32 access_required,
896                 const fstring clientname,
897                 const fstring user_name)
898 {
899         DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
900
901         q_u->printername = TALLOC_P( get_talloc_ctx(), UNISTR2 );
902         if (!q_u->printername) {
903                 return False;
904         }
905         init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
906
907         q_u->printer_default.datatype_ptr = 0;
908
909         q_u->printer_default.devmode_cont.size=0;
910         q_u->printer_default.devmode_cont.devmode_ptr=0;
911         q_u->printer_default.devmode_cont.devmode=NULL;
912         q_u->printer_default.access_required=access_required;
913
914         q_u->user_switch = 1;
915         
916         q_u->user_ctr.level                 = 1;
917         q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
918         if (!q_u->user_ctr.user.user1) {
919                 return False;
920         }
921         q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
922         q_u->user_ctr.user.user1->build     = 1381;
923         q_u->user_ctr.user.user1->major     = 2;
924         q_u->user_ctr.user.user1->minor     = 0;
925         q_u->user_ctr.user.user1->processor = 0;
926
927         q_u->user_ctr.user.user1->client_name = TALLOC_P( get_talloc_ctx(), UNISTR2 );
928         if (!q_u->user_ctr.user.user1->client_name) {
929                 return False;
930         }
931         q_u->user_ctr.user.user1->user_name   = TALLOC_P( get_talloc_ctx(), UNISTR2 );
932         if (!q_u->user_ctr.user.user1->user_name) {
933                 return False;
934         }
935
936         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
937         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
938         
939         return True;
940 }
941
942 /*******************************************************************
943  * init a structure.
944  ********************************************************************/
945
946 BOOL make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
947         const char *srv_name, const char* clientname, const char* user_name,
948         uint32 level, PRINTER_INFO_CTR *ctr)
949 {
950         DEBUG(5,("make_spoolss_q_addprinterex\n"));
951         
952         if (!ctr || !ctr->printers_2) 
953                 return False;
954
955         ZERO_STRUCTP(q_u);
956
957         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
958         if (!q_u->server_name) {
959                 return False;
960         }
961         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
962
963         q_u->level = level;
964         
965         q_u->info.level = level;
966         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
967         switch (level) {
968                 case 2:
969                         /* init q_u->info.info2 from *info */
970                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
971                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
972                                 return False;
973                         }
974                         break;
975                 default :
976                         break;
977         }
978
979         q_u->user_switch=1;
980
981         q_u->user_ctr.level                 = 1;
982         q_u->user_ctr.user.user1            = TALLOC_P( get_talloc_ctx(), SPOOL_USER_1 );
983         if (!q_u->user_ctr.user.user1) {
984                 return False;
985         }
986         q_u->user_ctr.user.user1->build     = 1381;
987         q_u->user_ctr.user.user1->major     = 2; 
988         q_u->user_ctr.user.user1->minor     = 0;
989         q_u->user_ctr.user.user1->processor = 0;
990
991         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
992         if (!q_u->user_ctr.user.user1->client_name) {
993                 return False;
994         }
995         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
996         if (!q_u->user_ctr.user.user1->user_name) {
997                 return False;
998         }
999         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
1000         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
1001
1002         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
1003                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
1004         
1005         return True;
1006 }
1007         
1008 /*******************************************************************
1009 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
1010 *******************************************************************/
1011
1012 BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
1013                                 PRINTER_INFO_2 *info)
1014 {
1015
1016         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
1017
1018         /* allocate the necessary memory */
1019         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
1020                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
1021                 return False;
1022         }
1023         
1024         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
1025         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
1026         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
1027         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
1028         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
1029         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
1030         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
1031         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
1032         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
1033         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
1034         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
1035         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
1036         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1037         inf->attributes         = info->attributes;
1038         inf->priority           = info->priority;
1039         inf->default_priority   = info->defaultpriority;
1040         inf->starttime          = info->starttime;
1041         inf->untiltime          = info->untiltime;
1042         inf->cjobs              = info->cjobs;
1043         inf->averageppm = info->averageppm;
1044         init_unistr2_from_unistr(&inf->servername,      &info->servername);
1045         init_unistr2_from_unistr(&inf->printername,     &info->printername);
1046         init_unistr2_from_unistr(&inf->sharename,       &info->sharename);
1047         init_unistr2_from_unistr(&inf->portname,        &info->portname);
1048         init_unistr2_from_unistr(&inf->drivername,      &info->drivername);
1049         init_unistr2_from_unistr(&inf->comment,         &info->comment);
1050         init_unistr2_from_unistr(&inf->location,        &info->location);
1051         init_unistr2_from_unistr(&inf->sepfile,         &info->sepfile);
1052         init_unistr2_from_unistr(&inf->printprocessor,  &info->printprocessor);
1053         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
1054         init_unistr2_from_unistr(&inf->parameters,      &info->parameters);
1055         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
1056
1057         *spool_info2 = inf;
1058
1059         return True;
1060 }
1061
1062 /*******************************************************************
1063 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
1064 *******************************************************************/
1065
1066 BOOL make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
1067                                 PRINTER_INFO_3 *info)
1068 {
1069
1070         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
1071
1072         /* allocate the necessary memory */
1073         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
1074                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
1075                 return False;
1076         }
1077         
1078         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1079
1080         *spool_info3 = inf;
1081
1082         return True;
1083 }
1084
1085 /*******************************************************************
1086 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
1087 *******************************************************************/
1088
1089 BOOL make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
1090                                 PRINTER_INFO_7 *info)
1091 {
1092
1093         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
1094
1095         /* allocate the necessary memory */
1096         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
1097                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
1098                 return False;
1099         }
1100
1101         inf->guid_ptr           = (info->guid.buffer!=NULL)?1:0;
1102         inf->action             = info->action;
1103         init_unistr2_from_unistr(&inf->guid,            &info->guid);
1104
1105         *spool_info7 = inf;
1106
1107         return True;
1108 }
1109
1110
1111 /*******************************************************************
1112  * read a structure.
1113  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1114  ********************************************************************/
1115
1116 BOOL spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1117 {
1118         if (q_u == NULL)
1119                 return False;
1120
1121         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1122         depth++;
1123
1124         if (!prs_align(ps))
1125                 return False;
1126
1127         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1128                 return False;
1129         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1130                 return False;
1131         
1132         if (!prs_align(ps))
1133                 return False;
1134
1135         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1136                 return False;
1137                 
1138         return True;
1139 }
1140
1141 /*******************************************************************
1142  * write a structure.
1143  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1144  * called from spoolss_open_printer_ex (cli_spoolss.c)
1145  ********************************************************************/
1146
1147 BOOL spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1148 {
1149         if (r_u == NULL) return False;
1150
1151         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1152         depth++;
1153         
1154         if (!prs_align(ps))
1155                 return False;
1156
1157         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1158                 return False;   
1159
1160         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1161                 return False;
1162                 
1163         return True;
1164 }
1165
1166
1167 /*******************************************************************
1168  * read a structure.
1169  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1170  ********************************************************************/
1171
1172 BOOL spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1173 {
1174         if (q_u == NULL)
1175                 return False;
1176
1177         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1178         depth++;
1179
1180         if (!prs_align(ps))
1181                 return False;
1182
1183         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1184                 return False;
1185         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1186                 return False;
1187         
1188         if (!prs_align(ps))
1189                 return False;
1190
1191         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1192                 return False;
1193
1194         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1195                 return False;   
1196         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1197                 return False;
1198         
1199         return True;
1200 }
1201
1202 /*******************************************************************
1203  * write a structure.
1204  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1205  * called from spoolss_open_printer_ex (cli_spoolss.c)
1206  ********************************************************************/
1207
1208 BOOL spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1209 {
1210         if (r_u == NULL) return False;
1211
1212         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1213         depth++;
1214         
1215         if (!prs_align(ps))
1216                 return False;
1217
1218         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1219                 return False;
1220
1221         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1222                 return False;
1223
1224         return True;
1225 }
1226
1227 /*******************************************************************
1228  * init a structure.
1229  ********************************************************************/
1230 BOOL make_spoolss_q_deleteprinterdriverex( TALLOC_CTX *mem_ctx,
1231                                            SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, 
1232                                            const char *server,
1233                                            const char* arch, 
1234                                            const char* driver,
1235                                            int version)
1236 {
1237         DEBUG(5,("make_spoolss_q_deleteprinterdriverex\n"));
1238  
1239         q_u->server_ptr = (server!=NULL)?1:0;
1240         q_u->delete_flags = DPD_DELETE_UNUSED_FILES;
1241  
1242         /* these must be NULL terminated or else NT4 will
1243            complain about invalid parameters --jerry */
1244         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1245         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1246         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1247
1248         if (version >= 0) { 
1249                 q_u->delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1250                 q_u->version = version;
1251         }
1252
1253         return True;
1254 }
1255
1256
1257 /*******************************************************************
1258  * init a structure.
1259  ********************************************************************/
1260 BOOL make_spoolss_q_deleteprinterdriver(
1261         TALLOC_CTX *mem_ctx,
1262         SPOOL_Q_DELETEPRINTERDRIVER *q_u, 
1263         const char *server,
1264         const char* arch, 
1265         const char* driver 
1266 )
1267 {
1268         DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1269         
1270         q_u->server_ptr = (server!=NULL)?1:0;
1271
1272         /* these must be NULL terminated or else NT4 will
1273            complain about invalid parameters --jerry */
1274         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1275         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1276         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1277         
1278         return True;
1279 }
1280
1281 /*******************************************************************
1282  * make a structure.
1283  ********************************************************************/
1284
1285 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1286                                    const POLICY_HND *handle,
1287                                    const char *valuename, uint32 size)
1288 {
1289         if (q_u == NULL) return False;
1290
1291         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1292
1293         q_u->handle = *handle;
1294         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1295         q_u->size = size;
1296
1297         return True;
1298 }
1299
1300 /*******************************************************************
1301  * make a structure.
1302  ********************************************************************/
1303
1304 BOOL make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
1305                                      const POLICY_HND *handle,
1306                                      const char *keyname, 
1307                                      const char *valuename, uint32 size)
1308 {
1309         if (q_u == NULL) return False;
1310
1311         DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
1312
1313         q_u->handle = *handle;
1314         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1315         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
1316         q_u->size = size;
1317
1318         return True;
1319 }
1320
1321 /*******************************************************************
1322  * read a structure.
1323  * called from spoolss_q_getprinterdata (srv_spoolss.c)
1324  ********************************************************************/
1325
1326 BOOL spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1327 {
1328         if (q_u == NULL)
1329                 return False;
1330
1331         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1332         depth++;
1333
1334         if (!prs_align(ps))
1335                 return False;
1336         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1337                 return False;
1338         if (!prs_align(ps))
1339                 return False;
1340         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1341                 return False;
1342         if (!prs_align(ps))
1343                 return False;
1344         if (!prs_uint32("size", ps, depth, &q_u->size))
1345                 return False;
1346
1347         return True;
1348 }
1349
1350 /*******************************************************************
1351  * read a structure.
1352  * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1353  ********************************************************************/
1354
1355 BOOL spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1356 {
1357         if (q_u == NULL)
1358                 return False;
1359
1360         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1361         depth++;
1362
1363         if (!prs_align(ps))
1364                 return False;
1365         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1366                 return False;
1367         if (!prs_align(ps))
1368                 return False;
1369         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1370                 return False;
1371
1372         return True;
1373 }
1374
1375 /*******************************************************************
1376  * write a structure.
1377  * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1378  ********************************************************************/
1379
1380 BOOL spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1381 {
1382         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1383         depth++;
1384         if(!prs_werror("status", ps, depth, &r_u->status))
1385                 return False;
1386
1387         return True;
1388 }
1389
1390 /*******************************************************************
1391  * read a structure.
1392  * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
1393  ********************************************************************/
1394
1395 BOOL spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1396 {
1397         if (q_u == NULL)
1398                 return False;
1399
1400         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
1401         depth++;
1402
1403         if (!prs_align(ps))
1404                 return False;
1405         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1406                 return False;
1407         
1408         if (!smb_io_unistr2("keyname  ", &q_u->keyname, True, ps, depth))
1409                 return False;
1410         if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
1411                 return False;
1412
1413         return True;
1414 }
1415
1416 /*******************************************************************
1417  * write a structure.
1418  * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
1419  ********************************************************************/
1420
1421 BOOL spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1422 {
1423         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
1424         depth++;
1425         
1426         if(!prs_werror("status", ps, depth, &r_u->status))
1427                 return False;
1428
1429         return True;
1430 }
1431
1432 /*******************************************************************
1433  * write a structure.
1434  * called from spoolss_r_getprinterdata (srv_spoolss.c)
1435  ********************************************************************/
1436
1437 BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1438 {
1439         if (r_u == NULL)
1440                 return False;
1441
1442         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1443         depth++;
1444
1445         if (!prs_align(ps))
1446                 return False;
1447         if (!prs_uint32("type", ps, depth, &r_u->type))
1448                 return False;
1449         if (!prs_uint32("size", ps, depth, &r_u->size))
1450                 return False;
1451         
1452         if (UNMARSHALLING(ps) && r_u->size) {
1453                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
1454                 if(!r_u->data)
1455                         return False;
1456         }
1457
1458         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1459                 return False;
1460                 
1461         if (!prs_align(ps))
1462                 return False;
1463         
1464         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1465                 return False;
1466         if (!prs_werror("status", ps, depth, &r_u->status))
1467                 return False;
1468                 
1469         return True;
1470 }
1471
1472 /*******************************************************************
1473  * make a structure.
1474  ********************************************************************/
1475
1476 BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1477 {
1478         if (q_u == NULL) return False;
1479
1480         DEBUG(5,("make_spoolss_q_closeprinter\n"));
1481
1482         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1483
1484         return True;
1485 }
1486
1487 /*******************************************************************
1488  * read a structure.
1489  * called from static spoolss_q_abortprinter (srv_spoolss.c)
1490  * called from spoolss_abortprinter (cli_spoolss.c)
1491  ********************************************************************/
1492
1493 BOOL spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1494 {
1495         if (q_u == NULL) return False;
1496
1497         prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1498         depth++;
1499
1500         if (!prs_align(ps))
1501                 return False;
1502
1503         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1504                 return False;
1505
1506         return True;
1507 }
1508
1509 /*******************************************************************
1510  * write a structure.
1511  * called from spoolss_r_abortprinter (srv_spoolss.c)
1512  ********************************************************************/
1513
1514 BOOL spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1515 {
1516         prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1517         depth++;
1518         if(!prs_werror("status", ps, depth, &r_u->status))
1519                 return False;
1520
1521         return True;
1522 }
1523
1524 /*******************************************************************
1525  * read a structure.
1526  * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1527  * called from spoolss_deleteprinter (cli_spoolss.c)
1528  ********************************************************************/
1529
1530 BOOL spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1531 {
1532         if (q_u == NULL) return False;
1533
1534         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1535         depth++;
1536
1537         if (!prs_align(ps))
1538                 return False;
1539
1540         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1541                 return False;
1542
1543         return True;
1544 }
1545
1546 /*******************************************************************
1547  * write a structure.
1548  * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1549  * called from spoolss_deleteprinter (cli_spoolss.c)
1550  ********************************************************************/
1551
1552 BOOL spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1553 {
1554         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1555         depth++;
1556         
1557         if (!prs_align(ps))
1558                 return False;
1559
1560         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1561                 return False;
1562         if (!prs_werror("status", ps, depth, &r_u->status))
1563                 return False;
1564         
1565         return True;
1566 }
1567
1568
1569 /*******************************************************************
1570  * read a structure.
1571  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1572  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1573  ********************************************************************/
1574
1575 BOOL spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1576 {
1577         if (q_u == NULL) return False;
1578
1579         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1580         depth++;
1581
1582         if (!prs_align(ps))
1583                 return False;
1584
1585         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1586                 return False;           
1587         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1588                 return False;
1589         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1590                 return False;
1591         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1592                 return False;
1593
1594
1595         return True;
1596 }
1597
1598
1599 /*******************************************************************
1600  * write a structure.
1601  ********************************************************************/
1602 BOOL spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1603 {
1604         if (r_u == NULL) return False;
1605
1606         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1607         depth++;
1608
1609         if (!prs_align(ps))
1610                 return False;
1611
1612         if (!prs_werror("status", ps, depth, &r_u->status))
1613                 return False;
1614
1615         return True;
1616 }
1617
1618
1619 /*******************************************************************
1620  * read a structure.
1621  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1622  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1623  ********************************************************************/
1624
1625 BOOL spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
1626 {
1627         if (q_u == NULL) return False;
1628
1629         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
1630         depth++;
1631
1632         if (!prs_align(ps))
1633                 return False;
1634
1635         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1636                 return False;           
1637         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1638                 return False;
1639         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1640                 return False;
1641         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1642                 return False;
1643
1644         if (!prs_align(ps))
1645                 return False;
1646
1647         if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
1648                 return False;           
1649         if(!prs_uint32("version      ", ps, depth, &q_u->version))
1650                 return False;           
1651
1652
1653         return True;
1654 }
1655
1656
1657 /*******************************************************************
1658  * write a structure.
1659  ********************************************************************/
1660 BOOL spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
1661 {
1662         if (r_u == NULL) return False;
1663
1664         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
1665         depth++;
1666
1667         if (!prs_align(ps))
1668                 return False;
1669
1670         if (!prs_werror("status", ps, depth, &r_u->status))
1671                 return False;
1672
1673         return True;
1674 }
1675
1676
1677
1678 /*******************************************************************
1679  * read a structure.
1680  * called from static spoolss_q_closeprinter (srv_spoolss.c)
1681  * called from spoolss_closeprinter (cli_spoolss.c)
1682  ********************************************************************/
1683
1684 BOOL spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1685 {
1686         if (q_u == NULL) return False;
1687
1688         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1689         depth++;
1690
1691         if (!prs_align(ps))
1692                 return False;
1693
1694         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1695                 return False;
1696
1697         return True;
1698 }
1699
1700 /*******************************************************************
1701  * write a structure.
1702  * called from static spoolss_r_closeprinter (srv_spoolss.c)
1703  * called from spoolss_closeprinter (cli_spoolss.c)
1704  ********************************************************************/
1705
1706 BOOL spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1707 {
1708         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1709         depth++;
1710         
1711         if (!prs_align(ps))
1712                 return False;
1713
1714         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1715                 return False;
1716         if (!prs_werror("status", ps, depth, &r_u->status))
1717                 return False;
1718         
1719         return True;
1720 }
1721
1722 /*******************************************************************
1723  * read a structure.
1724  * called from spoolss_q_startdocprinter (srv_spoolss.c)
1725  ********************************************************************/
1726
1727 BOOL spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1728 {
1729         if (q_u == NULL) return False;
1730
1731         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1732         depth++;
1733
1734         if(!prs_align(ps))
1735                 return False;
1736
1737         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1738                 return False;
1739         
1740         if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1741                 return False;
1742
1743         return True;
1744 }
1745
1746 /*******************************************************************
1747  * write a structure.
1748  * called from spoolss_r_startdocprinter (srv_spoolss.c)
1749  ********************************************************************/
1750
1751 BOOL spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1752 {
1753         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1754         depth++;
1755         if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1756                 return False;
1757         if(!prs_werror("status", ps, depth, &r_u->status))
1758                 return False;
1759
1760         return True;
1761 }
1762
1763 /*******************************************************************
1764  * read a structure.
1765  * called from spoolss_q_enddocprinter (srv_spoolss.c)
1766  ********************************************************************/
1767
1768 BOOL spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1769 {
1770         if (q_u == NULL) return False;
1771
1772         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1773         depth++;
1774
1775         if(!prs_align(ps))
1776                 return False;
1777
1778         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1779                 return False;
1780
1781         return True;
1782 }
1783
1784 /*******************************************************************
1785  * write a structure.
1786  * called from spoolss_r_enddocprinter (srv_spoolss.c)
1787  ********************************************************************/
1788
1789 BOOL spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1790 {
1791         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1792         depth++;
1793         if(!prs_werror("status", ps, depth, &r_u->status))
1794                 return False;
1795
1796         return True;
1797 }
1798
1799 /*******************************************************************
1800  * read a structure.
1801  * called from spoolss_q_startpageprinter (srv_spoolss.c)
1802  ********************************************************************/
1803
1804 BOOL spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1805 {
1806         if (q_u == NULL) return False;
1807
1808         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1809         depth++;
1810
1811         if(!prs_align(ps))
1812                 return False;
1813
1814         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1815                 return False;
1816
1817         return True;
1818 }
1819
1820 /*******************************************************************
1821  * write a structure.
1822  * called from spoolss_r_startpageprinter (srv_spoolss.c)
1823  ********************************************************************/
1824
1825 BOOL spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1826 {
1827         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1828         depth++;
1829         if(!prs_werror("status", ps, depth, &r_u->status))
1830                 return False;
1831
1832         return True;
1833 }
1834
1835 /*******************************************************************
1836  * read a structure.
1837  * called from spoolss_q_endpageprinter (srv_spoolss.c)
1838  ********************************************************************/
1839
1840 BOOL spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1841 {
1842         if (q_u == NULL) return False;
1843
1844         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1845         depth++;
1846
1847         if(!prs_align(ps))
1848                 return False;
1849
1850         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1851                 return False;
1852
1853         return True;
1854 }
1855
1856 /*******************************************************************
1857  * write a structure.
1858  * called from spoolss_r_endpageprinter (srv_spoolss.c)
1859  ********************************************************************/
1860
1861 BOOL spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1862 {
1863         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1864         depth++;
1865         if(!prs_werror("status", ps, depth, &r_u->status))
1866                 return False;
1867
1868         return True;
1869 }
1870
1871 /*******************************************************************
1872  * read a structure.
1873  * called from spoolss_q_writeprinter (srv_spoolss.c)
1874  ********************************************************************/
1875
1876 BOOL spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1877 {
1878         if (q_u == NULL) return False;
1879
1880         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1881         depth++;
1882
1883         if(!prs_align(ps))
1884                 return False;
1885
1886         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1887                 return False;
1888         if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1889                 return False;
1890         
1891         if (q_u->buffer_size!=0)
1892         {
1893                 if (UNMARSHALLING(ps))
1894                         q_u->buffer=PRS_ALLOC_MEM(ps, uint8, q_u->buffer_size);
1895                 if(q_u->buffer == NULL)
1896                         return False;   
1897                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1898                         return False;
1899         }
1900         if(!prs_align(ps))
1901                 return False;
1902         if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1903                 return False;
1904
1905         return True;
1906 }
1907
1908 /*******************************************************************
1909  * write a structure.
1910  * called from spoolss_r_writeprinter (srv_spoolss.c)
1911  ********************************************************************/
1912
1913 BOOL spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1914 {
1915         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1916         depth++;
1917         if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1918                 return False;
1919         if(!prs_werror("status", ps, depth, &r_u->status))
1920                 return False;
1921
1922         return True;
1923 }
1924
1925 /*******************************************************************
1926  * read a structure.
1927  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1928  ********************************************************************/
1929
1930 BOOL spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1931 {
1932         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1933         depth++;
1934
1935         if(!prs_align(ps))
1936                 return False;
1937
1938         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1939                 return False;
1940         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1941                 return False;
1942         if(!prs_uint32("options", ps, depth, &q_u->options))
1943                 return False;
1944         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1945                 return False;
1946         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1947                 return False;
1948
1949         if(!prs_align(ps))
1950                 return False;
1951                 
1952         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1953                 return False;
1954
1955         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1956                 return False;
1957         
1958         if (q_u->option_ptr!=0) {
1959         
1960                 if (UNMARSHALLING(ps))
1961                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1962                                 return False;
1963         
1964                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1965                         return False;
1966         }
1967         
1968         return True;
1969 }
1970
1971 /*******************************************************************
1972  * write a structure.
1973  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1974  ********************************************************************/
1975
1976 BOOL spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1977 {
1978         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1979         depth++;
1980
1981         if(!prs_werror("status", ps, depth, &r_u->status))
1982                 return False;
1983
1984         return True;
1985 }
1986
1987 /*******************************************************************
1988  * read a structure.
1989  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1990  ********************************************************************/
1991
1992 BOOL spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1993 {
1994         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1995         depth++;
1996
1997         if(!prs_align(ps))
1998                 return False;
1999
2000         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
2001                 return False;
2002
2003         if(!prs_uint32("change", ps, depth, &q_u->change))
2004                 return False;
2005         
2006         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
2007                 return False;
2008         
2009         if (q_u->option_ptr!=0) {
2010         
2011                 if (UNMARSHALLING(ps))
2012                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
2013                                 return False;
2014         
2015                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
2016                         return False;
2017         }
2018
2019         return True;
2020 }
2021
2022 /*******************************************************************
2023  * write a structure.
2024  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
2025  ********************************************************************/
2026
2027 BOOL spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
2028 {
2029         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
2030         depth++;
2031
2032         if(!prs_align(ps))
2033                 return False;
2034                 
2035         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
2036                 return False;
2037
2038         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
2039                 return False;
2040         
2041         if(!prs_align(ps))
2042                 return False;
2043         if(!prs_werror("status", ps, depth, &r_u->status))
2044                 return False;
2045
2046         return True;
2047 }
2048
2049 /*******************************************************************
2050  * return the length of a uint16 (obvious, but the code is clean)
2051  ********************************************************************/
2052
2053 static uint32 size_of_uint16(uint16 *value)
2054 {
2055         return (sizeof(*value));
2056 }
2057
2058 /*******************************************************************
2059  * return the length of a uint32 (obvious, but the code is clean)
2060  ********************************************************************/
2061
2062 static uint32 size_of_uint32(uint32 *value)
2063 {
2064         return (sizeof(*value));
2065 }
2066
2067 /*******************************************************************
2068  * return the length of a NTTIME (obvious, but the code is clean)
2069  ********************************************************************/
2070
2071 static uint32 size_of_nttime(NTTIME *value)
2072 {
2073         return (sizeof(*value));
2074 }
2075
2076 /*******************************************************************
2077  * return the length of a uint32 (obvious, but the code is clean)
2078  ********************************************************************/
2079
2080 static uint32 size_of_device_mode(DEVICEMODE *devmode)
2081 {
2082         if (devmode==NULL)
2083                 return (4);
2084         else 
2085                 return (4+devmode->size+devmode->driverextra);
2086 }
2087
2088 /*******************************************************************
2089  * return the length of a uint32 (obvious, but the code is clean)
2090  ********************************************************************/
2091
2092 static uint32 size_of_systemtime(SYSTEMTIME *systime)
2093 {
2094         if (systime==NULL)
2095                 return (4);
2096         else 
2097                 return (sizeof(SYSTEMTIME) +4);
2098 }
2099
2100 /*******************************************************************
2101  Parse a DEVMODE structure and its relative pointer.
2102 ********************************************************************/
2103
2104 static BOOL smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2105 {
2106         prs_struct *ps=&buffer->prs;
2107
2108         prs_debug(ps, depth, desc, "smb_io_reldevmode");
2109         depth++;
2110
2111         if (MARSHALLING(ps)) {
2112                 uint32 struct_offset = prs_offset(ps);
2113                 uint32 relative_offset;
2114                 
2115                 if (*devmode == NULL) {
2116                         relative_offset=0;
2117                         if (!prs_uint32("offset", ps, depth, &relative_offset))
2118                                 return False;
2119                         DEBUG(8, ("boing, the devmode was NULL\n"));
2120                         
2121                         return True;
2122                 }
2123                 
2124                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2125                 
2126                 if(!prs_set_offset(ps, buffer->string_at_end))
2127                         return False;
2128                 
2129                 /* write the DEVMODE */
2130                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2131                         return False;
2132
2133                 if(!prs_set_offset(ps, struct_offset))
2134                         return False;
2135                 
2136                 relative_offset=buffer->string_at_end - buffer->struct_start;
2137                 /* write its offset */
2138                 if (!prs_uint32("offset", ps, depth, &relative_offset))
2139                         return False;
2140         }
2141         else {
2142                 uint32 old_offset;
2143                 
2144                 /* read the offset */
2145                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2146                         return False;
2147                 if (buffer->string_at_end == 0) {
2148                         *devmode = NULL;
2149                         return True;
2150                 }
2151
2152                 old_offset = prs_offset(ps);
2153                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2154                         return False;
2155
2156                 /* read the string */
2157                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
2158                         return False;
2159                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2160                         return False;
2161
2162                 if(!prs_set_offset(ps, old_offset))
2163                         return False;
2164         }
2165         return True;
2166 }
2167
2168 /*******************************************************************
2169  Parse a PRINTER_INFO_0 structure.
2170 ********************************************************************/  
2171
2172 BOOL smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2173 {
2174         prs_struct *ps=&buffer->prs;
2175
2176         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2177         depth++;        
2178         
2179         buffer->struct_start=prs_offset(ps);
2180
2181         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2182                 return False;
2183         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2184                 return False;
2185         
2186         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2187                 return False;
2188         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2189                 return False;
2190         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2191                 return False;
2192
2193         if(!prs_uint16("year", ps, depth, &info->year))
2194                 return False;
2195         if(!prs_uint16("month", ps, depth, &info->month))
2196                 return False;
2197         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2198                 return False;
2199         if(!prs_uint16("day", ps, depth, &info->day))
2200                 return False;
2201         if(!prs_uint16("hour", ps, depth, &info->hour))
2202                 return False;
2203         if(!prs_uint16("minute", ps, depth, &info->minute))
2204                 return False;
2205         if(!prs_uint16("second", ps, depth, &info->second))
2206                 return False;
2207         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2208                 return False;
2209
2210         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2211                 return False;
2212         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2213                 return False;
2214
2215         if(!prs_uint16("major_version", ps, depth, &info->major_version))
2216                 return False;
2217         if(!prs_uint16("build_version", ps, depth, &info->build_version))
2218                 return False;
2219         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2220                 return False;
2221         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2222                 return False;
2223         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2224                 return False;
2225         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2226                 return False;
2227         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2228                 return False;
2229         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2230                 return False;
2231         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2232                 return False;
2233         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2234                 return False;
2235         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2236                 return False;
2237         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2238                 return False;
2239         if(!prs_uint32("change_id", ps, depth, &info->change_id))
2240                 return False;
2241         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2242                 return False;
2243         if(!prs_uint32("status"   , ps, depth, &info->status))
2244                 return False;
2245         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2246                 return False;
2247         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2248                 return False;
2249         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2250                 return False;
2251         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2252                 return False;
2253         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2254                 return False;
2255         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2256                 return False;
2257         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2258                 return False;
2259         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2260                 return False;
2261         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2262                 return False;
2263         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2264                 return False;
2265
2266         return True;
2267 }
2268
2269 /*******************************************************************
2270  Parse a PRINTER_INFO_1 structure.
2271 ********************************************************************/  
2272
2273 BOOL smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2274 {
2275         prs_struct *ps=&buffer->prs;
2276
2277         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2278         depth++;        
2279         
2280         buffer->struct_start=prs_offset(ps);
2281
2282         if (!prs_uint32("flags", ps, depth, &info->flags))
2283                 return False;
2284         if (!smb_io_relstr("description", buffer, depth, &info->description))
2285                 return False;
2286         if (!smb_io_relstr("name", buffer, depth, &info->name))
2287                 return False;
2288         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2289                 return False;   
2290
2291         return True;
2292 }
2293
2294 /*******************************************************************
2295  Parse a PRINTER_INFO_2 structure.
2296 ********************************************************************/  
2297
2298 BOOL smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2299 {
2300         prs_struct *ps=&buffer->prs;
2301         uint32 dm_offset, sd_offset, current_offset;
2302         uint32 dummy_value = 0, has_secdesc = 0;
2303
2304         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2305         depth++;        
2306         
2307         buffer->struct_start=prs_offset(ps);
2308         
2309         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2310                 return False;
2311         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2312                 return False;
2313         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2314                 return False;
2315         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2316                 return False;
2317         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2318                 return False;
2319         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2320                 return False;
2321         if (!smb_io_relstr("location", buffer, depth, &info->location))
2322                 return False;
2323
2324         /* save current offset and wind forwared by a uint32 */
2325         dm_offset = prs_offset(ps);
2326         if (!prs_uint32("devmode", ps, depth, &dummy_value))
2327                 return False;
2328         
2329         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2330                 return False;
2331         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2332                 return False;
2333         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2334                 return False;
2335         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2336                 return False;
2337
2338         /* save current offset for the sec_desc */
2339         sd_offset = prs_offset(ps);
2340         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
2341                 return False;
2342
2343         
2344         /* save current location so we can pick back up here */
2345         current_offset = prs_offset(ps);
2346         
2347         /* parse the devmode */
2348         if (!prs_set_offset(ps, dm_offset))
2349                 return False;
2350         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2351                 return False;
2352         
2353         /* parse the sec_desc */
2354         if (info->secdesc) {
2355                 if (!prs_set_offset(ps, sd_offset))
2356                         return False;
2357                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2358                         return False;
2359         }
2360
2361         /* pick up where we left off */
2362         if (!prs_set_offset(ps, current_offset))
2363                 return False;
2364
2365         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2366                 return False;
2367         if (!prs_uint32("priority", ps, depth, &info->priority))
2368                 return False;
2369         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2370                 return False;
2371         if (!prs_uint32("starttime", ps, depth, &info->starttime))
2372                 return False;
2373         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2374                 return False;
2375         if (!prs_uint32("status", ps, depth, &info->status))
2376                 return False;
2377         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2378                 return False;
2379         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2380                 return False;
2381
2382         return True;
2383 }
2384
2385 /*******************************************************************
2386  Parse a PRINTER_INFO_3 structure.
2387 ********************************************************************/  
2388
2389 BOOL smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2390 {
2391         prs_struct *ps=&buffer->prs;
2392
2393         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2394         depth++;        
2395         
2396         buffer->struct_start=prs_offset(ps);
2397         
2398         if (!prs_uint32("flags", ps, depth, &info->flags))
2399                 return False;
2400         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2401                 return False;
2402
2403         return True;
2404 }
2405
2406 /*******************************************************************
2407  Parse a PRINTER_INFO_4 structure.
2408 ********************************************************************/  
2409
2410 BOOL smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2411 {
2412         prs_struct *ps=&buffer->prs;
2413
2414         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2415         depth++;        
2416         
2417         buffer->struct_start=prs_offset(ps);
2418         
2419         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2420                 return False;
2421         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2422                 return False;
2423         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2424                 return False;
2425         return True;
2426 }
2427
2428 /*******************************************************************
2429  Parse a PRINTER_INFO_5 structure.
2430 ********************************************************************/  
2431
2432 BOOL smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2433 {
2434         prs_struct *ps=&buffer->prs;
2435
2436         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2437         depth++;        
2438         
2439         buffer->struct_start=prs_offset(ps);
2440         
2441         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2442                 return False;
2443         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2444                 return False;
2445         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2446                 return False;
2447         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2448                 return False;
2449         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2450                 return False;
2451         return True;
2452 }
2453
2454 /*******************************************************************
2455  Parse a PRINTER_INFO_7 structure.
2456 ********************************************************************/  
2457
2458 BOOL smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
2459 {
2460         prs_struct *ps=&buffer->prs;
2461
2462         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
2463         depth++;        
2464         
2465         buffer->struct_start=prs_offset(ps);
2466         
2467         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
2468                 return False;
2469         if (!prs_uint32("action", ps, depth, &info->action))
2470                 return False;
2471         return True;
2472 }
2473
2474 /*******************************************************************
2475  Parse a PORT_INFO_1 structure.
2476 ********************************************************************/  
2477
2478 BOOL smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2479 {
2480         prs_struct *ps=&buffer->prs;
2481
2482         prs_debug(ps, depth, desc, "smb_io_port_info_1");
2483         depth++;        
2484         
2485         buffer->struct_start=prs_offset(ps);
2486         
2487         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2488                 return False;
2489
2490         return True;
2491 }
2492
2493 /*******************************************************************
2494  Parse a PORT_INFO_2 structure.
2495 ********************************************************************/  
2496
2497 BOOL smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2498 {
2499         prs_struct *ps=&buffer->prs;
2500
2501         prs_debug(ps, depth, desc, "smb_io_port_info_2");
2502         depth++;        
2503         
2504         buffer->struct_start=prs_offset(ps);
2505         
2506         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2507                 return False;
2508         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2509                 return False;
2510         if (!smb_io_relstr("description", buffer, depth, &info->description))
2511                 return False;
2512         if (!prs_uint32("port_type", ps, depth, &info->port_type))
2513                 return False;
2514         if (!prs_uint32("reserved", ps, depth, &info->reserved))
2515                 return False;
2516
2517         return True;
2518 }
2519
2520 /*******************************************************************
2521  Parse a DRIVER_INFO_1 structure.
2522 ********************************************************************/
2523
2524 BOOL smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
2525 {
2526         prs_struct *ps=&buffer->prs;
2527
2528         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2529         depth++;        
2530         
2531         buffer->struct_start=prs_offset(ps);
2532
2533         if (!smb_io_relstr("name", buffer, depth, &info->name))
2534                 return False;
2535
2536         return True;
2537 }
2538
2539 /*******************************************************************
2540  Parse a DRIVER_INFO_2 structure.
2541 ********************************************************************/
2542
2543 BOOL smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
2544 {
2545         prs_struct *ps=&buffer->prs;
2546
2547         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2548         depth++;        
2549         
2550         buffer->struct_start=prs_offset(ps);
2551
2552         if (!prs_uint32("version", ps, depth, &info->version))
2553                 return False;
2554         if (!smb_io_relstr("name", buffer, depth, &info->name))
2555                 return False;
2556         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2557                 return False;
2558         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2559                 return False;
2560         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2561                 return False;
2562         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2563                 return False;
2564
2565         return True;
2566 }
2567
2568 /*******************************************************************
2569  Parse a DRIVER_INFO_3 structure.
2570 ********************************************************************/
2571
2572 BOOL smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2573 {
2574         prs_struct *ps=&buffer->prs;
2575
2576         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2577         depth++;        
2578         
2579         buffer->struct_start=prs_offset(ps);
2580
2581         if (!prs_uint32("version", ps, depth, &info->version))
2582                 return False;
2583         if (!smb_io_relstr("name", buffer, depth, &info->name))
2584                 return False;
2585         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2586                 return False;
2587         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2588                 return False;
2589         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2590                 return False;
2591         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2592                 return False;
2593         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2594                 return False;
2595
2596         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2597                 return False;
2598
2599         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2600                 return False;
2601         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2602                 return False;
2603
2604         return True;
2605 }
2606
2607 /*******************************************************************
2608  Parse a DRIVER_INFO_6 structure.
2609 ********************************************************************/
2610
2611 BOOL smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2612 {
2613         prs_struct *ps=&buffer->prs;
2614
2615         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2616         depth++;        
2617         
2618         buffer->struct_start=prs_offset(ps);
2619
2620         if (!prs_uint32("version", ps, depth, &info->version))
2621                 return False;
2622         if (!smb_io_relstr("name", buffer, depth, &info->name))
2623                 return False;
2624         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2625                 return False;
2626         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2627                 return False;
2628         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2629                 return False;
2630         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2631                 return False;
2632         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2633                 return False;
2634
2635         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2636                 return False;
2637
2638         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2639                 return False;
2640         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2641                 return False;
2642
2643         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2644                 return False;
2645
2646         if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
2647                 return False;
2648         if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
2649                 return False;
2650
2651         if (!prs_uint32("padding", ps, depth, &info->padding))
2652                 return False;
2653
2654         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2655                 return False;
2656
2657         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2658                 return False;
2659
2660         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2661                 return False;
2662         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2663                 return False;
2664         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2665                 return False;
2666         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2667                 return False;
2668         
2669         return True;
2670 }
2671
2672 /*******************************************************************
2673  Parse a JOB_INFO_1 structure.
2674 ********************************************************************/  
2675
2676 BOOL smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2677 {
2678         prs_struct *ps=&buffer->prs;
2679
2680         prs_debug(ps, depth, desc, "smb_io_job_info_1");
2681         depth++;        
2682         
2683         buffer->struct_start=prs_offset(ps);
2684
2685         if (!prs_uint32("jobid", ps, depth, &info->jobid))
2686                 return False;
2687         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2688                 return False;
2689         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2690                 return False;
2691         if (!smb_io_relstr("username", buffer, depth, &info->username))
2692                 return False;
2693         if (!smb_io_relstr("document", buffer, depth, &info->document))
2694                 return False;
2695         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2696                 return False;
2697         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2698                 return False;
2699         if (!prs_uint32("status", ps, depth, &info->status))
2700                 return False;
2701         if (!prs_uint32("priority", ps, depth, &info->priority))
2702                 return False;
2703         if (!prs_uint32("position", ps, depth, &info->position))
2704                 return False;
2705         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2706                 return False;
2707         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2708                 return False;
2709         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2710                 return False;
2711
2712         return True;
2713 }
2714
2715 /*******************************************************************
2716  Parse a JOB_INFO_2 structure.
2717 ********************************************************************/  
2718
2719 BOOL smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2720 {       
2721         uint32 pipo=0;
2722         prs_struct *ps=&buffer->prs;
2723         
2724         prs_debug(ps, depth, desc, "smb_io_job_info_2");
2725         depth++;        
2726
2727         buffer->struct_start=prs_offset(ps);
2728         
2729         if (!prs_uint32("jobid",ps, depth, &info->jobid))
2730                 return False;
2731         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2732                 return False;
2733         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2734                 return False;
2735         if (!smb_io_relstr("username", buffer, depth, &info->username))
2736                 return False;
2737         if (!smb_io_relstr("document", buffer, depth, &info->document))
2738                 return False;
2739         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2740                 return False;
2741         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2742                 return False;
2743
2744         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2745                 return False;
2746         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2747                 return False;
2748         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2749                 return False;
2750         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2751                 return False;
2752         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2753                 return False;
2754
2755 /*      SEC_DESC sec_desc;*/
2756         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2757                 return False;
2758
2759         if (!prs_uint32("status",ps, depth, &info->status))
2760                 return False;
2761         if (!prs_uint32("priority",ps, depth, &info->priority))
2762                 return False;
2763         if (!prs_uint32("position",ps, depth, &info->position)) 
2764                 return False;
2765         if (!prs_uint32("starttime",ps, depth, &info->starttime))
2766                 return False;
2767         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2768                 return False;
2769         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2770                 return False;
2771         if (!prs_uint32("size",ps, depth, &info->size))
2772                 return False;
2773         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2774                 return False;
2775         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2776                 return False;
2777         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2778                 return False;
2779
2780         return True;
2781 }
2782
2783 /*******************************************************************
2784 ********************************************************************/  
2785
2786 BOOL smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
2787 {
2788         prs_struct *ps=&buffer->prs;
2789         
2790         prs_debug(ps, depth, desc, "smb_io_form_1");
2791         depth++;
2792                 
2793         buffer->struct_start=prs_offset(ps);
2794         
2795         if (!prs_uint32("flag", ps, depth, &info->flag))
2796                 return False;
2797                 
2798         if (!smb_io_relstr("name", buffer, depth, &info->name))
2799                 return False;
2800
2801         if (!prs_uint32("width", ps, depth, &info->width))
2802                 return False;
2803         if (!prs_uint32("length", ps, depth, &info->length))
2804                 return False;
2805         if (!prs_uint32("left", ps, depth, &info->left))
2806                 return False;
2807         if (!prs_uint32("top", ps, depth, &info->top))
2808                 return False;
2809         if (!prs_uint32("right", ps, depth, &info->right))
2810                 return False;
2811         if (!prs_uint32("bottom", ps, depth, &info->bottom))
2812                 return False;
2813
2814         return True;
2815 }
2816
2817
2818
2819 /*******************************************************************
2820  Parse a DRIVER_DIRECTORY_1 structure.
2821 ********************************************************************/  
2822
2823 BOOL smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2824 {
2825         prs_struct *ps=&buffer->prs;
2826
2827         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2828         depth++;
2829
2830         buffer->struct_start=prs_offset(ps);
2831
2832         if (!smb_io_unistr(desc, &info->name, ps, depth))
2833                 return False;
2834
2835         return True;
2836 }
2837
2838 /*******************************************************************
2839  Parse a PORT_INFO_1 structure.
2840 ********************************************************************/  
2841
2842 BOOL smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2843 {
2844         prs_struct *ps=&buffer->prs;
2845
2846         prs_debug(ps, depth, desc, "smb_io_port_1");
2847         depth++;
2848
2849         buffer->struct_start=prs_offset(ps);
2850
2851         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2852                 return False;
2853
2854         return True;
2855 }
2856
2857 /*******************************************************************
2858  Parse a PORT_INFO_2 structure.
2859 ********************************************************************/  
2860
2861 BOOL smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2862 {
2863         prs_struct *ps=&buffer->prs;
2864
2865         prs_debug(ps, depth, desc, "smb_io_port_2");
2866         depth++;
2867
2868         buffer->struct_start=prs_offset(ps);
2869
2870         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2871                 return False;
2872         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2873                 return False;
2874         if(!smb_io_relstr("description", buffer, depth, &info->description))
2875                 return False;
2876         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2877                 return False;
2878         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2879                 return False;
2880
2881         return True;
2882 }
2883
2884 /*******************************************************************
2885 ********************************************************************/  
2886
2887 BOOL smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2888 {
2889         prs_struct *ps=&buffer->prs;
2890
2891         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2892         depth++;        
2893
2894         buffer->struct_start=prs_offset(ps);
2895         
2896         if (smb_io_relstr("name", buffer, depth, &info->name))
2897                 return False;
2898
2899         return True;
2900 }
2901
2902 /*******************************************************************
2903 ********************************************************************/  
2904
2905 BOOL smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2906 {
2907         prs_struct *ps=&buffer->prs;
2908
2909         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2910         depth++;        
2911
2912         buffer->struct_start=prs_offset(ps);
2913         
2914         if (smb_io_relstr("name", buffer, depth, &info->name))
2915                 return False;
2916
2917         return True;
2918 }
2919
2920 /*******************************************************************
2921 ********************************************************************/  
2922
2923 BOOL smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2924 {
2925         prs_struct *ps=&buffer->prs;
2926
2927         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2928         depth++;        
2929
2930         buffer->struct_start=prs_offset(ps);
2931
2932         if (!smb_io_relstr("name", buffer, depth, &info->name))
2933                 return False;
2934
2935         return True;
2936 }
2937
2938 /*******************************************************************
2939 ********************************************************************/  
2940
2941 BOOL smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2942 {
2943         prs_struct *ps=&buffer->prs;
2944
2945         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2946         depth++;        
2947
2948         buffer->struct_start=prs_offset(ps);
2949
2950         if (!smb_io_relstr("name", buffer, depth, &info->name))
2951                 return False;
2952         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2953                 return False;
2954         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2955                 return False;
2956
2957         return True;
2958 }
2959
2960 /*******************************************************************
2961 return the size required by a struct in the stream
2962 ********************************************************************/  
2963
2964 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2965 {
2966         int size=0;
2967         
2968         size+=size_of_relative_string( &info->printername );
2969         size+=size_of_relative_string( &info->servername );
2970
2971         size+=size_of_uint32( &info->cjobs);
2972         size+=size_of_uint32( &info->total_jobs);
2973         size+=size_of_uint32( &info->total_bytes);
2974
2975         size+=size_of_uint16( &info->year);
2976         size+=size_of_uint16( &info->month);
2977         size+=size_of_uint16( &info->dayofweek);
2978         size+=size_of_uint16( &info->day);
2979         size+=size_of_uint16( &info->hour);
2980         size+=size_of_uint16( &info->minute);
2981         size+=size_of_uint16( &info->second);
2982         size+=size_of_uint16( &info->milliseconds);
2983
2984         size+=size_of_uint32( &info->global_counter);
2985         size+=size_of_uint32( &info->total_pages);
2986
2987         size+=size_of_uint16( &info->major_version);
2988         size+=size_of_uint16( &info->build_version);
2989
2990         size+=size_of_uint32( &info->unknown7);
2991         size+=size_of_uint32( &info->unknown8);
2992         size+=size_of_uint32( &info->unknown9);
2993         size+=size_of_uint32( &info->session_counter);
2994         size+=size_of_uint32( &info->unknown11);
2995         size+=size_of_uint32( &info->printer_errors);
2996         size+=size_of_uint32( &info->unknown13);
2997         size+=size_of_uint32( &info->unknown14);
2998         size+=size_of_uint32( &info->unknown15);
2999         size+=size_of_uint32( &info->unknown16);
3000         size+=size_of_uint32( &info->change_id);
3001         size+=size_of_uint32( &info->unknown18);
3002         size+=size_of_uint32( &info->status);
3003         size+=size_of_uint32( &info->unknown20);
3004         size+=size_of_uint32( &info->c_setprinter);
3005         
3006         size+=size_of_uint16( &info->unknown22);
3007         size+=size_of_uint16( &info->unknown23);
3008         size+=size_of_uint16( &info->unknown24);
3009         size+=size_of_uint16( &info->unknown25);
3010         size+=size_of_uint16( &info->unknown26);
3011         size+=size_of_uint16( &info->unknown27);
3012         size+=size_of_uint16( &info->unknown28);
3013         size+=size_of_uint16( &info->unknown29);
3014         
3015         return size;
3016 }
3017
3018 /*******************************************************************
3019 return the size required by a struct in the stream
3020 ********************************************************************/  
3021
3022 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3023 {
3024         int size=0;
3025                 
3026         size+=size_of_uint32( &info->flags );   
3027         size+=size_of_relative_string( &info->description );
3028         size+=size_of_relative_string( &info->name );
3029         size+=size_of_relative_string( &info->comment );
3030
3031         return size;
3032 }
3033
3034 /*******************************************************************
3035 return the size required by a struct in the stream
3036 ********************************************************************/
3037
3038 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3039 {
3040         uint32 size=0;
3041                 
3042         size += 4;
3043         
3044         size += sec_desc_size( info->secdesc );
3045
3046         size+=size_of_device_mode( info->devmode );
3047         
3048         size+=size_of_relative_string( &info->servername );
3049         size+=size_of_relative_string( &info->printername );
3050         size+=size_of_relative_string( &info->sharename );
3051         size+=size_of_relative_string( &info->portname );
3052         size+=size_of_relative_string( &info->drivername );
3053         size+=size_of_relative_string( &info->comment );
3054         size+=size_of_relative_string( &info->location );
3055         
3056         size+=size_of_relative_string( &info->sepfile );
3057         size+=size_of_relative_string( &info->printprocessor );
3058         size+=size_of_relative_string( &info->datatype );
3059         size+=size_of_relative_string( &info->parameters );
3060
3061         size+=size_of_uint32( &info->attributes );
3062         size+=size_of_uint32( &info->priority );
3063         size+=size_of_uint32( &info->defaultpriority );
3064         size+=size_of_uint32( &info->starttime );
3065         size+=size_of_uint32( &info->untiltime );
3066         size+=size_of_uint32( &info->status );
3067         size+=size_of_uint32( &info->cjobs );
3068         size+=size_of_uint32( &info->averageppm );      
3069                 
3070         /* 
3071          * add any adjustments for alignment.  This is
3072          * not optimal since we could be calling this
3073          * function from a loop (e.g. enumprinters), but 
3074          * it is easier to maintain the calculation here and
3075          * not place the burden on the caller to remember.   --jerry
3076          */
3077         if ((size % 4) != 0)
3078                 size += 4 - (size % 4);
3079         
3080         return size;
3081 }
3082
3083 /*******************************************************************
3084 return the size required by a struct in the stream
3085 ********************************************************************/
3086
3087 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3088 {
3089         uint32 size=0;
3090                 
3091         size+=size_of_relative_string( &info->printername );
3092         size+=size_of_relative_string( &info->servername );
3093
3094         size+=size_of_uint32( &info->attributes );
3095         return size;
3096 }
3097
3098 /*******************************************************************
3099 return the size required by a struct in the stream
3100 ********************************************************************/
3101
3102 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3103 {
3104         uint32 size=0;
3105                 
3106         size+=size_of_relative_string( &info->printername );
3107         size+=size_of_relative_string( &info->portname );
3108
3109         size+=size_of_uint32( &info->attributes );
3110         size+=size_of_uint32( &info->device_not_selected_timeout );
3111         size+=size_of_uint32( &info->transmission_retry_timeout );
3112         return size;
3113 }
3114
3115
3116 /*******************************************************************
3117 return the size required by a struct in the stream
3118 ********************************************************************/
3119
3120 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3121 {
3122         /* The 4 is for the self relative pointer.. */
3123         /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
3124         return 4 + (uint32)sec_desc_size( info->secdesc );
3125 }
3126
3127 /*******************************************************************
3128 return the size required by a struct in the stream
3129 ********************************************************************/
3130
3131 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
3132 {
3133         uint32 size=0;
3134                 
3135         size+=size_of_relative_string( &info->guid );
3136         size+=size_of_uint32( &info->action );
3137         return size;
3138 }
3139
3140 /*******************************************************************
3141 return the size required by a struct in the stream
3142 ********************************************************************/
3143
3144 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3145 {
3146         int size=0;
3147         size+=size_of_relative_string( &info->name );
3148
3149         return size;
3150 }
3151
3152 /*******************************************************************
3153 return the size required by a struct in the stream
3154 ********************************************************************/
3155
3156 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3157 {
3158         int size=0;
3159         size+=size_of_uint32( &info->version ); 
3160         size+=size_of_relative_string( &info->name );
3161         size+=size_of_relative_string( &info->architecture );
3162         size+=size_of_relative_string( &info->driverpath );
3163         size+=size_of_relative_string( &info->datafile );
3164         size+=size_of_relative_string( &info->configfile );
3165
3166         return size;
3167 }
3168
3169 /*******************************************************************
3170 return the size required by a string array.
3171 ********************************************************************/
3172
3173 uint32 spoolss_size_string_array(uint16 *string)
3174 {
3175         uint32 i = 0;
3176
3177         if (string) {
3178                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3179         }
3180         i=i+2; /* to count all chars including the leading zero */
3181         i=2*i; /* because we need the value in bytes */
3182         i=i+4; /* the offset pointer size */
3183
3184         return i;
3185 }
3186
3187 /*******************************************************************
3188 return the size required by a struct in the stream
3189 ********************************************************************/
3190
3191 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3192 {
3193         int size=0;
3194
3195         size+=size_of_uint32( &info->version ); 
3196         size+=size_of_relative_string( &info->name );
3197         size+=size_of_relative_string( &info->architecture );
3198         size+=size_of_relative_string( &info->driverpath );
3199         size+=size_of_relative_string( &info->datafile );
3200         size+=size_of_relative_string( &info->configfile );
3201         size+=size_of_relative_string( &info->helpfile );
3202         size+=size_of_relative_string( &info->monitorname );
3203         size+=size_of_relative_string( &info->defaultdatatype );
3204         
3205         size+=spoolss_size_string_array(info->dependentfiles);
3206
3207         return size;
3208 }
3209
3210 /*******************************************************************
3211 return the size required by a struct in the stream
3212 ********************************************************************/
3213
3214 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3215 {
3216         uint32 size=0;
3217
3218         size+=size_of_uint32( &info->version ); 
3219         size+=size_of_relative_string( &info->name );
3220         size+=size_of_relative_string( &info->architecture );
3221         size+=size_of_relative_string( &info->driverpath );
3222         size+=size_of_relative_string( &info->datafile );
3223         size+=size_of_relative_string( &info->configfile );
3224         size+=size_of_relative_string( &info->helpfile );
3225
3226         size+=spoolss_size_string_array(info->dependentfiles);
3227
3228         size+=size_of_relative_string( &info->monitorname );
3229         size+=size_of_relative_string( &info->defaultdatatype );
3230         
3231         size+=spoolss_size_string_array(info->previousdrivernames);
3232
3233         size+=size_of_nttime(&info->driver_date);
3234         size+=size_of_uint32( &info->padding ); 
3235         size+=size_of_uint32( &info->driver_version_low );      
3236         size+=size_of_uint32( &info->driver_version_high );     
3237         size+=size_of_relative_string( &info->mfgname );
3238         size+=size_of_relative_string( &info->oem_url );
3239         size+=size_of_relative_string( &info->hardware_id );
3240         size+=size_of_relative_string( &info->provider );
3241
3242         return size;
3243 }
3244
3245 /*******************************************************************
3246 return the size required by a struct in the stream
3247 ********************************************************************/  
3248
3249 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3250 {
3251         int size=0;
3252         size+=size_of_uint32( &info->jobid );
3253         size+=size_of_relative_string( &info->printername );
3254         size+=size_of_relative_string( &info->machinename );
3255         size+=size_of_relative_string( &info->username );
3256         size+=size_of_relative_string( &info->document );
3257         size+=size_of_relative_string( &info->datatype );
3258         size+=size_of_relative_string( &info->text_status );
3259         size+=size_of_uint32( &info->status );
3260         size+=size_of_uint32( &info->priority );
3261         size+=size_of_uint32( &info->position );
3262         size+=size_of_uint32( &info->totalpages );
3263         size+=size_of_uint32( &info->pagesprinted );
3264         size+=size_of_systemtime( &info->submitted );
3265
3266         return size;
3267 }
3268
3269 /*******************************************************************
3270 return the size required by a struct in the stream
3271 ********************************************************************/  
3272
3273 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3274 {
3275         int size=0;
3276
3277         size+=4; /* size of sec desc ptr */
3278
3279         size+=size_of_uint32( &info->jobid );
3280         size+=size_of_relative_string( &info->printername );
3281         size+=size_of_relative_string( &info->machinename );
3282         size+=size_of_relative_string( &info->username );
3283         size+=size_of_relative_string( &info->document );
3284         size+=size_of_relative_string( &info->notifyname );
3285         size+=size_of_relative_string( &info->datatype );
3286         size+=size_of_relative_string( &info->printprocessor );
3287         size+=size_of_relative_string( &info->parameters );
3288         size+=size_of_relative_string( &info->drivername );
3289         size+=size_of_device_mode( info->devmode );
3290         size+=size_of_relative_string( &info->text_status );
3291 /*      SEC_DESC sec_desc;*/
3292         size+=size_of_uint32( &info->status );
3293         size+=size_of_uint32( &info->priority );
3294         size+=size_of_uint32( &info->position );
3295         size+=size_of_uint32( &info->starttime );
3296         size+=size_of_uint32( &info->untiltime );
3297         size+=size_of_uint32( &info->totalpages );
3298         size+=size_of_uint32( &info->size );
3299         size+=size_of_systemtime( &info->submitted );
3300         size+=size_of_uint32( &info->timeelapsed );
3301         size+=size_of_uint32( &info->pagesprinted );
3302
3303         return size;
3304 }
3305
3306 /*******************************************************************
3307 return the size required by a struct in the stream
3308 ********************************************************************/
3309
3310 uint32 spoolss_size_form_1(FORM_1 *info)
3311 {
3312         int size=0;
3313
3314         size+=size_of_uint32( &info->flag );
3315         size+=size_of_relative_string( &info->name );
3316         size+=size_of_uint32( &info->width );
3317         size+=size_of_uint32( &info->length );
3318         size+=size_of_uint32( &info->left );
3319         size+=size_of_uint32( &info->top );
3320         size+=size_of_uint32( &info->right );
3321         size+=size_of_uint32( &info->bottom );
3322
3323         return size;
3324 }
3325
3326 /*******************************************************************
3327 return the size required by a struct in the stream
3328 ********************************************************************/  
3329
3330 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3331 {
3332         int size=0;
3333
3334         size+=size_of_relative_string( &info->port_name );
3335
3336         return size;
3337 }
3338
3339 /*******************************************************************
3340 return the size required by a struct in the stream
3341 ********************************************************************/  
3342
3343 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3344 {
3345         int size=0;
3346
3347         size=str_len_uni(&info->name);  /* the string length       */
3348         size=size+1;                    /* add the leading zero    */
3349         size=size*2;                    /* convert in char         */
3350
3351         return size;
3352 }
3353
3354 /*******************************************************************
3355 return the size required by a struct in the stream
3356 ********************************************************************/  
3357
3358 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3359 {
3360         int size=0;
3361
3362         size=str_len_uni(&info->name);  /* the string length       */
3363         size=size+1;                    /* add the leading zero    */
3364         size=size*2;                    /* convert in char         */
3365
3366         return size;
3367 }
3368
3369 /*******************************************************************
3370 return the size required by a struct in the stream
3371 ********************************************************************/  
3372
3373 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3374 {
3375         int size=0;
3376
3377         size+=size_of_relative_string( &info->port_name );
3378         size+=size_of_relative_string( &info->monitor_name );
3379         size+=size_of_relative_string( &info->description );
3380
3381         size+=size_of_uint32( &info->port_type );
3382         size+=size_of_uint32( &info->reserved );
3383
3384         return size;
3385 }
3386
3387 /*******************************************************************
3388 return the size required by a struct in the stream
3389 ********************************************************************/  
3390
3391 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3392 {
3393         int size=0;
3394         size+=size_of_relative_string( &info->name );
3395
3396         return size;
3397 }
3398
3399 /*******************************************************************
3400 return the size required by a struct in the stream
3401 ********************************************************************/  
3402
3403 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3404 {
3405         int size=0;
3406         size+=size_of_relative_string( &info->name );
3407
3408         return size;
3409 }
3410
3411 /*******************************************************************
3412 return the size required by a struct in the stream
3413 ********************************************************************/  
3414 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
3415 {
3416         uint32  size = 0; 
3417         
3418         if (!p)
3419                 return 0;
3420         
3421         /* uint32(offset) + uint32(length) + length) */
3422         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
3423         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
3424         
3425         size += size_of_uint32(&p->type);
3426                        
3427         return size;
3428 }
3429
3430 /*******************************************************************
3431 return the size required by a struct in the stream
3432 ********************************************************************/  
3433
3434 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3435 {
3436         int size=0;
3437         size+=size_of_relative_string( &info->name );
3438
3439         return size;
3440 }
3441
3442 /*******************************************************************
3443 return the size required by a struct in the stream
3444 ********************************************************************/  
3445
3446 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3447 {
3448         int size=0;
3449         size+=size_of_relative_string( &info->name);
3450         size+=size_of_relative_string( &info->environment);
3451         size+=size_of_relative_string( &info->dll_name);
3452
3453         return size;
3454 }
3455
3456 /*******************************************************************
3457  * init a structure.
3458  ********************************************************************/
3459
3460 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
3461                                const POLICY_HND *hnd,
3462                                const fstring architecture,
3463                                uint32 level, uint32 clientmajor, uint32 clientminor,
3464                                RPC_BUFFER *buffer, uint32 offered)
3465 {      
3466         if (q_u == NULL)
3467                 return False;
3468
3469         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3470
3471         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3472
3473         q_u->level=level;
3474         q_u->clientmajorversion=clientmajor;
3475         q_u->clientminorversion=clientminor;
3476
3477         q_u->buffer=buffer;
3478         q_u->offered=offered;
3479
3480         return True;
3481 }
3482
3483 /*******************************************************************
3484  * read a structure.
3485  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3486  ********************************************************************/
3487
3488 BOOL spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3489 {
3490         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3491         depth++;
3492
3493         if(!prs_align(ps))
3494                 return False;
3495         
3496         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3497                 return False;
3498         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3499                 return False;
3500         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3501                 return False;
3502         
3503         if(!prs_align(ps))
3504                 return False;
3505         if(!prs_uint32("level", ps, depth, &q_u->level))
3506                 return False;
3507                 
3508         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3509                 return False;
3510
3511         if(!prs_align(ps))
3512                 return False;
3513
3514         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3515                 return False;
3516                 
3517         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3518                 return False;
3519         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3520                 return False;
3521
3522         return True;
3523 }
3524
3525 /*******************************************************************
3526  * read a structure.
3527  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3528  ********************************************************************/
3529
3530 BOOL spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3531 {
3532         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3533         depth++;
3534
3535         if (!prs_align(ps))
3536                 return False;
3537                 
3538         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3539                 return False;
3540
3541         if (!prs_align(ps))
3542                 return False;
3543         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3544                 return False;
3545         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3546                 return False;
3547         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3548                 return False;           
3549         if (!prs_werror("status", ps, depth, &r_u->status))
3550                 return False;
3551
3552         return True;            
3553 }
3554
3555 /*******************************************************************
3556  * init a structure.
3557  ********************************************************************/
3558
3559 BOOL make_spoolss_q_enumprinters(
3560         SPOOL_Q_ENUMPRINTERS *q_u, 
3561         uint32 flags, 
3562         char *servername, 
3563         uint32 level, 
3564         RPC_BUFFER *buffer, 
3565         uint32 offered
3566 )
3567 {
3568         q_u->flags=flags;
3569         
3570         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3571         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3572
3573         q_u->level=level;
3574         q_u->buffer=buffer;
3575         q_u->offered=offered;
3576
3577         return True;
3578 }
3579
3580 /*******************************************************************
3581  * init a structure.
3582  ********************************************************************/
3583
3584 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
3585                                 fstring servername, uint32 level, 
3586                                 RPC_BUFFER *buffer, uint32 offered)
3587 {
3588         q_u->name_ptr = (servername != NULL) ? 1 : 0;
3589         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3590
3591         q_u->level=level;
3592         q_u->buffer=buffer;
3593         q_u->offered=offered;
3594
3595         return True;
3596 }
3597
3598 /*******************************************************************
3599  * read a structure.
3600  * called from spoolss_enumprinters (srv_spoolss.c)
3601  ********************************************************************/
3602
3603 BOOL spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3604 {
3605         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3606         depth++;
3607
3608         if (!prs_align(ps))
3609                 return False;
3610
3611         if (!prs_uint32("flags", ps, depth, &q_u->flags))
3612                 return False;
3613         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3614                 return False;
3615
3616         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3617                 return False;
3618                 
3619         if (!prs_align(ps))
3620                 return False;
3621         if (!prs_uint32("level", ps, depth, &q_u->level))
3622                 return False;
3623
3624         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3625                 return False;
3626
3627         if (!prs_align(ps))
3628                 return False;
3629         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3630                 return False;
3631
3632         return True;
3633 }
3634
3635 /*******************************************************************
3636  Parse a SPOOL_R_ENUMPRINTERS structure.
3637  ********************************************************************/
3638
3639 BOOL spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3640 {
3641         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3642         depth++;
3643
3644         if (!prs_align(ps))
3645                 return False;
3646                 
3647         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3648                 return False;
3649
3650         if (!prs_align(ps))
3651                 return False;
3652                 
3653         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3654                 return False;
3655                 
3656         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3657                 return False;
3658                 
3659         if (!prs_werror("status", ps, depth, &r_u->status))
3660                 return False;
3661
3662         return True;            
3663 }
3664
3665 /*******************************************************************
3666  * write a structure.
3667  * called from spoolss_r_enum_printers (srv_spoolss.c)
3668  *
3669  ********************************************************************/
3670
3671 BOOL spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3672 {       
3673         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3674         depth++;
3675
3676         if (!prs_align(ps))
3677                 return False;
3678                 
3679         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3680                 return False;
3681
3682         if (!prs_align(ps))
3683                 return False;
3684
3685         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3686                 return False;
3687                 
3688         if (!prs_werror("status", ps, depth, &r_u->status))
3689                 return False;
3690
3691         return True;            
3692 }
3693
3694 /*******************************************************************
3695  * read a structure.
3696  * called from spoolss_getprinter (srv_spoolss.c)
3697  ********************************************************************/
3698
3699 BOOL spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3700 {
3701         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3702         depth++;
3703
3704         if (!prs_align(ps))
3705                 return False;
3706
3707         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3708                 return False;
3709         if (!prs_uint32("level", ps, depth, &q_u->level))
3710                 return False;
3711
3712         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3713                 return False;
3714
3715         if (!prs_align(ps))
3716                 return False;
3717         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3718                 return False;
3719
3720         return True;
3721 }
3722
3723 /*******************************************************************
3724  * init a structure.
3725  ********************************************************************/
3726
3727 BOOL make_spoolss_q_getprinter(
3728         TALLOC_CTX *mem_ctx,
3729         SPOOL_Q_GETPRINTER *q_u, 
3730         const POLICY_HND *hnd, 
3731         uint32 level, 
3732         RPC_BUFFER *buffer, 
3733         uint32 offered
3734 )
3735 {
3736         if (q_u == NULL)
3737         {
3738                 return False;
3739         }
3740         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3741
3742         q_u->level=level;
3743         q_u->buffer=buffer;
3744         q_u->offered=offered;
3745
3746         return True;
3747 }
3748
3749 /*******************************************************************
3750  * init a structure.
3751  ********************************************************************/
3752 BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
3753                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
3754                                 uint32 command)
3755 {
3756         SEC_DESC *secdesc;
3757         DEVICEMODE *devmode;
3758
3759         if (!q_u || !info)
3760                 return False;
3761         
3762         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3763
3764         q_u->level = level;
3765         q_u->info.level = level;
3766         q_u->info.info_ptr = 1; /* Info is != NULL, see above */
3767         switch (level) {
3768
3769           /* There's no such thing as a setprinter level 1 */
3770
3771         case 2:
3772                 secdesc = info->printers_2->secdesc;
3773                 devmode = info->printers_2->devmode;
3774                 
3775                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3776 #if 1   /* JERRY TEST */
3777                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3778                 if (!q_u->secdesc_ctr)
3779                         return False;
3780                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3781                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3782                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3783                 q_u->secdesc_ctr->sec = secdesc;
3784
3785                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3786                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3787                 q_u->devmode_ctr.devmode = devmode;
3788 #else
3789                 q_u->secdesc_ctr = NULL;
3790         
3791                 q_u->devmode_ctr.devmode_ptr = 0;
3792                 q_u->devmode_ctr.size = 0;
3793                 q_u->devmode_ctr.devmode = NULL;
3794 #endif
3795                 break;
3796         case 3:
3797                 secdesc = info->printers_3->secdesc;
3798                 
3799                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
3800                 
3801                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
3802                 if (!q_u->secdesc_ctr)
3803                         return False;
3804                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3805                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3806                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3807                 q_u->secdesc_ctr->sec = secdesc;
3808
3809                 break;
3810         case 7:
3811                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
3812                 break;
3813
3814         default: 
3815                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3816                         break;
3817         }
3818
3819         
3820         q_u->command = command;
3821
3822         return True;
3823 }
3824
3825
3826 /*******************************************************************
3827 ********************************************************************/  
3828
3829 BOOL spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3830 {               
3831         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3832         depth++;
3833
3834         if(!prs_align(ps))
3835                 return False;
3836         
3837         if(!prs_werror("status", ps, depth, &r_u->status))
3838                 return False;
3839
3840         return True;
3841 }
3842
3843 /*******************************************************************
3844  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3845 ********************************************************************/  
3846
3847 BOOL spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3848 {
3849         uint32 ptr_sec_desc = 0;
3850
3851         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3852         depth++;
3853
3854         if(!prs_align(ps))
3855                 return False;
3856
3857         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3858                 return False;
3859         if(!prs_uint32("level", ps, depth, &q_u->level))
3860                 return False;
3861         
3862         /* check for supported levels and structures we know about */
3863                 
3864         switch ( q_u->level ) {
3865                 case 0:
3866                 case 2:
3867                 case 3:
3868                 case 7:
3869                         /* supported levels */
3870                         break;
3871                 default:
3872                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
3873                                 q_u->level));
3874                         return True;
3875         }
3876                         
3877
3878         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3879                 return False;
3880
3881         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3882                 return False;
3883         
3884         if(!prs_align(ps))
3885                 return False;
3886
3887         switch (q_u->level)
3888         {
3889                 case 2:
3890                 {
3891                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3892                         break;
3893                 }
3894                 case 3:
3895                 {
3896                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3897                         break;
3898                 }
3899         }
3900         if (ptr_sec_desc)
3901         {
3902                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3903                         return False;
3904         } else {
3905                 uint32 dummy = 0;
3906
3907                 /* Parse a NULL security descriptor.  This should really
3908                    happen inside the sec_io_desc_buf() function. */
3909
3910                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3911                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3912                         return False;
3913                 if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
3914                                                                        False;
3915         }
3916         
3917         if(!prs_uint32("command", ps, depth, &q_u->command))
3918                 return False;
3919
3920         return True;
3921 }
3922
3923 /*******************************************************************
3924 ********************************************************************/  
3925
3926 BOOL spoolss_io_r_fcpn(const char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
3927 {               
3928         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
3929         depth++;
3930
3931         if(!prs_align(ps))
3932                 return False;
3933         
3934         if(!prs_werror("status", ps, depth, &r_u->status))
3935                 return False;
3936
3937         return True;
3938 }
3939
3940 /*******************************************************************
3941 ********************************************************************/  
3942
3943 BOOL spoolss_io_q_fcpn(const char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
3944 {
3945
3946         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
3947         depth++;
3948
3949         if(!prs_align(ps))
3950                 return False;
3951
3952         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3953                 return False;
3954
3955         return True;
3956 }
3957
3958
3959 /*******************************************************************
3960 ********************************************************************/  
3961
3962 BOOL spoolss_io_r_addjob(const char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
3963 {               
3964         prs_debug(ps, depth, desc, "");
3965         depth++;
3966
3967         if(!prs_align(ps))
3968                 return False;
3969         
3970         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3971                 return False;
3972
3973         if(!prs_align(ps))
3974                 return False;
3975         
3976         if(!prs_uint32("needed", ps, depth, &r_u->needed))
3977                 return False;
3978
3979         if(!prs_werror("status", ps, depth, &r_u->status))
3980                 return False;
3981
3982         return True;
3983 }
3984
3985 /*******************************************************************
3986 ********************************************************************/  
3987
3988 BOOL spoolss_io_q_addjob(const char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
3989 {
3990         prs_debug(ps, depth, desc, "");
3991         depth++;
3992
3993         if(!prs_align(ps))
3994                 return False;
3995
3996         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3997                 return False;
3998         if(!prs_uint32("level", ps, depth, &q_u->level))
3999                 return False;
4000         
4001         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4002                 return False;
4003
4004         if(!prs_align(ps))
4005                 return False;
4006         
4007         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4008                 return False;
4009
4010         return True;
4011 }
4012
4013 /*******************************************************************
4014 ********************************************************************/  
4015
4016 BOOL spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
4017 {               
4018         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
4019         depth++;
4020
4021         if (!prs_align(ps))
4022                 return False;
4023                 
4024         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4025                 return False;
4026
4027         if (!prs_align(ps))
4028                 return False;
4029                 
4030         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4031                 return False;
4032                 
4033         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4034                 return False;
4035                 
4036         if (!prs_werror("status", ps, depth, &r_u->status))
4037                 return False;
4038
4039         return True;            
4040 }
4041
4042 /*******************************************************************
4043 ********************************************************************/  
4044
4045 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4046                                 uint32 firstjob,
4047                                 uint32 numofjobs,
4048                                 uint32 level,
4049                                 RPC_BUFFER *buffer,
4050                                 uint32 offered)
4051 {
4052         if (q_u == NULL)
4053         {
4054                 return False;
4055         }
4056         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4057         q_u->firstjob = firstjob;
4058         q_u->numofjobs = numofjobs;
4059         q_u->level = level;
4060         q_u->buffer= buffer;
4061         q_u->offered = offered;
4062         return True;
4063 }
4064
4065 /*******************************************************************
4066 ********************************************************************/  
4067
4068 BOOL spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4069 {
4070         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4071         depth++;
4072
4073         if (!prs_align(ps))
4074                 return False;
4075
4076         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4077                 return False;
4078                 
4079         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4080                 return False;
4081         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4082                 return False;
4083         if (!prs_uint32("level", ps, depth, &q_u->level))
4084                 return False;
4085
4086         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4087                 return False;   
4088
4089         if(!prs_align(ps))
4090                 return False;
4091
4092         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4093                 return False;
4094
4095         return True;
4096 }
4097
4098 /*******************************************************************
4099 ********************************************************************/  
4100
4101 BOOL spoolss_io_r_schedulejob(const char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4102 {               
4103         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4104         depth++;
4105
4106         if(!prs_align(ps))
4107                 return False;
4108         
4109         if(!prs_werror("status", ps, depth, &r_u->status))
4110                 return False;
4111
4112         return True;
4113 }
4114
4115 /*******************************************************************
4116 ********************************************************************/  
4117
4118 BOOL spoolss_io_q_schedulejob(const char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4119 {
4120         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4121         depth++;
4122
4123         if(!prs_align(ps))
4124                 return False;
4125
4126         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4127                 return False;
4128         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4129                 return False;
4130
4131         return True;
4132 }
4133
4134 /*******************************************************************
4135 ********************************************************************/  
4136
4137 BOOL spoolss_io_r_setjob(const char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4138 {               
4139         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4140         depth++;
4141
4142         if(!prs_align(ps))
4143                 return False;
4144         
4145         if(!prs_werror("status", ps, depth, &r_u->status))
4146                 return False;
4147
4148         return True;
4149 }
4150
4151 /*******************************************************************
4152 ********************************************************************/  
4153
4154 BOOL spoolss_io_q_setjob(const char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4155 {
4156         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4157         depth++;
4158
4159         if(!prs_align(ps))
4160                 return False;
4161
4162         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4163                 return False;
4164         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4165                 return False;
4166         /* 
4167          * level is usually 0. If (level!=0) then I'm in trouble !
4168          * I will try to generate setjob command with level!=0, one day.
4169          */
4170         if(!prs_uint32("level", ps, depth, &q_u->level))
4171                 return False;
4172         if(!prs_uint32("command", ps, depth, &q_u->command))
4173                 return False;
4174
4175         return True;
4176 }
4177
4178 /*******************************************************************
4179  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4180 ********************************************************************/  
4181
4182 BOOL spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4183 {
4184         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4185         depth++;
4186
4187         if (!prs_align(ps))
4188                 return False;
4189                 
4190         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4191                 return False;
4192
4193         if (!prs_align(ps))
4194                 return False;
4195                 
4196         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4197                 return False;
4198                 
4199         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4200                 return False;
4201                 
4202         if (!prs_werror("status", ps, depth, &r_u->status))
4203                 return False;
4204
4205         return True;            
4206 }
4207
4208 /*******************************************************************
4209  * init a structure.
4210  ********************************************************************/
4211
4212 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4213                                 const char *name,
4214                                 const char *environment,
4215                                 uint32 level,
4216                                 RPC_BUFFER *buffer, uint32 offered)
4217 {
4218         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4219         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4220
4221         q_u->level=level;
4222         q_u->buffer=buffer;
4223         q_u->offered=offered;
4224
4225         return True;
4226 }
4227
4228 /*******************************************************************
4229  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4230 ********************************************************************/  
4231
4232 BOOL spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4233 {
4234
4235         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4236         depth++;
4237
4238         if (!prs_align(ps))
4239                 return False;
4240                 
4241         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4242                 return False;
4243         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4244                 return False;
4245                 
4246         if (!prs_align(ps))
4247                 return False;
4248         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4249                 return False;
4250         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4251                 return False;
4252                 
4253         if (!prs_align(ps))
4254                 return False;
4255         if (!prs_uint32("level", ps, depth, &q_u->level))
4256                 return False;
4257                 
4258         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4259                 return False;
4260
4261         if (!prs_align(ps))
4262                 return False;
4263                 
4264         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4265                 return False;
4266
4267         return True;
4268 }
4269
4270 /*******************************************************************
4271 ********************************************************************/  
4272
4273 BOOL spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4274 {
4275
4276         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4277         depth++;
4278
4279         if (!prs_align(ps))
4280                 return False;                   
4281         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4282                 return False;           
4283         if (!prs_uint32("level", ps, depth, &q_u->level))
4284                 return False;   
4285         
4286         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4287                 return False;
4288
4289         if (!prs_align(ps))
4290                 return False;
4291         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4292                 return False;
4293
4294         return True;
4295 }
4296
4297 /*******************************************************************
4298 ********************************************************************/  
4299
4300 BOOL spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4301 {
4302         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4303         depth++;
4304
4305         if (!prs_align(ps))
4306                 return False;
4307                 
4308         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4309                 return False;
4310
4311         if (!prs_align(ps))
4312                 return False;
4313                 
4314         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4315                 return False;
4316                 
4317         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4318                 return False;
4319                 
4320         if (!prs_werror("status", ps, depth, &r_u->status))
4321                 return False;
4322
4323         return True;
4324 }
4325
4326 /*******************************************************************
4327 ********************************************************************/  
4328
4329 BOOL spoolss_io_q_getform(const char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4330 {
4331
4332         prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4333         depth++;
4334
4335         if (!prs_align(ps))
4336                 return False;                   
4337         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4338                 return False;           
4339         if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4340                 return False;
4341
4342         if (!prs_align(ps))
4343                 return False;
4344
4345         if (!prs_uint32("level", ps, depth, &q_u->level))
4346                 return False;   
4347         
4348         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4349                 return False;
4350
4351         if (!prs_align(ps))
4352                 return False;
4353         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4354                 return False;
4355
4356         return True;
4357 }
4358
4359 /*******************************************************************
4360 ********************************************************************/  
4361
4362 BOOL spoolss_io_r_getform(const char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4363 {
4364         prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4365         depth++;
4366
4367         if (!prs_align(ps))
4368                 return False;
4369                 
4370         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4371                 return False;
4372
4373         if (!prs_align(ps))
4374                 return False;
4375                 
4376         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4377                 return False;
4378                 
4379         if (!prs_werror("status", ps, depth, &r_u->status))
4380                 return False;
4381
4382         return True;
4383 }
4384
4385 /*******************************************************************
4386  Parse a SPOOL_R_ENUMPORTS structure.
4387 ********************************************************************/  
4388
4389 BOOL spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4390 {
4391         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4392         depth++;
4393
4394         if (!prs_align(ps))
4395                 return False;
4396                 
4397         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
4398                 return False;
4399
4400         if (!prs_align(ps))
4401                 return False;
4402                 
4403         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4404                 return False;
4405                 
4406         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4407                 return False;
4408                 
4409         if (!prs_werror("status", ps, depth, &r_u->status))
4410                 return False;
4411
4412         return True;            
4413 }
4414
4415 /*******************************************************************
4416 ********************************************************************/  
4417
4418 BOOL spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4419 {
4420         prs_debug(ps, depth, desc, "");
4421         depth++;
4422
4423         if (!prs_align(ps))
4424                 return False;
4425
4426         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4427                 return False;
4428         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4429                 return False;
4430
4431         if (!prs_align(ps))
4432                 return False;
4433         if (!prs_uint32("level", ps, depth, &q_u->level))
4434                 return False;
4435                 
4436         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
4437                 return False;
4438
4439         if (!prs_align(ps))
4440                 return False;
4441         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4442                 return False;
4443
4444         return True;
4445 }
4446
4447 /*******************************************************************
4448  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4449 ********************************************************************/  
4450
4451 BOOL spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4452 {       
4453         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4454         depth++;
4455                 
4456         if(!prs_align(ps))
4457                 return False;
4458
4459         if(!prs_uint32("flags", ps, depth, &il->flags))
4460                 return False;
4461         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4462                 return False;
4463         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4464                 return False;
4465         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4466                 return False;
4467                 
4468         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4469                 return False;
4470         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4471                 return False;
4472         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4473                 return False;
4474
4475         return True;
4476 }
4477
4478 /*******************************************************************
4479  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4480 ********************************************************************/  
4481
4482 BOOL spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4483 {       
4484         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4485         depth++;
4486                 
4487         if(!prs_align(ps))
4488                 return False;
4489
4490         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4491                 return False;
4492
4493         return True;
4494 }
4495
4496 /*******************************************************************
4497  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4498 ********************************************************************/  
4499
4500 BOOL spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4501 {       
4502         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4503         depth++;
4504                 
4505         if(!prs_align(ps))
4506                 return False;
4507
4508         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4509                 return False;
4510         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4511                 return False;
4512         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4513                 return False;
4514         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4515                 return False;
4516
4517         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4518                 return False;
4519         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4520                 return False;
4521         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4522                 return False;
4523         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4524                 return False;
4525         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4526                 return False;
4527         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4528                 return False;
4529         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4530                 return False;
4531         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4532                 return False;
4533         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4534                 return False;
4535
4536         if(!prs_uint32("attributes", ps, depth, &il->attributes))
4537                 return False;
4538         if(!prs_uint32("priority", ps, depth, &il->priority))
4539                 return False;
4540         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4541                 return False;
4542         if(!prs_uint32("starttime", ps, depth, &il->starttime))
4543                 return False;
4544         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4545                 return False;
4546         if(!prs_uint32("status", ps, depth, &il->status))
4547                 return False;
4548         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4549                 return False;
4550         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4551                 return False;
4552
4553         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4554                 return False;
4555         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4556                 return False;
4557         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4558                 return False;
4559         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4560                 return False;
4561         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4562                 return False;
4563         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4564                 return False;
4565         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4566                 return False;
4567         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4568                 return False;
4569         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4570                 return False;
4571         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4572                 return False;
4573         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4574                 return False;
4575
4576         return True;
4577 }
4578
4579 BOOL spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
4580 {       
4581         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
4582         depth++;
4583                 
4584         if(!prs_align(ps))
4585                 return False;
4586
4587         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
4588                 return False;
4589         if(!prs_uint32("action", ps, depth, &il->action))
4590                 return False;
4591
4592         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
4593                 return False;
4594         return True;
4595 }
4596
4597 /*******************************************************************
4598 ********************************************************************/  
4599
4600 BOOL spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4601 {
4602         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4603         depth++;
4604
4605         if(!prs_align(ps))
4606                 return False;
4607         if(!prs_uint32("level", ps, depth, &il->level))
4608                 return False;
4609         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4610                 return False;
4611         
4612         /* if no struct inside just return */
4613         if (il->info_ptr==0) {
4614                 if (UNMARSHALLING(ps)) {
4615                         il->info_1=NULL;
4616                         il->info_2=NULL;
4617                 }
4618                 return True;
4619         }
4620                         
4621         switch (il->level) {
4622                 /*
4623                  * level 0 is used by setprinter when managing the queue
4624                  * (hold, stop, start a queue)
4625                  */
4626                 case 0:
4627                         break;
4628                 /* DOCUMENT ME!!! What is level 1 used for? */
4629                 case 1:
4630                 {
4631                         if (UNMARSHALLING(ps)) {
4632                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
4633                                         return False;
4634                         }
4635                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4636                                 return False;
4637                         break;          
4638                 }
4639                 /* 
4640                  * level 2 is used by addprinter
4641                  * and by setprinter when updating printer's info
4642                  */     
4643                 case 2:
4644                         if (UNMARSHALLING(ps)) {
4645                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
4646                                         return False;
4647                         }
4648                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4649                                 return False;
4650                         break;          
4651                 /* DOCUMENT ME!!! What is level 3 used for? */
4652                 case 3:
4653                 {
4654                         if (UNMARSHALLING(ps)) {
4655                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
4656                                         return False;
4657                         }
4658                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4659                                 return False;
4660                         break;          
4661                 }
4662                 case 7:
4663                         if (UNMARSHALLING(ps))
4664                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
4665                                         return False;
4666                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
4667                                 return False;
4668                         break;
4669         }
4670
4671         return True;
4672 }
4673
4674 /*******************************************************************
4675 ********************************************************************/  
4676
4677 BOOL spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4678 {
4679         uint32 ptr_sec_desc = 0;
4680
4681         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4682         depth++;
4683
4684         if(!prs_align(ps))
4685                 return False;
4686
4687         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
4688                 return False;
4689         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
4690                 return False;
4691
4692         if(!prs_align(ps))
4693                 return False;
4694
4695         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4696                 return False;
4697         
4698         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4699                 return False;
4700         
4701         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4702                 return False;
4703
4704         if(!prs_align(ps))
4705                 return False;
4706
4707         switch (q_u->level) {
4708                 case 2:
4709                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4710                         break;
4711                 case 3:
4712                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4713                         break;
4714         }
4715         if (ptr_sec_desc) {
4716                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4717                         return False;
4718         } else {
4719                 uint32 dummy;
4720
4721                 /* Parse a NULL security descriptor.  This should really
4722                         happen inside the sec_io_desc_buf() function. */
4723
4724                 prs_debug(ps, depth, "", "sec_io_desc_buf");
4725                 if (!prs_uint32("size", ps, depth + 1, &dummy))
4726                         return False;
4727                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
4728                         return False;
4729         }
4730
4731         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4732                 return False;
4733         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4734                 return False;
4735
4736         return True;
4737 }
4738
4739 /*******************************************************************
4740 ********************************************************************/  
4741
4742 BOOL spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
4743                                prs_struct *ps, int depth)
4744 {
4745         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4746         depth++;
4747         
4748         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4749                 return False;
4750
4751         if(!prs_werror("status", ps, depth, &r_u->status))
4752                 return False;
4753
4754         return True;
4755 }
4756
4757 /*******************************************************************
4758 ********************************************************************/  
4759
4760 BOOL spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
4761                                           prs_struct *ps, int depth)
4762 {       
4763         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4764         
4765         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4766         depth++;
4767                 
4768         /* reading */
4769         if (UNMARSHALLING(ps)) {
4770                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
4771                 if(il == NULL)
4772                         return False;
4773                 *q_u=il;
4774         }
4775         else {
4776                 il=*q_u;
4777         }
4778         
4779         if(!prs_align(ps))
4780                 return False;
4781
4782         if(!prs_uint32("cversion", ps, depth, &il->cversion))
4783                 return False;
4784         if(!prs_uint32("name", ps, depth, &il->name_ptr))
4785                 return False;
4786         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4787                 return False;
4788         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4789                 return False;
4790         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4791                 return False;
4792         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4793                 return False;
4794         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4795                 return False;
4796         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4797                 return False;
4798         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4799                 return False;
4800         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4801                 return False;
4802         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4803                 return False;
4804
4805         if(!prs_align(ps))
4806                 return False;
4807         
4808         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4809                 return False;
4810         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4811                 return False;
4812         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4813                 return False;
4814         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4815                 return False;
4816         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4817                 return False;
4818         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4819                 return False;
4820         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4821                 return False;
4822         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4823                 return False;
4824
4825         if(!prs_align(ps))
4826                 return False;
4827                 
4828         if (il->dependentfiles_ptr)
4829                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4830
4831         return True;
4832 }
4833
4834 /*******************************************************************
4835 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4836 ********************************************************************/  
4837
4838 BOOL spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4839                                           prs_struct *ps, int depth)
4840 {       
4841         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4842         
4843         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4844         depth++;
4845                 
4846         /* reading */
4847         if (UNMARSHALLING(ps)) {
4848                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
4849                 if(il == NULL)
4850                         return False;
4851                 *q_u=il;
4852         }
4853         else {
4854                 il=*q_u;
4855         }
4856         
4857         if(!prs_align(ps))
4858                 return False;
4859
4860         /* 
4861          * I know this seems weird, but I have no other explanation.
4862          * This is observed behavior on both NT4 and 2K servers.
4863          * --jerry
4864          */
4865          
4866         if (!prs_align_uint64(ps))
4867                 return False;
4868
4869         /* parse the main elements the packet */
4870
4871         if(!prs_uint32("cversion       ", ps, depth, &il->version))
4872                 return False;
4873         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
4874                 return False;
4875         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
4876                 return False;
4877         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
4878                 return False;
4879         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
4880                 return False;
4881         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
4882                 return False;
4883         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
4884                 return False;
4885         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
4886                 return False;
4887         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4888                 return False;
4889         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
4890                 return False;
4891         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
4892                 return False;
4893         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
4894                 return False;
4895         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
4896                 return False;
4897         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
4898                 return False;
4899         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
4900                 return False;
4901         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
4902                 return False;
4903         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
4904                 return False;
4905         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
4906                 return False;
4907         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
4908                 return False;
4909         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
4910                 return False;
4911
4912         /* parse the structures in the packet */
4913
4914         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4915                 return False;
4916         if(!prs_align(ps))
4917                 return False;
4918
4919         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4920                 return False;
4921         if(!prs_align(ps))
4922                 return False;
4923
4924         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4925                 return False;
4926         if(!prs_align(ps))
4927                 return False;
4928
4929         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4930                 return False;
4931         if(!prs_align(ps))
4932                 return False;
4933
4934         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4935                 return False;
4936         if(!prs_align(ps))
4937                 return False;
4938
4939         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4940                 return False;
4941         if(!prs_align(ps))
4942                 return False;
4943
4944         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4945                 return False;
4946         if(!prs_align(ps))
4947                 return False;
4948
4949         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4950                 return False;
4951         if(!prs_align(ps))
4952                 return False;
4953         if (il->dependentfiles_ptr) {
4954                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
4955                         return False;
4956                 if(!prs_align(ps))
4957                         return False;
4958         }
4959         if (il->previousnames_ptr) {
4960                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
4961                         return False;
4962                 if(!prs_align(ps))
4963                         return False;
4964         }
4965         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
4966                 return False;
4967         if(!prs_align(ps))
4968                 return False;
4969         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
4970                 return False;
4971         if(!prs_align(ps))
4972                 return False;
4973         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
4974                 return False;
4975         if(!prs_align(ps))
4976                 return False;
4977         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
4978                 return False;
4979
4980         return True;
4981 }
4982
4983 /*******************************************************************
4984  convert a buffer of UNICODE strings null terminated
4985  the buffer is terminated by a NULL
4986  
4987  convert to an dos codepage array (null terminated)
4988  
4989  dynamically allocate memory
4990  
4991 ********************************************************************/  
4992
4993 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
4994 {
4995         fstring f;
4996         int n = 0;
4997         char *src;
4998
4999         if (buf5==NULL)
5000                 return False;
5001
5002         src = (char *)buf5->buffer;
5003         *ar = SMB_MALLOC_ARRAY(fstring, 1);
5004         if (!*ar) {
5005                 return False;
5006         }
5007
5008         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
5009                 rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
5010                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
5011                 *ar = SMB_REALLOC_ARRAY(*ar, fstring, n+2);
5012                 if (!*ar) {
5013                         return False;
5014                 }
5015                 fstrcpy((*ar)[n], f);
5016                 n++;
5017         }
5018
5019         fstrcpy((*ar)[n], "");
5020  
5021         return True;
5022 }
5023
5024 /*******************************************************************
5025  read a UNICODE array with null terminated strings 
5026  and null terminated array 
5027  and size of array at beginning
5028 ********************************************************************/  
5029
5030 BOOL smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
5031 {
5032         if (buffer==NULL) return False;
5033
5034         buffer->offset=0;
5035         buffer->uni_str_len=buffer->uni_max_len;
5036         
5037         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
5038                 return False;
5039
5040         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
5041                 return False;
5042
5043         return True;
5044 }
5045
5046 /*******************************************************************
5047 ********************************************************************/  
5048
5049 BOOL spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
5050 {
5051         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
5052         depth++;
5053
5054         if(!prs_align(ps))
5055                 return False;
5056         if(!prs_uint32("level", ps, depth, &il->level))
5057                 return False;
5058         if(!prs_uint32("ptr", ps, depth, &il->ptr))
5059                 return False;
5060
5061         if (il->ptr==0)
5062                 return True;
5063                 
5064         switch (il->level) {
5065                 case 3:
5066                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
5067                                 return False;
5068                         break;          
5069                 case 6:
5070                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5071                                 return False;
5072                         break;          
5073         default:
5074                 return False;
5075         }
5076
5077         return True;
5078 }
5079
5080 /*******************************************************************
5081  init a SPOOL_Q_ADDPRINTERDRIVER struct
5082  ******************************************************************/
5083
5084 BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5085                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
5086                                 uint32 level, PRINTER_DRIVER_CTR *info)
5087 {
5088         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5089         
5090         if (!srv_name || !info) {
5091                 return False;
5092         }
5093
5094         q_u->server_name_ptr = 1; /* srv_name is != NULL, see above */
5095         init_unistr2(&q_u->server_name, srv_name, UNI_STR_TERMINATE);
5096         
5097         q_u->level = level;
5098         
5099         q_u->info.level = level;
5100         q_u->info.ptr = 1;      /* Info is != NULL, see above */
5101         switch (level)
5102         {
5103         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5104         case 3 :
5105                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5106                 break;
5107                 
5108         default:
5109                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5110                 break;
5111         }
5112         
5113         return True;
5114 }
5115
5116 BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, 
5117         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5118                                 DRIVER_INFO_3 *info3)
5119 {
5120         uint32          len = 0;
5121         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5122
5123         if (!(inf=TALLOC_ZERO_P(mem_ctx, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)))
5124                 return False;
5125         
5126         inf->cversion   = info3->version;
5127         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
5128         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
5129         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
5130         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
5131         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
5132         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
5133         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
5134         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
5135
5136         init_unistr2_from_unistr(&inf->name, &info3->name);
5137         init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5138         init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5139         init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5140         init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5141         init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5142         init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5143         init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5144
5145         if (info3->dependentfiles) {
5146                 BOOL done = False;
5147                 BOOL null_char = False;
5148                 uint16 *ptr = info3->dependentfiles;
5149
5150                 while (!done) {
5151                         switch (*ptr) {
5152                                 case 0:
5153                                         /* the null_char BOOL is used to help locate
5154                                            two '\0's back to back */
5155                                         if (null_char) {
5156                                                 done = True;
5157                                         } else {
5158                                                 null_char = True;
5159                                         }
5160                                         break;
5161                                         
5162                                 default:
5163                                         null_char = False;
5164                                         break;                          
5165                         }
5166                         len++;
5167                         ptr++;
5168                 }
5169         }
5170
5171         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5172         inf->dependentfilessize = (info3->dependentfiles != NULL) ? len : 0;
5173         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles)) {
5174                 SAFE_FREE(inf);
5175                 return False;
5176         }
5177         
5178         *spool_drv_info = inf;
5179         
5180         return True;
5181 }
5182
5183 /*******************************************************************
5184  make a BUFFER5 struct from a uint16*
5185  ******************************************************************/
5186
5187 BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5188 {
5189
5190         buf5->buf_len = len;
5191         if (src) {
5192                 if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
5193                         DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5194                         return False;
5195                 }
5196         } else {
5197                 buf5->buffer=NULL;
5198         }
5199         
5200         return True;
5201 }
5202
5203 /*******************************************************************
5204  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5205  ********************************************************************/  
5206
5207 BOOL spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5208 {
5209         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5210         depth++;
5211
5212         if(!prs_align(ps))
5213                 return False;
5214
5215         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5216                 return False;
5217         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5218                 return False;
5219                 
5220         if(!prs_align(ps))
5221                 return False;
5222         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5223                 return False;
5224
5225         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5226                 return False;
5227
5228         return True;
5229 }
5230
5231 /*******************************************************************
5232 ********************************************************************/  
5233
5234 BOOL spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5235 {
5236         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5237         depth++;
5238
5239         if(!prs_werror("status", ps, depth, &q_u->status))
5240                 return False;
5241
5242         return True;
5243 }
5244
5245 /*******************************************************************
5246  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5247  ********************************************************************/  
5248
5249 BOOL spoolss_io_q_addprinterdriverex(const char *desc, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5250 {
5251         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriverex");
5252         depth++;
5253
5254         if(!prs_align(ps))
5255                 return False;
5256
5257         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5258                 return False;
5259         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5260                 return False;
5261                 
5262         if(!prs_align(ps))
5263                 return False;
5264         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5265                 return False;
5266
5267         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5268                 return False;
5269
5270         if(!prs_align(ps))
5271                 return False;
5272         if(!prs_uint32("copy flags", ps, depth, &q_u->copy_flags))
5273                 return False;
5274                 
5275         return True;
5276 }
5277
5278 /*******************************************************************
5279 ********************************************************************/  
5280
5281 BOOL spoolss_io_r_addprinterdriverex(const char *desc, SPOOL_R_ADDPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
5282 {
5283         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriverex");
5284         depth++;
5285
5286         if(!prs_werror("status", ps, depth, &q_u->status))
5287                 return False;
5288
5289         return True;
5290 }
5291
5292 /*******************************************************************
5293 ********************************************************************/  
5294
5295 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5296                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5297 {
5298         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5299         
5300         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5301         
5302         if (*asc==NULL)
5303         {
5304                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
5305                 if(*asc == NULL)
5306                         return False;
5307                 ZERO_STRUCTP(*asc);
5308         }       
5309
5310         d=*asc;
5311
5312         d->cversion=uni->cversion;
5313
5314         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5315         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5316         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5317         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5318         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5319         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5320         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5321         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5322
5323         DEBUGADD(8,( "version:         %d\n", d->cversion));
5324         DEBUGADD(8,( "name:            %s\n", d->name));
5325         DEBUGADD(8,( "environment:     %s\n", d->environment));
5326         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5327         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5328         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5329         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5330         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5331         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5332
5333         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5334                 return True;
5335         
5336         SAFE_FREE(*asc);
5337         return False;
5338 }
5339
5340 /*******************************************************************
5341 ********************************************************************/  
5342 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5343                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5344 {
5345         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5346         
5347         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5348         
5349         if (*asc==NULL)
5350         {
5351                 *asc=SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
5352                 if(*asc == NULL)
5353                         return False;
5354                 ZERO_STRUCTP(*asc);
5355         }       
5356
5357         d=*asc;
5358
5359         d->version=uni->version;
5360
5361         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5362         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5363         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5364         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5365         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5366         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5367         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5368         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5369
5370         DEBUGADD(8,( "version:         %d\n", d->version));
5371         DEBUGADD(8,( "name:            %s\n", d->name));
5372         DEBUGADD(8,( "environment:     %s\n", d->environment));
5373         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5374         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5375         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5376         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5377         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5378         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5379
5380         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5381                 goto error;
5382         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5383                 goto error;
5384         
5385         return True;
5386         
5387 error:
5388         SAFE_FREE(*asc);
5389         return False;
5390 }
5391
5392 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5393                               NT_PRINTER_INFO_LEVEL_2  *d)
5394 {
5395         DEBUG(7,("Converting from UNICODE to ASCII\n"));
5396         
5397         d->attributes=uni->attributes;
5398         d->priority=uni->priority;
5399         d->default_priority=uni->default_priority;
5400         d->starttime=uni->starttime;
5401         d->untiltime=uni->untiltime;
5402         d->status=uni->status;
5403         d->cjobs=uni->cjobs;
5404         
5405         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5406         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5407         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5408         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5409         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5410         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5411         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5412         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5413         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5414         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5415         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5416
5417         return True;
5418 }
5419
5420 /*******************************************************************
5421  * init a structure.
5422  ********************************************************************/
5423
5424 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5425                                 fstring servername, fstring env_name, uint32 level,
5426                                 RPC_BUFFER *buffer, uint32 offered)
5427 {
5428         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5429         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5430
5431         q_u->level=level;
5432         q_u->buffer=buffer;
5433         q_u->offered=offered;
5434
5435         return True;
5436 }
5437
5438 /*******************************************************************
5439  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5440 ********************************************************************/  
5441
5442 BOOL spoolss_io_q_getprinterdriverdir(const char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5443 {
5444         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5445         depth++;
5446
5447         if(!prs_align(ps))
5448                 return False;
5449         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5450                 return False;
5451         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5452                 return False;
5453
5454         if(!prs_align(ps))
5455                 return False;
5456                 
5457         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5458                 return False;
5459         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5460                 return False;
5461                 
5462         if(!prs_align(ps))
5463                 return False;
5464
5465         if(!prs_uint32("level", ps, depth, &q_u->level))
5466                 return False;
5467                 
5468         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5469                 return False;
5470                 
5471         if(!prs_align(ps))
5472                 return False;
5473                 
5474         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5475                 return False;
5476
5477         return True;
5478 }
5479
5480 /*******************************************************************
5481  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5482 ********************************************************************/  
5483
5484 BOOL spoolss_io_r_getprinterdriverdir(const char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5485 {               
5486         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5487         depth++;
5488
5489         if (!prs_align(ps))
5490                 return False;
5491                 
5492         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5493                 return False;
5494
5495         if (!prs_align(ps))
5496                 return False;
5497                 
5498         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5499                 return False;
5500                 
5501         if (!prs_werror("status", ps, depth, &r_u->status))
5502                 return False;
5503
5504         return True;            
5505 }
5506
5507 /*******************************************************************
5508 ********************************************************************/  
5509
5510 BOOL spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5511 {               
5512         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5513         depth++;
5514
5515         if (!prs_align(ps))
5516                 return False;
5517                 
5518         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5519                 return False;
5520
5521         if (!prs_align(ps))
5522                 return False;
5523                 
5524         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5525                 return False;
5526                 
5527         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5528                 return False;
5529                 
5530         if (!prs_werror("status", ps, depth, &r_u->status))
5531                 return False;
5532
5533         return True;            
5534 }
5535
5536 /*******************************************************************
5537 ********************************************************************/  
5538
5539 BOOL spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5540 {
5541         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5542         depth++;
5543
5544         if (!prs_align(ps))
5545                 return False;
5546                 
5547         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5548                 return False;
5549         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5550                 return False;
5551                 
5552         if (!prs_align(ps))
5553                 return False;
5554                 
5555         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5556                 return False;
5557         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5558                 return False;
5559         
5560         if (!prs_align(ps))
5561                 return False;
5562                 
5563         if (!prs_uint32("level", ps, depth, &q_u->level))
5564                 return False;
5565                 
5566         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5567                 return False;
5568
5569         if (!prs_align(ps))
5570                 return False;
5571
5572         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5573                 return False;
5574
5575         return True;
5576 }
5577
5578 /*******************************************************************
5579 ********************************************************************/  
5580
5581 BOOL spoolss_io_q_addprintprocessor(const char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5582 {
5583         prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5584         depth++;
5585
5586         if (!prs_align(ps))
5587                 return False;
5588                 
5589         if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5590                 return False;
5591         if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5592                 return False;
5593                 
5594         if (!prs_align(ps))
5595                 return False;
5596         if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5597                 return False;
5598                 
5599         if (!prs_align(ps))
5600                 return False;
5601         if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5602                 return False;
5603
5604         if (!prs_align(ps))
5605                 return False;
5606         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5607                 return False;
5608
5609         return True;
5610 }
5611
5612 /*******************************************************************
5613 ********************************************************************/  
5614
5615 BOOL spoolss_io_r_addprintprocessor(const char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5616 {               
5617         prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5618         depth++;
5619
5620         if (!prs_align(ps))
5621                 return False;
5622                 
5623         if (!prs_werror("status", ps, depth, &r_u->status))
5624                 return False;
5625
5626         return True;            
5627 }
5628
5629 /*******************************************************************
5630 ********************************************************************/  
5631
5632 BOOL spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5633 {               
5634         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5635         depth++;
5636
5637         if (!prs_align(ps))
5638                 return False;
5639                 
5640         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5641                 return False;
5642
5643         if (!prs_align(ps))
5644                 return False;
5645                 
5646         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5647                 return False;
5648                 
5649         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5650                 return False;
5651                 
5652         if (!prs_werror("status", ps, depth, &r_u->status))
5653                 return False;
5654
5655         return True;            
5656 }
5657
5658 /*******************************************************************
5659 ********************************************************************/  
5660
5661 BOOL spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5662 {
5663         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5664         depth++;
5665
5666         if (!prs_align(ps))
5667                 return False;
5668                 
5669         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5670                 return False;
5671         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5672                 return False;
5673                 
5674         if (!prs_align(ps))
5675                 return False;
5676                 
5677         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5678                 return False;
5679         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5680                 return False;
5681         
5682         if (!prs_align(ps))
5683                 return False;
5684                 
5685         if (!prs_uint32("level", ps, depth, &q_u->level))
5686                 return False;
5687                 
5688         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
5689                 return False;
5690
5691         if (!prs_align(ps))
5692                 return False;
5693
5694         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5695                 return False;
5696
5697         return True;
5698 }
5699
5700 /*******************************************************************
5701  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5702 ********************************************************************/  
5703
5704 BOOL spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
5705 {
5706         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
5707         depth++;
5708
5709         if (!prs_align(ps))
5710                 return False;
5711                 
5712         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5713                 return False;
5714         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5715                 return False;
5716                 
5717         if (!prs_align(ps))
5718                 return False;
5719                                 
5720         if (!prs_uint32("level", ps, depth, &q_u->level))
5721                 return False;
5722                 
5723         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
5724                 return False;
5725
5726         if (!prs_align(ps))
5727                 return False;
5728
5729         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5730                 return False;
5731
5732         return True;
5733 }
5734
5735 /*******************************************************************
5736 ********************************************************************/  
5737
5738 BOOL spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
5739 {               
5740         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
5741         depth++;
5742
5743         if (!prs_align(ps))
5744                 return False;
5745                 
5746         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
5747                 return False;
5748
5749         if (!prs_align(ps))
5750                 return False;
5751                 
5752         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5753                 return False;
5754                 
5755         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5756                 return False;
5757                 
5758         if (!prs_werror("status", ps, depth, &r_u->status))
5759                 return False;
5760
5761         return True;            
5762 }
5763
5764 /*******************************************************************
5765 ********************************************************************/  
5766
5767 BOOL spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
5768 {       
5769         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
5770         depth++;
5771
5772         if(!prs_align(ps))
5773                 return False;
5774         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
5775                 return False;
5776
5777         if (UNMARSHALLING(ps) && r_u->valuesize) {
5778                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
5779                 if (!r_u->value) {
5780                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
5781                         return False;
5782                 }
5783         }
5784
5785         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
5786                 return False;
5787
5788         if(!prs_align(ps))
5789                 return False;
5790
5791         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
5792                 return False;
5793
5794         if(!prs_uint32("type", ps, depth, &r_u->type))
5795                 return False;
5796
5797         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
5798                 return False;
5799
5800         if (UNMARSHALLING(ps) && r_u->datasize) {
5801                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
5802                 if (!r_u->data) {
5803                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
5804                         return False;
5805                 }
5806         }
5807
5808         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
5809                 return False;
5810         if(!prs_align(ps))
5811                 return False;
5812
5813         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
5814                 return False;
5815         if(!prs_werror("status", ps, depth, &r_u->status))
5816                 return False;
5817
5818         return True;
5819 }
5820
5821 /*******************************************************************
5822 ********************************************************************/  
5823
5824 BOOL spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
5825 {
5826         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
5827         depth++;
5828
5829         if(!prs_align(ps))
5830                 return False;
5831         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5832                 return False;
5833         if(!prs_uint32("index", ps, depth, &q_u->index))
5834                 return False;
5835         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
5836                 return False;
5837         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
5838                 return False;
5839
5840         return True;
5841 }
5842
5843 /*******************************************************************
5844 ********************************************************************/  
5845
5846 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
5847                 const POLICY_HND *hnd,
5848                 uint32 idx, uint32 valuelen, uint32 datalen)
5849 {
5850         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5851         q_u->index=idx;
5852         q_u->valuesize=valuelen;
5853         q_u->datasize=datalen;
5854
5855         return True;
5856 }
5857
5858 /*******************************************************************
5859 ********************************************************************/  
5860
5861 BOOL make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
5862                                       const POLICY_HND *hnd, const char *key,
5863                                       uint32 size)
5864 {
5865         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5866         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5867         q_u->size = size;
5868
5869         return True;
5870 }
5871
5872 /*******************************************************************
5873 ********************************************************************/  
5874 BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
5875                                    char* value, uint32 data_type, char* data, uint32 data_size)
5876 {
5877         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5878         q_u->type = data_type;
5879         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5880
5881         q_u->max_len = q_u->real_len = data_size;
5882         q_u->data = (unsigned char *)data;
5883         
5884         return True;
5885 }
5886
5887 /*******************************************************************
5888 ********************************************************************/  
5889 BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY_HND *hnd,
5890                                      char *key, char* value, uint32 data_type, char* data, 
5891                                      uint32 data_size)
5892 {
5893         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5894         q_u->type = data_type;
5895         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
5896         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
5897
5898         q_u->max_len = q_u->real_len = data_size;
5899         q_u->data = (unsigned char *)data;
5900         
5901         return True;
5902 }
5903
5904 /*******************************************************************
5905 ********************************************************************/  
5906
5907 BOOL spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5908 {
5909         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5910         depth++;
5911
5912         if(!prs_align(ps))
5913                 return False;
5914         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5915                 return False;
5916         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5917                 return False;
5918
5919         if(!prs_align(ps))
5920                 return False;
5921
5922         if(!prs_uint32("type", ps, depth, &q_u->type))
5923                 return False;
5924
5925         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5926                 return False;
5927
5928         switch (q_u->type)
5929         {
5930                 case REG_SZ:
5931                 case REG_BINARY:
5932                 case REG_DWORD:
5933                 case REG_MULTI_SZ:
5934             if (q_u->max_len) {
5935                 if (UNMARSHALLING(ps))
5936                                 q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
5937                         if(q_u->data == NULL)
5938                                 return False;
5939                         if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
5940                                 return False;
5941             }
5942                         if(!prs_align(ps))
5943                                 return False;
5944                         break;
5945         }       
5946         
5947         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
5948                 return False;
5949
5950         return True;
5951 }
5952
5953 /*******************************************************************
5954 ********************************************************************/  
5955
5956 BOOL spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
5957 {
5958         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
5959         depth++;
5960
5961         if(!prs_align(ps))
5962                 return False;
5963         if(!prs_werror("status",     ps, depth, &r_u->status))
5964                 return False;
5965
5966         return True;
5967 }
5968
5969 /*******************************************************************
5970 ********************************************************************/  
5971 BOOL spoolss_io_q_resetprinter(const char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
5972 {
5973         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
5974         depth++;
5975
5976         if (!prs_align(ps))
5977                 return False;
5978         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5979                 return False;
5980
5981         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
5982                 return False;
5983                 
5984         if (q_u->datatype_ptr) {
5985                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
5986                 return False;
5987         }
5988
5989         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
5990                 return False;
5991
5992         return True;
5993 }
5994
5995
5996 /*******************************************************************
5997 ********************************************************************/  
5998 BOOL spoolss_io_r_resetprinter(const char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
5999 {
6000         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
6001         depth++;
6002
6003         if(!prs_align(ps))
6004                 return False;
6005         if(!prs_werror("status",     ps, depth, &r_u->status))
6006                 return False;
6007
6008         return True;
6009 }
6010
6011 /*******************************************************************
6012 ********************************************************************/  
6013
6014 static BOOL spoolss_io_addform(const char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
6015 {
6016         prs_debug(ps, depth, desc, "spoolss_io_addform");
6017         depth++;
6018         if(!prs_align(ps))
6019                 return False;
6020
6021         if (ptr!=0)
6022         {
6023                 if(!prs_uint32("flags",    ps, depth, &f->flags))
6024                         return False;
6025                 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
6026                         return False;
6027                 if(!prs_uint32("size_x",   ps, depth, &f->size_x))
6028                         return False;
6029                 if(!prs_uint32("size_y",   ps, depth, &f->size_y))
6030                         return False;
6031                 if(!prs_uint32("left",     ps, depth, &f->left))
6032                         return False;
6033                 if(!prs_uint32("top",      ps, depth, &f->top))
6034                         return False;
6035                 if(!prs_uint32("right",    ps, depth, &f->right))
6036                         return False;
6037                 if(!prs_uint32("bottom",   ps, depth, &f->bottom))
6038                         return False;
6039
6040                 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
6041                         return False;
6042         }
6043
6044         return True;
6045 }
6046
6047 /*******************************************************************
6048 ********************************************************************/  
6049
6050 BOOL spoolss_io_q_deleteform(const char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
6051 {
6052         prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
6053         depth++;
6054
6055         if(!prs_align(ps))
6056                 return False;
6057         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6058                 return False;
6059         if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
6060                 return False;
6061
6062         return True;
6063 }
6064
6065 /*******************************************************************
6066 ********************************************************************/  
6067
6068 BOOL spoolss_io_r_deleteform(const char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
6069 {
6070         prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
6071         depth++;
6072
6073         if(!prs_align(ps))
6074                 return False;
6075         if(!prs_werror("status",        ps, depth, &r_u->status))
6076                 return False;
6077
6078         return True;
6079 }
6080
6081 /*******************************************************************
6082 ********************************************************************/  
6083
6084 BOOL spoolss_io_q_addform(const char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
6085 {
6086         uint32 useless_ptr=1;
6087         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
6088         depth++;
6089
6090         if(!prs_align(ps))
6091                 return False;
6092         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6093                 return False;
6094         if(!prs_uint32("level",  ps, depth, &q_u->level))
6095                 return False;
6096         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6097                 return False;
6098
6099         if (q_u->level==1)
6100         {
6101                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6102                         return False;
6103                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6104                         return False;
6105         }
6106
6107         return True;
6108 }
6109
6110 /*******************************************************************
6111 ********************************************************************/  
6112
6113 BOOL spoolss_io_r_addform(const char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
6114 {
6115         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
6116         depth++;
6117
6118         if(!prs_align(ps))
6119                 return False;
6120         if(!prs_werror("status",        ps, depth, &r_u->status))
6121                 return False;
6122
6123         return True;
6124 }
6125
6126 /*******************************************************************
6127 ********************************************************************/  
6128
6129 BOOL spoolss_io_q_setform(const char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
6130 {
6131         uint32 useless_ptr=1;
6132         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
6133         depth++;
6134
6135         if(!prs_align(ps))
6136                 return False;
6137         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6138                 return False;
6139         if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
6140                 return False;
6141               
6142         if(!prs_align(ps))
6143                 return False;
6144         
6145         if(!prs_uint32("level",  ps, depth, &q_u->level))
6146                 return False;
6147         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6148                 return False;
6149
6150         if (q_u->level==1)
6151         {
6152                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6153                         return False;
6154                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6155                         return False;
6156         }
6157
6158         return True;
6159 }
6160
6161 /*******************************************************************
6162 ********************************************************************/  
6163
6164 BOOL spoolss_io_r_setform(const char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
6165 {
6166         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
6167         depth++;
6168
6169         if(!prs_align(ps))
6170                 return False;
6171         if(!prs_werror("status",        ps, depth, &r_u->status))
6172                 return False;
6173
6174         return True;
6175 }
6176
6177 /*******************************************************************
6178  Parse a SPOOL_R_GETJOB structure.
6179 ********************************************************************/  
6180
6181 BOOL spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
6182 {               
6183         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
6184         depth++;
6185
6186         if (!prs_align(ps))
6187                 return False;
6188                 
6189         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
6190                 return False;
6191
6192         if (!prs_align(ps))
6193                 return False;
6194                 
6195         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6196                 return False;
6197                 
6198         if (!prs_werror("status", ps, depth, &r_u->status))
6199                 return False;
6200
6201         return True;            
6202 }
6203
6204 /*******************************************************************
6205  Parse a SPOOL_Q_GETJOB structure.
6206 ********************************************************************/  
6207
6208 BOOL spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
6209 {
6210         prs_debug(ps, depth, desc, "");
6211         depth++;
6212
6213         if(!prs_align(ps))
6214                 return False;
6215
6216         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6217                 return False;
6218         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
6219                 return False;
6220         if(!prs_uint32("level", ps, depth, &q_u->level))
6221                 return False;
6222         
6223         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
6224                 return False;
6225
6226         if(!prs_align(ps))
6227                 return False;
6228         
6229         if(!prs_uint32("offered", ps, depth, &q_u->offered))
6230                 return False;
6231
6232         return True;
6233 }
6234
6235 void free_devmode(DEVICEMODE *devmode)
6236 {
6237         if (devmode!=NULL) {
6238                 SAFE_FREE(devmode->dev_private);
6239                 SAFE_FREE(devmode);
6240         }
6241 }
6242
6243 void free_printer_info_1(PRINTER_INFO_1 *printer)
6244 {
6245         SAFE_FREE(printer);
6246 }
6247
6248 void free_printer_info_2(PRINTER_INFO_2 *printer)
6249 {
6250         if (printer!=NULL) {
6251                 free_devmode(printer->devmode);
6252                 printer->devmode = NULL;
6253                 SAFE_FREE(printer);
6254         }
6255 }
6256
6257 void free_printer_info_3(PRINTER_INFO_3 *printer)
6258 {
6259         SAFE_FREE(printer);
6260 }
6261
6262 void free_printer_info_4(PRINTER_INFO_4 *printer)
6263 {
6264         SAFE_FREE(printer);
6265 }
6266
6267 void free_printer_info_5(PRINTER_INFO_5 *printer)
6268 {
6269         SAFE_FREE(printer);
6270 }
6271
6272 void free_printer_info_7(PRINTER_INFO_7 *printer)
6273 {
6274         SAFE_FREE(printer);
6275 }
6276
6277 void free_job_info_2(JOB_INFO_2 *job)
6278 {
6279     if (job!=NULL)
6280         free_devmode(job->devmode);
6281 }
6282
6283 /*******************************************************************
6284  * init a structure.
6285  ********************************************************************/
6286
6287 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
6288                                const fstring string, uint32 printer, uint32 type)
6289 {      
6290         if (q_u == NULL)
6291                 return False;
6292
6293         init_unistr2(&q_u->string, string, UNI_STR_TERMINATE);
6294
6295         q_u->printer=printer;
6296         q_u->type=type;
6297
6298         q_u->unknown0=0x0;
6299         q_u->unknown1=0x0;
6300
6301         return True;
6302 }
6303
6304 /*******************************************************************
6305  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
6306 ********************************************************************/  
6307
6308 BOOL spoolss_io_q_replyopenprinter(const char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
6309 {
6310         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
6311         depth++;
6312
6313         if(!prs_align(ps))
6314                 return False;
6315
6316         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
6317                 return False;
6318
6319         if(!prs_align(ps))
6320                 return False;
6321
6322         if(!prs_uint32("printer", ps, depth, &q_u->printer))
6323                 return False;
6324         if(!prs_uint32("type", ps, depth, &q_u->type))
6325                 return False;
6326         
6327         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6328                 return False;
6329         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6330                 return False;
6331
6332         return True;
6333 }
6334
6335 /*******************************************************************
6336  Parse a SPOOL_R_REPLYOPENPRINTER structure.
6337 ********************************************************************/  
6338
6339 BOOL spoolss_io_r_replyopenprinter(const char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
6340 {               
6341         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
6342         depth++;
6343
6344         if (!prs_align(ps))
6345                 return False;
6346
6347         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6348                 return False;
6349
6350         if (!prs_werror("status", ps, depth, &r_u->status))
6351                 return False;
6352
6353         return True;            
6354 }
6355
6356 /*******************************************************************
6357  * init a structure.
6358  ********************************************************************/
6359 BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd, 
6360                                         uint32 condition, uint32 change_id)
6361 {
6362
6363         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6364
6365         q_u->condition = condition;
6366         q_u->change_id = change_id;
6367
6368         /* magic values */
6369         q_u->unknown1 = 0x1;
6370         memset(q_u->unknown2, 0x0, 5);
6371         q_u->unknown2[0] = 0x1;
6372
6373         return True;
6374 }
6375
6376 /*******************************************************************
6377  Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
6378 ********************************************************************/
6379 BOOL spoolss_io_q_routerreplyprinter (const char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
6380 {
6381
6382         prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
6383         depth++;
6384
6385         if (!prs_align(ps))
6386                 return False;
6387
6388         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6389                 return False;
6390
6391         if (!prs_uint32("condition", ps, depth, &q_u->condition))
6392                 return False;
6393
6394         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6395                 return False;
6396
6397         if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
6398                 return False;
6399
6400         if (!prs_uint8s(False, "dev_private",  ps, depth, q_u->unknown2, 5))
6401                 return False;
6402
6403         return True;
6404 }
6405
6406 /*******************************************************************
6407  Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
6408 ********************************************************************/
6409 BOOL spoolss_io_r_routerreplyprinter (const char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
6410 {
6411         prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
6412         depth++;
6413
6414         if (!prs_align(ps))
6415                 return False;
6416
6417         if (!prs_werror("status", ps, depth, &r_u->status))
6418                 return False;
6419
6420         return True;
6421 }
6422
6423 /*******************************************************************
6424  * init a structure.
6425  ********************************************************************/
6426
6427 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
6428 {      
6429         if (q_u == NULL)
6430                 return False;
6431
6432         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6433
6434         return True;
6435 }
6436
6437 /*******************************************************************
6438  Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
6439 ********************************************************************/  
6440
6441 BOOL spoolss_io_q_replycloseprinter(const char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
6442 {
6443         prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
6444         depth++;
6445
6446         if(!prs_align(ps))
6447                 return False;
6448
6449         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6450                 return False;
6451
6452         return True;
6453 }
6454
6455 /*******************************************************************
6456  Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6457 ********************************************************************/  
6458
6459 BOOL spoolss_io_r_replycloseprinter(const char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6460 {               
6461         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6462         depth++;
6463
6464         if (!prs_align(ps))
6465                 return False;
6466
6467         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6468                 return False;
6469
6470         if (!prs_werror("status", ps, depth, &r_u->status))
6471                 return False;
6472
6473         return True;            
6474 }
6475
6476 #if 0   /* JERRY - not currently used but could be :-) */
6477
6478 /*******************************************************************
6479  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
6480  ******************************************************************/
6481 static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
6482                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
6483 {
6484         int i;
6485
6486         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
6487         
6488         for (i=0; i<n; i++) {
6489                 int len;
6490                 uint16 *s = NULL;
6491                 
6492                 if (src->size != POINTER) 
6493                         continue;
6494                 len = src->notify_data.data.length;
6495                 s = SMB_MALLOC_ARRAY(uint16, len);
6496                 if (s == NULL) {
6497                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
6498                         return False;
6499                 }
6500                 
6501                 memcpy(s, src->notify_data.data.string, len*2);
6502                 dst->notify_data.data.string = s;
6503         }
6504         
6505         return True;
6506 }
6507
6508 /*******************************************************************
6509  Deep copy a SPOOL_NOTIFY_INFO structure
6510  ******************************************************************/
6511 static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
6512 {
6513         if (!dst) {
6514                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
6515                 return False;
6516         }
6517                 
6518         dst->version = src->version;
6519         dst->flags   = src->flags;
6520         dst->count   = src->count;
6521         
6522         if (dst->count) 
6523         {
6524                 dst->data = SMB_MALLOC_ARRAY(SPOOL_NOTIFY_INFO_DATA, dst->count);
6525                 
6526                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
6527                         dst->count));
6528
6529                 if (dst->data == NULL) {
6530                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
6531                                 dst->count));
6532                         return False;
6533                 }
6534                 
6535                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
6536         }
6537         
6538         return True;
6539 }
6540 #endif  /* JERRY */
6541
6542 /*******************************************************************
6543  * init a structure.
6544  ********************************************************************/
6545
6546 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6547                                 uint32 change_low, uint32 change_high,
6548                                 SPOOL_NOTIFY_INFO *info)
6549 {      
6550         if (q_u == NULL)
6551                 return False;
6552
6553         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6554
6555         q_u->change_low=change_low;
6556         q_u->change_high=change_high;
6557
6558         q_u->unknown0=0x0;
6559         q_u->unknown1=0x0;
6560
6561         q_u->info_ptr=0x0FF0ADDE;
6562
6563         q_u->info.version=2;
6564         
6565         if (info->count) {
6566                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
6567                         info->count));
6568                 q_u->info.version = info->version;
6569                 q_u->info.flags   = info->flags;
6570                 q_u->info.count   = info->count;
6571                 /* pointer field - be careful! */
6572                 q_u->info.data    = info->data;
6573         }
6574         else  {
6575         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6576         q_u->info.count=0;
6577         }
6578
6579         return True;
6580 }
6581
6582 /*******************************************************************
6583  Parse a SPOOL_Q_REPLY_RRPCN structure.
6584 ********************************************************************/  
6585
6586 BOOL spoolss_io_q_reply_rrpcn(const char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6587 {
6588         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6589         depth++;
6590
6591         if(!prs_align(ps))
6592                 return False;
6593
6594         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6595                 return False;
6596
6597         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6598                 return False;
6599
6600         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6601                 return False;
6602
6603         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6604                 return False;
6605
6606         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6607                 return False;
6608
6609         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6610                 return False;
6611
6612         if(q_u->info_ptr!=0)
6613                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6614                         return False;
6615                 
6616         return True;
6617 }
6618
6619 /*******************************************************************
6620  Parse a SPOOL_R_REPLY_RRPCN structure.
6621 ********************************************************************/  
6622
6623 BOOL spoolss_io_r_reply_rrpcn(const char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6624 {               
6625         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
6626         depth++;
6627
6628         if (!prs_align(ps))
6629                 return False;
6630
6631         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6632                 return False;
6633
6634         if (!prs_werror("status", ps, depth, &r_u->status))
6635                 return False;
6636
6637         return True;            
6638 }
6639
6640 /*******************************************************************
6641  * read a structure.
6642  * called from spoolss_q_getprinterdataex (srv_spoolss.c)
6643  ********************************************************************/
6644
6645 BOOL spoolss_io_q_getprinterdataex(const char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6646 {
6647         if (q_u == NULL)
6648                 return False;
6649
6650         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
6651         depth++;
6652
6653         if (!prs_align(ps))
6654                 return False;
6655         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6656                 return False;
6657         if (!prs_align(ps))
6658                 return False;
6659         if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
6660                 return False;
6661         if (!prs_align(ps))
6662                 return False;
6663         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
6664                 return False;
6665         if (!prs_align(ps))
6666                 return False;
6667         if (!prs_uint32("size", ps, depth, &q_u->size))
6668                 return False;
6669
6670         return True;
6671 }
6672
6673 /*******************************************************************
6674  * write a structure.
6675  * called from spoolss_r_getprinterdataex (srv_spoolss.c)
6676  ********************************************************************/
6677
6678 BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6679 {
6680         if (r_u == NULL)
6681                 return False;
6682
6683         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
6684         depth++;
6685
6686         if (!prs_align(ps))
6687                 return False;
6688         if (!prs_uint32("type", ps, depth, &r_u->type))
6689                 return False;
6690         if (!prs_uint32("size", ps, depth, &r_u->size))
6691                 return False;
6692         
6693         if (UNMARSHALLING(ps) && r_u->size) {
6694                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
6695                 if(!r_u->data)
6696                         return False;
6697         }
6698
6699         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
6700                 return False;
6701                 
6702         if (!prs_align(ps))
6703                 return False;
6704         
6705         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6706                 return False;
6707         if (!prs_werror("status", ps, depth, &r_u->status))
6708                 return False;
6709                 
6710         return True;
6711 }
6712
6713 /*******************************************************************
6714  * read a structure.
6715  ********************************************************************/  
6716
6717 BOOL spoolss_io_q_setprinterdataex(const char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6718 {
6719         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
6720         depth++;
6721
6722         if(!prs_align(ps))
6723                 return False;
6724         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6725                 return False;
6726         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6727                 return False;
6728
6729         if(!prs_align(ps))
6730                 return False;
6731
6732         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
6733                 return False;
6734
6735         if(!prs_align(ps))
6736                 return False;
6737
6738         if(!prs_uint32("type", ps, depth, &q_u->type))
6739                 return False;
6740
6741         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6742                 return False;
6743
6744         switch (q_u->type)
6745         {
6746                 case 0x1:
6747                 case 0x3:
6748                 case 0x4:
6749                 case 0x7:
6750                         if (q_u->max_len) {
6751                                 if (UNMARSHALLING(ps))
6752                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
6753                                 if(q_u->data == NULL)
6754                                         return False;
6755                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6756                                         return False;
6757                         }
6758                         if(!prs_align(ps))
6759                                 return False;
6760                         break;
6761         }       
6762         
6763         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6764                 return False;
6765
6766         return True;
6767 }
6768
6769 /*******************************************************************
6770  * write a structure.
6771  ********************************************************************/  
6772
6773 BOOL spoolss_io_r_setprinterdataex(const char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6774 {
6775         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
6776         depth++;
6777
6778         if(!prs_align(ps))
6779                 return False;
6780         if(!prs_werror("status",     ps, depth, &r_u->status))
6781                 return False;
6782
6783         return True;
6784 }
6785
6786 /*******************************************************************
6787  * read a structure.
6788  ********************************************************************/  
6789 BOOL make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
6790                                    POLICY_HND *hnd, const char *key, 
6791                                    uint32 size)
6792 {
6793         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
6794
6795         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6796         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
6797         q_u->size = size;
6798
6799         return True;
6800 }
6801
6802 /*******************************************************************
6803  * read a structure.
6804  ********************************************************************/  
6805
6806 BOOL spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
6807 {
6808         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
6809         depth++;
6810
6811         if(!prs_align(ps))
6812                 return False;
6813         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6814                 return False;
6815                 
6816         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6817                 return False;
6818
6819         if(!prs_align(ps))
6820                 return False;
6821         
6822         if(!prs_uint32("size", ps, depth, &q_u->size))
6823                 return False;
6824
6825         return True;
6826 }
6827
6828 /*******************************************************************
6829  * write a structure.
6830  ********************************************************************/  
6831
6832 BOOL spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
6833 {
6834         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
6835         depth++;
6836
6837         if(!prs_align(ps))
6838                 return False;
6839
6840         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
6841                 return False;
6842         
6843         if(!prs_align(ps))
6844                 return False;
6845
6846         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6847                 return False;
6848
6849         if(!prs_werror("status",     ps, depth, &r_u->status))
6850                 return False;
6851
6852         return True;
6853 }
6854
6855 /*******************************************************************
6856  * read a structure.
6857  ********************************************************************/  
6858
6859 BOOL make_spoolss_q_deleteprinterkey(SPOOL_Q_DELETEPRINTERKEY *q_u, 
6860                                      POLICY_HND *hnd, char *keyname)
6861 {
6862         DEBUG(5,("make_spoolss_q_deleteprinterkey\n"));
6863
6864         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6865         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
6866
6867         return True;
6868 }
6869
6870 /*******************************************************************
6871  * read a structure.
6872  ********************************************************************/  
6873
6874 BOOL spoolss_io_q_deleteprinterkey(const char *desc, SPOOL_Q_DELETEPRINTERKEY *q_u, prs_struct *ps, int depth)
6875 {
6876         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterkey");
6877         depth++;
6878
6879         if(!prs_align(ps))
6880                 return False;
6881         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6882                 return False;
6883                 
6884         if(!smb_io_unistr2("", &q_u->keyname, True, ps, depth))
6885                 return False;
6886
6887         return True;
6888 }
6889
6890 /*******************************************************************
6891  * write a structure.
6892  ********************************************************************/  
6893
6894 BOOL spoolss_io_r_deleteprinterkey(const char *desc, SPOOL_R_DELETEPRINTERKEY *r_u, prs_struct *ps, int depth)
6895 {
6896         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterkey");
6897         depth++;
6898
6899         if(!prs_align(ps))
6900                 return False;
6901                 
6902         if(!prs_werror("status",     ps, depth, &r_u->status))
6903                 return False;
6904
6905         return True;
6906 }
6907
6908
6909 /*******************************************************************
6910  * read a structure.
6911  ********************************************************************/  
6912
6913 BOOL spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6914 {
6915         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
6916         depth++;
6917
6918         if(!prs_align(ps))
6919                 return False;
6920         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6921                 return False;
6922                 
6923         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6924                 return False;
6925
6926         if(!prs_align(ps))
6927                 return False;
6928         
6929         if(!prs_uint32("size", ps, depth, &q_u->size))
6930                 return False;
6931
6932         return True;
6933 }
6934
6935 /*******************************************************************
6936 ********************************************************************/  
6937
6938 static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
6939                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
6940 {
6941         int     i;
6942         uint32  valuename_offset,
6943                 data_offset,
6944                 current_offset;
6945         const uint32 basic_unit = 20; /* size of static portion of enum_values */
6946         
6947         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
6948         depth++;        
6949         
6950         /* 
6951          * offset data begins at 20 bytes per structure * size_of_array.
6952          * Don't forget the uint32 at the beginning 
6953          * */
6954         
6955         current_offset = basic_unit * ctr->size_of_array;
6956         
6957         /* first loop to write basic enum_value information */
6958         
6959         if (UNMARSHALLING(ps)) {
6960                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
6961                 if (!ctr->values)
6962                         return False;
6963         }
6964
6965         for (i=0; i<ctr->size_of_array; i++) {
6966                 valuename_offset = current_offset;
6967                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
6968                         return False;
6969
6970                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
6971                         return False;
6972         
6973                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
6974                         return False;
6975         
6976                 data_offset = ctr->values[i].value_len + valuename_offset;
6977                 
6978                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
6979                         return False;
6980
6981                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
6982                         return False;
6983                         
6984                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
6985                 /* account for 2 byte alignment */
6986                 current_offset += (current_offset % 2);
6987         }
6988
6989         /* 
6990          * loop #2 for writing the dynamically size objects; pay 
6991          * attention to 2-byte alignment here....
6992          */
6993         
6994         for (i=0; i<ctr->size_of_array; i++) {
6995         
6996                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
6997                         return False;
6998                 
6999                 if ( ctr->values[i].data_len ) {
7000                         if ( UNMARSHALLING(ps) ) {
7001                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
7002                                 if (!ctr->values[i].data)
7003                                         return False;
7004                         }
7005                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
7006                                 return False;
7007                 }
7008                         
7009                 if ( !prs_align_uint16(ps) )
7010                         return False;
7011         }
7012
7013         return True;    
7014 }
7015
7016 /*******************************************************************
7017  * write a structure.
7018  ********************************************************************/  
7019
7020 BOOL spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
7021 {
7022         uint32 data_offset, end_offset;
7023         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
7024         depth++;
7025
7026         if(!prs_align(ps))
7027                 return False;
7028
7029         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
7030                 return False;
7031
7032         data_offset = prs_offset(ps);
7033
7034         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
7035                 return False;
7036
7037         if(!prs_align(ps))
7038                 return False;
7039
7040         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7041                 return False;
7042
7043         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
7044                 return False;
7045
7046         if(!prs_werror("status",     ps, depth, &r_u->status))
7047                 return False;
7048
7049         r_u->ctr.size_of_array = r_u->returned;
7050
7051         end_offset = prs_offset(ps);
7052
7053         if (!prs_set_offset(ps, data_offset))
7054                 return False;
7055
7056         if (r_u->ctr.size)
7057                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
7058                         return False;
7059
7060         if (!prs_set_offset(ps, end_offset))
7061                 return False;
7062         return True;
7063 }
7064
7065 /*******************************************************************
7066  * write a structure.
7067  ********************************************************************/  
7068
7069 /* 
7070    uint32 GetPrintProcessorDirectory(
7071        [in] unistr2 *name,
7072        [in] unistr2 *environment,
7073        [in] uint32 level,
7074        [in,out] RPC_BUFFER buffer,
7075        [in] uint32 offered,
7076        [out] uint32 needed,
7077        [out] uint32 returned
7078    );
7079
7080 */
7081
7082 BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, RPC_BUFFER *buffer, uint32 offered)
7083 {
7084         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
7085
7086         init_unistr2(&q_u->name, name, UNI_STR_TERMINATE);
7087         init_unistr2(&q_u->environment, environment, UNI_STR_TERMINATE);
7088
7089         q_u->level = level;
7090
7091         q_u->buffer = buffer;
7092         q_u->offered = offered;
7093
7094         return True;
7095 }
7096
7097 BOOL spoolss_io_q_getprintprocessordirectory(const char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
7098 {
7099         uint32 ptr;
7100
7101         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
7102         depth++;
7103
7104         if(!prs_align(ps))
7105                 return False;   
7106
7107         if (!prs_uint32("ptr", ps, depth, &ptr)) 
7108                 return False;
7109
7110         if (ptr) {
7111                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
7112                         return False;
7113         }
7114
7115         if (!prs_align(ps))
7116                 return False;
7117
7118         if (!prs_uint32("ptr", ps, depth, &ptr))
7119                 return False;
7120
7121         if (ptr) {
7122                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
7123                                    ps, depth))
7124                         return False;
7125         }
7126
7127         if (!prs_align(ps))
7128                 return False;
7129
7130         if(!prs_uint32("level",   ps, depth, &q_u->level))
7131                 return False;
7132
7133         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
7134                 return False;
7135         
7136         if(!prs_align(ps))
7137                 return False;
7138
7139         if(!prs_uint32("offered", ps, depth, &q_u->offered))
7140                 return False;
7141
7142         return True;
7143 }
7144
7145 /*******************************************************************
7146  * write a structure.
7147  ********************************************************************/  
7148
7149 BOOL spoolss_io_r_getprintprocessordirectory(const char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
7150 {
7151         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
7152         depth++;
7153
7154         if(!prs_align(ps))
7155                 return False;
7156
7157         if(!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
7158                 return False;
7159         
7160         if(!prs_align(ps))
7161                 return False;
7162
7163         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
7164                 return False;
7165                 
7166         if(!prs_werror("status",     ps, depth, &r_u->status))
7167                 return False;
7168
7169         return True;
7170 }
7171
7172 BOOL smb_io_printprocessordirectory_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
7173 {
7174         prs_struct *ps=&buffer->prs;
7175
7176         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
7177         depth++;
7178
7179         buffer->struct_start=prs_offset(ps);
7180
7181         if (!smb_io_unistr(desc, &info->name, ps, depth))
7182                 return False;
7183
7184         return True;
7185 }
7186
7187 /*******************************************************************
7188  * init a structure.
7189  ********************************************************************/
7190
7191 BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle, 
7192                             int level, FORM *form)
7193 {
7194         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7195         q_u->level = level;
7196         q_u->level2 = level;
7197         memcpy(&q_u->form, form, sizeof(FORM));
7198
7199         return True;
7200 }
7201
7202 /*******************************************************************
7203  * init a structure.
7204  ********************************************************************/
7205
7206 BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle, 
7207                             int level, const char *form_name, FORM *form)
7208 {
7209         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7210         q_u->level = level;
7211         q_u->level2 = level;
7212         memcpy(&q_u->form, form, sizeof(FORM));
7213         init_unistr2(&q_u->name, form_name, UNI_STR_TERMINATE);
7214
7215         return True;
7216 }
7217
7218 /*******************************************************************
7219  * init a structure.
7220  ********************************************************************/
7221
7222 BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, 
7223                                const char *form)
7224 {
7225         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7226         init_unistr2(&q_u->name, form, UNI_STR_TERMINATE);
7227         return True;
7228 }
7229
7230 /*******************************************************************
7231  * init a structure.
7232  ********************************************************************/
7233
7234 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, 
7235                             const char *formname, uint32 level, 
7236                             RPC_BUFFER *buffer, uint32 offered)
7237 {
7238         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7239         q_u->level = level;
7240         init_unistr2(&q_u->formname, formname, UNI_STR_TERMINATE);
7241         q_u->buffer=buffer;
7242         q_u->offered=offered;
7243
7244         return True;
7245 }
7246
7247 /*******************************************************************
7248  * init a structure.
7249  ********************************************************************/
7250
7251 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
7252                               uint32 level, RPC_BUFFER *buffer,
7253                               uint32 offered)
7254 {
7255         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7256         q_u->level = level;
7257         q_u->buffer=buffer;
7258         q_u->offered=offered;
7259
7260         return True;
7261 }
7262
7263 /*******************************************************************
7264  * init a structure.
7265  ********************************************************************/
7266
7267 BOOL make_spoolss_q_setjob(SPOOL_Q_SETJOB *q_u, POLICY_HND *handle, 
7268                            uint32 jobid, uint32 level, uint32 command)
7269 {
7270         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7271         q_u->jobid = jobid;
7272         q_u->level = level;
7273
7274         /* Hmm - the SPOOL_Q_SETJOB structure has a JOB_INFO ctr in it but
7275            the server side code has it marked as unused. */
7276
7277         q_u->command = command;
7278
7279         return True;
7280 }
7281
7282 /*******************************************************************
7283  * init a structure.
7284  ********************************************************************/
7285
7286 BOOL make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
7287                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
7288                            uint32 offered)
7289 {
7290         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7291         q_u->jobid = jobid;
7292         q_u->level = level;
7293         q_u->buffer = buffer;
7294         q_u->offered = offered;
7295
7296         return True;
7297 }
7298
7299 /*******************************************************************
7300  * init a structure.
7301  ********************************************************************/
7302
7303 BOOL make_spoolss_q_startpageprinter(SPOOL_Q_STARTPAGEPRINTER *q_u, 
7304                                      POLICY_HND *handle)
7305 {
7306         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7307
7308         return True;
7309 }
7310
7311 /*******************************************************************
7312  * init a structure.
7313  ********************************************************************/
7314
7315 BOOL make_spoolss_q_endpageprinter(SPOOL_Q_ENDPAGEPRINTER *q_u, 
7316                                    POLICY_HND *handle)
7317 {
7318         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7319
7320         return True;
7321 }
7322
7323 /*******************************************************************
7324  * init a structure.
7325  ********************************************************************/
7326
7327 BOOL make_spoolss_q_startdocprinter(SPOOL_Q_STARTDOCPRINTER *q_u, 
7328                                     POLICY_HND *handle, uint32 level,
7329                                     char *docname, char *outputfile,
7330                                     char *datatype)
7331 {
7332         DOC_INFO_CONTAINER *ctr = &q_u->doc_info_container;
7333
7334         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7335
7336         ctr->level = level;
7337
7338         switch (level) {
7339         case 1:
7340                 ctr->docinfo.switch_value = level;
7341
7342                 ctr->docinfo.doc_info_1.p_docname = docname ? 1 : 0;
7343                 ctr->docinfo.doc_info_1.p_outputfile = outputfile ? 1 : 0;
7344                 ctr->docinfo.doc_info_1.p_datatype = datatype ? 1 : 0;
7345
7346                 init_unistr2(&ctr->docinfo.doc_info_1.docname, docname, UNI_STR_TERMINATE);
7347                 init_unistr2(&ctr->docinfo.doc_info_1.outputfile, outputfile, UNI_STR_TERMINATE);
7348                 init_unistr2(&ctr->docinfo.doc_info_1.datatype, datatype, UNI_STR_TERMINATE);
7349
7350                 break;
7351         case 2:
7352                 /* DOC_INFO_2 is only used by Windows 9x and since it
7353                    doesn't do printing over RPC we don't have to worry
7354                    about it. */
7355         default:
7356                 DEBUG(3, ("unsupported info level %d\n", level));
7357                 return False;
7358         }
7359
7360         return True;
7361 }
7362
7363 /*******************************************************************
7364  * init a structure.
7365  ********************************************************************/
7366
7367 BOOL make_spoolss_q_enddocprinter(SPOOL_Q_ENDDOCPRINTER *q_u, 
7368                                   POLICY_HND *handle)
7369 {
7370         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7371
7372         return True;
7373 }
7374
7375 /*******************************************************************
7376  * init a structure.
7377  ********************************************************************/
7378
7379 BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u, 
7380                                  POLICY_HND *handle, uint32 data_size,
7381                                  char *data)
7382 {
7383         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7384         q_u->buffer_size = q_u->buffer_size2 = data_size;
7385         q_u->buffer = (unsigned char *)data;
7386         return True;
7387 }
7388
7389 /*******************************************************************
7390  * init a structure.
7391  ********************************************************************/
7392
7393 BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u, 
7394                                  POLICY_HND *handle, char *valuename)
7395 {
7396         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7397         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
7398
7399         return True;
7400 }
7401
7402 /*******************************************************************
7403  * init a structure.
7404  ********************************************************************/
7405
7406 BOOL make_spoolss_q_deleteprinterdataex(SPOOL_Q_DELETEPRINTERDATAEX *q_u, 
7407                                         POLICY_HND *handle, char *key,
7408                                         char *value)
7409 {
7410         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7411         init_unistr2(&q_u->valuename, value, UNI_STR_TERMINATE);
7412         init_unistr2(&q_u->keyname, key, UNI_STR_TERMINATE);
7413
7414         return True;
7415 }
7416
7417 /*******************************************************************
7418  * init a structure.
7419  ********************************************************************/
7420
7421 BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
7422                              uint32 flags, uint32 options, const char *localmachine,
7423                              uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
7424 {
7425         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7426
7427         q_u->flags = flags;
7428         q_u->options = options;
7429
7430         q_u->localmachine_ptr = 1;
7431
7432         init_unistr2(&q_u->localmachine, localmachine, UNI_STR_TERMINATE);
7433
7434         q_u->printerlocal = printerlocal;
7435
7436         if (option)
7437                 q_u->option_ptr = 1;
7438
7439         q_u->option = option;
7440
7441         return True;
7442 }
7443
7444
7445 /*******************************************************************
7446  ********************************************************************/  
7447
7448 BOOL spoolss_io_q_xcvdataport(const char *desc, SPOOL_Q_XCVDATAPORT *q_u, prs_struct *ps, int depth)
7449 {
7450         prs_debug(ps, depth, desc, "spoolss_io_q_xcvdataport");
7451         depth++;
7452
7453         if(!prs_align(ps))
7454                 return False;   
7455
7456         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
7457                 return False;
7458                 
7459         if(!smb_io_unistr2("", &q_u->dataname, True, ps, depth))
7460                 return False;
7461
7462         if (!prs_align(ps))
7463                 return False;
7464
7465         if(!prs_rpcbuffer("", ps, depth, &q_u->indata))
7466                 return False;
7467                 
7468         if (!prs_align(ps))
7469                 return False;
7470
7471         if (!prs_uint32("indata_len", ps, depth, &q_u->indata_len))
7472                 return False;
7473         if (!prs_uint32("offered", ps, depth, &q_u->offered))
7474                 return False;
7475         if (!prs_uint32("unknown", ps, depth, &q_u->unknown))
7476                 return False;
7477         
7478         return True;
7479 }
7480
7481 /*******************************************************************
7482  ********************************************************************/  
7483
7484 BOOL spoolss_io_r_xcvdataport(const char *desc, SPOOL_R_XCVDATAPORT *r_u, prs_struct *ps, int depth)
7485 {
7486         prs_debug(ps, depth, desc, "spoolss_io_r_xcvdataport");
7487         depth++;
7488
7489         if(!prs_align(ps))
7490                 return False;
7491         if(!prs_rpcbuffer("", ps, depth, &r_u->outdata))
7492                 return False;
7493                 
7494         if (!prs_align(ps))
7495                 return False;
7496
7497         if (!prs_uint32("needed", ps, depth, &r_u->needed))
7498                 return False;
7499         if (!prs_uint32("unknown", ps, depth, &r_u->unknown))
7500                 return False;
7501
7502         if(!prs_werror("status", ps, depth, &r_u->status))
7503                 return False;
7504
7505         return True;
7506 }
7507
7508 /*******************************************************************
7509  ********************************************************************/  
7510
7511 BOOL make_monitorui_buf( RPC_BUFFER *buf, const char *dllname )
7512 {
7513         UNISTR string;
7514         
7515         if ( !buf )
7516                 return False;
7517
7518         init_unistr( &string, dllname );
7519
7520         if ( !prs_unistr( "ui_dll", &buf->prs, 0, &string ) )
7521                 return False;
7522
7523         return True;
7524 }
7525
7526 /*******************************************************************
7527  ********************************************************************/  
7528  
7529 #define PORT_DATA_1_PAD    540
7530
7531 static BOOL smb_io_port_data_1( const char *desc, RPC_BUFFER *buf, int depth, SPOOL_PORT_DATA_1 *p1 )
7532 {
7533         prs_struct *ps = &buf->prs;
7534         uint8 padding[PORT_DATA_1_PAD];
7535
7536         prs_debug(ps, depth, desc, "smb_io_port_data_1");
7537         depth++;
7538
7539         if(!prs_align(ps))
7540                 return False;   
7541
7542         if( !prs_uint16s(True, "portname", ps, depth, p1->portname, MAX_PORTNAME))
7543                 return False;
7544
7545         if (!prs_uint32("version", ps, depth, &p1->version))
7546                 return False;
7547         if (!prs_uint32("protocol", ps, depth, &p1->protocol))
7548                 return False;
7549         if (!prs_uint32("size", ps, depth, &p1->size))
7550                 return False;
7551         if (!prs_uint32("reserved", ps, depth, &p1->reserved))
7552                 return False;
7553
7554         if( !prs_uint16s(True, "hostaddress", ps, depth, p1->hostaddress, MAX_NETWORK_NAME))
7555                 return False;
7556         if( !prs_uint16s(True, "snmpcommunity", ps, depth, p1->snmpcommunity, MAX_SNMP_COMM_NAME))
7557                 return False;
7558
7559         if (!prs_uint32("dblspool", ps, depth, &p1->dblspool))
7560                 return False;
7561                 
7562         if( !prs_uint16s(True, "queue", ps, depth, p1->queue, MAX_QUEUE_NAME))
7563                 return False;
7564         if( !prs_uint16s(True, "ipaddress", ps, depth, p1->ipaddress, MAX_IPADDR_STRING))
7565                 return False;
7566
7567         if( !prs_uint8s(False, "", ps, depth, padding, PORT_DATA_1_PAD))
7568                 return False;
7569                 
7570         if (!prs_uint32("port", ps, depth, &p1->port))
7571                 return False;
7572         if (!prs_uint32("snmpenabled", ps, depth, &p1->snmpenabled))
7573                 return False;
7574         if (!prs_uint32("snmpdevindex", ps, depth, &p1->snmpdevindex))
7575                 return False;
7576                 
7577         return True;
7578 }
7579
7580 /*******************************************************************
7581  ********************************************************************/  
7582
7583 BOOL convert_port_data_1( NT_PORT_DATA_1 *port1, RPC_BUFFER *buf ) 
7584 {
7585         SPOOL_PORT_DATA_1 spdata_1;
7586         
7587         ZERO_STRUCT( spdata_1 );
7588         
7589         if ( !smb_io_port_data_1( "port_data_1", buf, 0, &spdata_1 ) )
7590                 return False;
7591                 
7592         rpcstr_pull(port1->name, spdata_1.portname, sizeof(port1->name), -1, 0);
7593         rpcstr_pull(port1->queue, spdata_1.queue, sizeof(port1->queue), -1, 0);
7594         rpcstr_pull(port1->hostaddr, spdata_1.hostaddress, sizeof(port1->hostaddr), -1, 0);
7595         
7596         port1->port = spdata_1.port;
7597         
7598         switch ( spdata_1.protocol ) {
7599         case 1:
7600                 port1->protocol = PORT_PROTOCOL_DIRECT;
7601                 break;
7602         case 2:
7603                 port1->protocol = PORT_PROTOCOL_LPR;
7604                 break;
7605         default:
7606                 DEBUG(3,("convert_port_data_1: unknown protocol [%d]!\n", 
7607                         spdata_1.protocol));
7608                 return False;
7609         }
7610
7611         return True;
7612 }
7613