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