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