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