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