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