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