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