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