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