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