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