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