the next stage in the NTSTATUS/WERROR change. smbd and nmbd now compile, but the...
[kai/samba.git] / source3 / 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 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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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_werror("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                                 uint16 *tc2;
1865                         
1866                                 realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
1867
1868                                 /* Yes this should be realloc - it's freed below. JRA */
1869
1870                                 if((tc2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL) {
1871                                         if (chaine2) free(chaine2);
1872                                         return False;
1873                                 }
1874                                 else chaine2 = tc2;
1875                                 memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
1876                                 l_chaine2+=l_chaine+1;
1877                         }
1878                 
1879                 } while(l_chaine!=0);
1880                 
1881                 /* the end should be bould NULL terminated so add 
1882                    the second one here */
1883                 if (chaine2)
1884                 {
1885                         chaine2[l_chaine2] = '\0';
1886                         *string=(uint16 *)talloc_memdup(prs_get_mem_context(ps),chaine2,realloc_size);
1887                         free(chaine2);
1888                 }
1889
1890                 if(!prs_set_offset(ps, old_offset))
1891                         return False;
1892         }
1893         return True;
1894 }
1895
1896 /*******************************************************************
1897  Parse a DEVMODE structure and its relative pointer.
1898 ********************************************************************/
1899
1900 static BOOL smb_io_relsecdesc(char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc)
1901 {
1902         prs_struct *ps= &buffer->prs;
1903
1904         prs_debug(ps, depth, desc, "smb_io_relsecdesc");
1905         depth++;
1906
1907         if (MARSHALLING(ps)) {
1908                 uint32 struct_offset = prs_offset(ps);
1909                 uint32 relative_offset;
1910
1911                 if (! *secdesc) {
1912                         relative_offset = 0;
1913                         if (!prs_uint32("offset", ps, depth, &relative_offset))
1914                                 return False;
1915                         return True;
1916                 }
1917                 
1918                 if (*secdesc != NULL) {
1919                         buffer->string_at_end -= sec_desc_size(*secdesc);
1920
1921                         if(!prs_set_offset(ps, buffer->string_at_end))
1922                                 return False;
1923                         /* write the secdesc */
1924                         if (!sec_io_desc(desc, secdesc, ps, depth))
1925                                 return False;
1926
1927                         if(!prs_set_offset(ps, struct_offset))
1928                                 return False;
1929                 }
1930
1931                 relative_offset=buffer->string_at_end - buffer->struct_start;
1932                 /* write its offset */
1933
1934                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1935                         return False;
1936         } else {
1937                 uint32 old_offset;
1938                 
1939                 /* read the offset */
1940                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
1941                         return False;
1942
1943                 old_offset = prs_offset(ps);
1944                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
1945                         return False;
1946
1947                 /* read the sd */
1948                 if (!sec_io_desc(desc, secdesc, ps, depth))
1949                         return False;
1950
1951                 if(!prs_set_offset(ps, old_offset))
1952                         return False;
1953         }
1954         return True;
1955 }
1956
1957 /*******************************************************************
1958  Parse a DEVMODE structure and its relative pointer.
1959 ********************************************************************/
1960
1961 static BOOL smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
1962 {
1963         prs_struct *ps=&buffer->prs;
1964
1965         prs_debug(ps, depth, desc, "smb_io_reldevmode");
1966         depth++;
1967
1968         if (MARSHALLING(ps)) {
1969                 uint32 struct_offset = prs_offset(ps);
1970                 uint32 relative_offset;
1971                 
1972                 if (*devmode == NULL) {
1973                         relative_offset=0;
1974                         if (!prs_uint32("offset", ps, depth, &relative_offset))
1975                                 return False;
1976                         DEBUG(8, ("boing, the devmode was NULL\n"));
1977                         
1978                         return True;
1979                 }
1980                 
1981                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
1982                 
1983                 if(!prs_set_offset(ps, buffer->string_at_end))
1984                         return False;
1985                 
1986                 /* write the DEVMODE */
1987                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1988                         return False;
1989
1990                 if(!prs_set_offset(ps, struct_offset))
1991                         return False;
1992                 
1993                 relative_offset=buffer->string_at_end - buffer->struct_start;
1994                 /* write its offset */
1995                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1996                         return False;
1997         }
1998         else {
1999                 uint32 old_offset;
2000                 
2001                 /* read the offset */
2002                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2003                         return False;
2004
2005                 old_offset = prs_offset(ps);
2006                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2007                         return False;
2008
2009                 /* read the string */
2010                 if((*devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE))) == NULL)
2011                         return False;
2012                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2013                         return False;
2014
2015                 if(!prs_set_offset(ps, old_offset))
2016                         return False;
2017         }
2018         return True;
2019 }
2020
2021 /*******************************************************************
2022  Parse a PRINTER_INFO_0 structure.
2023 ********************************************************************/  
2024
2025 BOOL smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2026 {
2027         prs_struct *ps=&buffer->prs;
2028
2029         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2030         depth++;        
2031         
2032         buffer->struct_start=prs_offset(ps);
2033
2034         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2035                 return False;
2036         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2037                 return False;
2038         
2039         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2040                 return False;
2041         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2042                 return False;
2043         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2044                 return False;
2045
2046         if(!prs_uint16("year", ps, depth, &info->year))
2047                 return False;
2048         if(!prs_uint16("month", ps, depth, &info->month))
2049                 return False;
2050         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2051                 return False;
2052         if(!prs_uint16("day", ps, depth, &info->day))
2053                 return False;
2054         if(!prs_uint16("hour", ps, depth, &info->hour))
2055                 return False;
2056         if(!prs_uint16("minute", ps, depth, &info->minute))
2057                 return False;
2058         if(!prs_uint16("second", ps, depth, &info->second))
2059                 return False;
2060         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2061                 return False;
2062
2063         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2064                 return False;
2065         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2066                 return False;
2067
2068         if(!prs_uint16("major_version", ps, depth, &info->major_version))
2069                 return False;
2070         if(!prs_uint16("build_version", ps, depth, &info->build_version))
2071                 return False;
2072         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2073                 return False;
2074         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2075                 return False;
2076         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2077                 return False;
2078         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2079                 return False;
2080         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2081                 return False;
2082         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2083                 return False;
2084         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2085                 return False;
2086         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2087                 return False;
2088         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2089                 return False;
2090         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2091                 return False;
2092         if(!prs_uint32("change_id", ps, depth, &info->change_id))
2093                 return False;
2094         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2095                 return False;
2096         if(!prs_uint32("status"   , ps, depth, &info->status))
2097                 return False;
2098         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2099                 return False;
2100         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2101                 return False;
2102         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2103                 return False;
2104         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2105                 return False;
2106         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2107                 return False;
2108         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2109                 return False;
2110         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2111                 return False;
2112         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2113                 return False;
2114         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2115                 return False;
2116         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2117                 return False;
2118
2119         return True;
2120 }
2121
2122 /*******************************************************************
2123  Parse a PRINTER_INFO_1 structure.
2124 ********************************************************************/  
2125
2126 BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2127 {
2128         prs_struct *ps=&buffer->prs;
2129
2130         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2131         depth++;        
2132         
2133         buffer->struct_start=prs_offset(ps);
2134
2135         if (!prs_uint32("flags", ps, depth, &info->flags))
2136                 return False;
2137         if (!smb_io_relstr("description", buffer, depth, &info->description))
2138                 return False;
2139         if (!smb_io_relstr("name", buffer, depth, &info->name))
2140                 return False;
2141         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2142                 return False;   
2143
2144         return True;
2145 }
2146
2147 /*******************************************************************
2148  Parse a PRINTER_INFO_2 structure.
2149 ********************************************************************/  
2150
2151 BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2152 {
2153         prs_struct *ps=&buffer->prs;
2154
2155         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2156         depth++;        
2157         
2158         buffer->struct_start=prs_offset(ps);
2159         
2160         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2161                 return False;
2162         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2163                 return False;
2164         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2165                 return False;
2166         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2167                 return False;
2168         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2169                 return False;
2170         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2171                 return False;
2172         if (!smb_io_relstr("location", buffer, depth, &info->location))
2173                 return False;
2174
2175         /* NT parses the DEVMODE at the end of the struct */
2176         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2177                 return False;
2178         
2179         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2180                 return False;
2181         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2182                 return False;
2183         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2184                 return False;
2185         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2186                 return False;
2187
2188         if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2189                 return False;
2190
2191         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2192                 return False;
2193         if (!prs_uint32("priority", ps, depth, &info->priority))
2194                 return False;
2195         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2196                 return False;
2197         if (!prs_uint32("starttime", ps, depth, &info->starttime))
2198                 return False;
2199         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2200                 return False;
2201         if (!prs_uint32("status", ps, depth, &info->status))
2202                 return False;
2203         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2204                 return False;
2205         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2206                 return False;
2207
2208 #if 0 /* JFMTEST */
2209         if (!prs_uint32_post("secdesc_ptr", ps, depth, NULL, sec_offset, info->secdesc ? prs_offset(ps)-buffer->struct_start : 0 ))
2210                 return False;
2211
2212         if (!sec_io_desc("secdesc", &info->secdesc, ps, depth)) 
2213                 return False;
2214 #endif
2215         return True;
2216 }
2217
2218 /*******************************************************************
2219  Parse a PRINTER_INFO_3 structure.
2220 ********************************************************************/  
2221
2222 BOOL smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2223 {
2224         prs_struct *ps=&buffer->prs;
2225
2226         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2227         depth++;        
2228         
2229         buffer->struct_start=prs_offset(ps);
2230         
2231         if (!prs_uint32("flags", ps, depth, &info->flags))
2232                 return False;
2233         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2234                 return False;
2235
2236         return True;
2237 }
2238
2239 /*******************************************************************
2240  Parse a PORT_INFO_1 structure.
2241 ********************************************************************/  
2242
2243 BOOL smb_io_port_info_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2244 {
2245         prs_struct *ps=&buffer->prs;
2246
2247         prs_debug(ps, depth, desc, "smb_io_port_info_1");
2248         depth++;        
2249         
2250         buffer->struct_start=prs_offset(ps);
2251         
2252         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2253                 return False;
2254
2255         return True;
2256 }
2257
2258 /*******************************************************************
2259  Parse a PORT_INFO_2 structure.
2260 ********************************************************************/  
2261
2262 BOOL smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2263 {
2264         prs_struct *ps=&buffer->prs;
2265
2266         prs_debug(ps, depth, desc, "smb_io_port_info_2");
2267         depth++;        
2268         
2269         buffer->struct_start=prs_offset(ps);
2270         
2271         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2272                 return False;
2273         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2274                 return False;
2275         if (!smb_io_relstr("description", buffer, depth, &info->description))
2276                 return False;
2277         if (!prs_uint32("port_type", ps, depth, &info->port_type))
2278                 return False;
2279         if (!prs_uint32("reserved", ps, depth, &info->reserved))
2280                 return False;
2281
2282         return True;
2283 }
2284
2285 /*******************************************************************
2286  Parse a DRIVER_INFO_1 structure.
2287 ********************************************************************/
2288
2289 BOOL smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
2290 {
2291         prs_struct *ps=&buffer->prs;
2292
2293         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2294         depth++;        
2295         
2296         buffer->struct_start=prs_offset(ps);
2297
2298         if (!smb_io_relstr("name", buffer, depth, &info->name))
2299                 return False;
2300
2301         return True;
2302 }
2303
2304 /*******************************************************************
2305  Parse a DRIVER_INFO_2 structure.
2306 ********************************************************************/
2307
2308 BOOL smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
2309 {
2310         prs_struct *ps=&buffer->prs;
2311
2312         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2313         depth++;        
2314         
2315         buffer->struct_start=prs_offset(ps);
2316
2317         if (!prs_uint32("version", ps, depth, &info->version))
2318                 return False;
2319         if (!smb_io_relstr("name", buffer, depth, &info->name))
2320                 return False;
2321         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2322                 return False;
2323         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2324                 return False;
2325         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2326                 return False;
2327         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2328                 return False;
2329
2330         return True;
2331 }
2332
2333 /*******************************************************************
2334  Parse a DRIVER_INFO_3 structure.
2335 ********************************************************************/
2336
2337 BOOL smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2338 {
2339         prs_struct *ps=&buffer->prs;
2340
2341         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2342         depth++;        
2343         
2344         buffer->struct_start=prs_offset(ps);
2345
2346         if (!prs_uint32("version", ps, depth, &info->version))
2347                 return False;
2348         if (!smb_io_relstr("name", buffer, depth, &info->name))
2349                 return False;
2350         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2351                 return False;
2352         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2353                 return False;
2354         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2355                 return False;
2356         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2357                 return False;
2358         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2359                 return False;
2360
2361         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2362                 return False;
2363
2364         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2365                 return False;
2366         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2367                 return False;
2368
2369         return True;
2370 }
2371
2372 /*******************************************************************
2373  Parse a DRIVER_INFO_6 structure.
2374 ********************************************************************/
2375
2376 BOOL smb_io_printer_driver_info_6(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2377 {
2378         prs_struct *ps=&buffer->prs;
2379
2380         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2381         depth++;        
2382         
2383         buffer->struct_start=prs_offset(ps);
2384
2385         if (!prs_uint32("version", ps, depth, &info->version))
2386                 return False;
2387         if (!smb_io_relstr("name", buffer, depth, &info->name))
2388                 return False;
2389         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2390                 return False;
2391         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2392                 return False;
2393         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2394                 return False;
2395         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2396                 return False;
2397         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2398                 return False;
2399
2400         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2401                 return False;
2402
2403         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2404                 return False;
2405         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2406                 return False;
2407
2408         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2409                 return False;
2410
2411         if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
2412                 return False;
2413         if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
2414                 return False;
2415
2416         if (!prs_uint32("padding", ps, depth, &info->padding))
2417                 return False;
2418
2419         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2420                 return False;
2421
2422         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2423                 return False;
2424
2425         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2426                 return False;
2427         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2428                 return False;
2429         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2430                 return False;
2431         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2432                 return False;
2433         
2434         return True;
2435 }
2436
2437 /*******************************************************************
2438  Parse a JOB_INFO_1 structure.
2439 ********************************************************************/  
2440
2441 BOOL smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2442 {
2443         prs_struct *ps=&buffer->prs;
2444
2445         prs_debug(ps, depth, desc, "smb_io_job_info_1");
2446         depth++;        
2447         
2448         buffer->struct_start=prs_offset(ps);
2449
2450         if (!prs_uint32("jobid", ps, depth, &info->jobid))
2451                 return False;
2452         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2453                 return False;
2454         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2455                 return False;
2456         if (!smb_io_relstr("username", buffer, depth, &info->username))
2457                 return False;
2458         if (!smb_io_relstr("document", buffer, depth, &info->document))
2459                 return False;
2460         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2461                 return False;
2462         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2463                 return False;
2464         if (!prs_uint32("status", ps, depth, &info->status))
2465                 return False;
2466         if (!prs_uint32("priority", ps, depth, &info->priority))
2467                 return False;
2468         if (!prs_uint32("position", ps, depth, &info->position))
2469                 return False;
2470         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2471                 return False;
2472         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2473                 return False;
2474         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2475                 return False;
2476
2477         return True;
2478 }
2479
2480 /*******************************************************************
2481  Parse a JOB_INFO_2 structure.
2482 ********************************************************************/  
2483
2484 BOOL smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2485 {       
2486         uint32 pipo=0;
2487         prs_struct *ps=&buffer->prs;
2488         
2489         prs_debug(ps, depth, desc, "smb_io_job_info_2");
2490         depth++;        
2491
2492         buffer->struct_start=prs_offset(ps);
2493         
2494         if (!prs_uint32("jobid",ps, depth, &info->jobid))
2495                 return False;
2496         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2497                 return False;
2498         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2499                 return False;
2500         if (!smb_io_relstr("username", buffer, depth, &info->username))
2501                 return False;
2502         if (!smb_io_relstr("document", buffer, depth, &info->document))
2503                 return False;
2504         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2505                 return False;
2506         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2507                 return False;
2508
2509         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2510                 return False;
2511         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2512                 return False;
2513         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2514                 return False;
2515         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2516                 return False;
2517         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2518                 return False;
2519
2520 /*      SEC_DESC sec_desc;*/
2521         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2522                 return False;
2523
2524         if (!prs_uint32("status",ps, depth, &info->status))
2525                 return False;
2526         if (!prs_uint32("priority",ps, depth, &info->priority))
2527                 return False;
2528         if (!prs_uint32("position",ps, depth, &info->position)) 
2529                 return False;
2530         if (!prs_uint32("starttime",ps, depth, &info->starttime))
2531                 return False;
2532         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2533                 return False;
2534         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2535                 return False;
2536         if (!prs_uint32("size",ps, depth, &info->size))
2537                 return False;
2538         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2539                 return False;
2540         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2541                 return False;
2542         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2543                 return False;
2544
2545         return True;
2546 }
2547
2548 /*******************************************************************
2549 ********************************************************************/  
2550
2551 BOOL smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
2552 {
2553         prs_struct *ps=&buffer->prs;
2554         
2555         prs_debug(ps, depth, desc, "smb_io_form_1");
2556         depth++;
2557                 
2558         buffer->struct_start=prs_offset(ps);
2559         
2560         if (!prs_uint32("flag", ps, depth, &info->flag))
2561                 return False;
2562                 
2563         if (!smb_io_relstr("name", buffer, depth, &info->name))
2564                 return False;
2565
2566         if (!prs_uint32("width", ps, depth, &info->width))
2567                 return False;
2568         if (!prs_uint32("length", ps, depth, &info->length))
2569                 return False;
2570         if (!prs_uint32("left", ps, depth, &info->left))
2571                 return False;
2572         if (!prs_uint32("top", ps, depth, &info->top))
2573                 return False;
2574         if (!prs_uint32("right", ps, depth, &info->right))
2575                 return False;
2576         if (!prs_uint32("bottom", ps, depth, &info->bottom))
2577                 return False;
2578
2579         return True;
2580 }
2581
2582 /*******************************************************************
2583  Read/write a BUFFER struct.
2584 ********************************************************************/  
2585
2586 static BOOL spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer)
2587 {
2588         NEW_BUFFER *buffer = *pp_buffer;
2589
2590         prs_debug(ps, depth, desc, "spoolss_io_buffer");
2591         depth++;
2592         
2593         if (UNMARSHALLING(ps))
2594                 buffer = *pp_buffer = (NEW_BUFFER *)prs_alloc_mem(ps, sizeof(NEW_BUFFER));
2595
2596         if (buffer == NULL)
2597                 return False;
2598
2599         if (!prs_uint32("ptr", ps, depth, &buffer->ptr))
2600                 return False;
2601         
2602         /* reading */
2603         if (UNMARSHALLING(ps)) {
2604                 buffer->size=0;
2605                 buffer->string_at_end=0;
2606                 
2607                 if (buffer->ptr==0) {
2608                         /*
2609                          * JRA. I'm not sure if the data in here is in big-endian format if
2610                          * the client is big-endian. Leave as default (little endian) for now.
2611                          */
2612
2613                         if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL))
2614                                 return False;
2615                         return True;
2616                 }
2617                 
2618                 if (!prs_uint32("size", ps, depth, &buffer->size))
2619                         return False;
2620                                         
2621                 /*
2622                  * JRA. I'm not sure if the data in here is in big-endian format if
2623                  * the client is big-endian. Leave as default (little endian) for now.
2624                  */
2625
2626                 if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
2627                         return False;
2628
2629                 if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
2630                         return False;
2631
2632                 if (!prs_set_offset(&buffer->prs, 0))
2633                         return False;
2634
2635                 if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
2636                         return False;
2637
2638                 buffer->string_at_end=buffer->size;
2639                 
2640                 return True;
2641         }
2642         else {
2643                 BOOL ret = False;
2644
2645                 /* writing */
2646                 if (buffer->ptr==0) {
2647                         /* We have finished with the data in buffer->prs - free it. */
2648                         prs_mem_free(&buffer->prs);
2649                         return True;
2650                 }
2651         
2652                 if (!prs_uint32("size", ps, depth, &buffer->size))
2653                         goto out;
2654
2655                 if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
2656                         goto out;
2657
2658                 ret = True;
2659         out:
2660
2661                 /* We have finished with the data in buffer->prs - free it. */
2662                 prs_mem_free(&buffer->prs);
2663
2664                 return ret;
2665         }
2666 }
2667
2668 /*******************************************************************
2669  move a BUFFER from the query to the reply.
2670  As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed,
2671  this is ok. This is an OPTIMIZATION and is not strictly neccessary.
2672 ********************************************************************/  
2673
2674 void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
2675 {
2676         prs_switch_type(&src->prs, MARSHALL);
2677         if(!prs_set_offset(&src->prs, 0))
2678                 return;
2679         prs_force_dynamic(&(src->prs));
2680
2681         *dest=src;
2682 }
2683
2684 /*******************************************************************
2685  Get the size of a BUFFER struct.
2686 ********************************************************************/  
2687
2688 uint32 new_get_buffer_size(NEW_BUFFER *buffer)
2689 {
2690         return (buffer->size);
2691 }
2692
2693 /*******************************************************************
2694  Parse a DRIVER_DIRECTORY_1 structure.
2695 ********************************************************************/  
2696
2697 BOOL smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2698 {
2699         prs_struct *ps=&buffer->prs;
2700
2701         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2702         depth++;
2703
2704         buffer->struct_start=prs_offset(ps);
2705
2706         if (!smb_io_unistr(desc, &info->name, ps, depth))
2707                 return False;
2708
2709         return True;
2710 }
2711
2712 /*******************************************************************
2713  Parse a PORT_INFO_1 structure.
2714 ********************************************************************/  
2715
2716 BOOL smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2717 {
2718         prs_struct *ps=&buffer->prs;
2719
2720         prs_debug(ps, depth, desc, "smb_io_port_1");
2721         depth++;
2722
2723         buffer->struct_start=prs_offset(ps);
2724
2725         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2726                 return False;
2727
2728         return True;
2729 }
2730
2731 /*******************************************************************
2732  Parse a PORT_INFO_2 structure.
2733 ********************************************************************/  
2734
2735 BOOL smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2736 {
2737         prs_struct *ps=&buffer->prs;
2738
2739         prs_debug(ps, depth, desc, "smb_io_port_2");
2740         depth++;
2741
2742         buffer->struct_start=prs_offset(ps);
2743
2744         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2745                 return False;
2746         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2747                 return False;
2748         if(!smb_io_relstr("description", buffer, depth, &info->description))
2749                 return False;
2750         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2751                 return False;
2752         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2753                 return False;
2754
2755         return True;
2756 }
2757
2758 /*******************************************************************
2759 ********************************************************************/  
2760
2761 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2762 {
2763         prs_struct *ps=&buffer->prs;
2764
2765         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2766         depth++;        
2767
2768         buffer->struct_start=prs_offset(ps);
2769         
2770         if (smb_io_relstr("name", buffer, depth, &info->name))
2771                 return False;
2772
2773         return True;
2774 }
2775
2776 /*******************************************************************
2777 ********************************************************************/  
2778
2779 BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2780 {
2781         prs_struct *ps=&buffer->prs;
2782
2783         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2784         depth++;        
2785
2786         buffer->struct_start=prs_offset(ps);
2787         
2788         if (smb_io_relstr("name", buffer, depth, &info->name))
2789                 return False;
2790
2791         return True;
2792 }
2793
2794 /*******************************************************************
2795 ********************************************************************/  
2796
2797 BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2798 {
2799         prs_struct *ps=&buffer->prs;
2800
2801         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2802         depth++;        
2803
2804         buffer->struct_start=prs_offset(ps);
2805
2806         if (!smb_io_relstr("name", buffer, depth, &info->name))
2807                 return False;
2808
2809         return True;
2810 }
2811
2812 /*******************************************************************
2813 ********************************************************************/  
2814
2815 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2816 {
2817         prs_struct *ps=&buffer->prs;
2818
2819         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2820         depth++;        
2821
2822         buffer->struct_start=prs_offset(ps);
2823
2824         if (!smb_io_relstr("name", buffer, depth, &info->name))
2825                 return False;
2826         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2827                 return False;
2828         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2829                 return False;
2830
2831         return True;
2832 }
2833
2834 /*******************************************************************
2835 return the size required by a struct in the stream
2836 ********************************************************************/  
2837
2838 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2839 {
2840         int size=0;
2841         
2842         size+=size_of_relative_string( &info->printername );
2843         size+=size_of_relative_string( &info->servername );
2844
2845         size+=size_of_uint32( &info->cjobs);
2846         size+=size_of_uint32( &info->total_jobs);
2847         size+=size_of_uint32( &info->total_bytes);
2848
2849         size+=size_of_uint16( &info->year);
2850         size+=size_of_uint16( &info->month);
2851         size+=size_of_uint16( &info->dayofweek);
2852         size+=size_of_uint16( &info->day);
2853         size+=size_of_uint16( &info->hour);
2854         size+=size_of_uint16( &info->minute);
2855         size+=size_of_uint16( &info->second);
2856         size+=size_of_uint16( &info->milliseconds);
2857
2858         size+=size_of_uint32( &info->global_counter);
2859         size+=size_of_uint32( &info->total_pages);
2860
2861         size+=size_of_uint16( &info->major_version);
2862         size+=size_of_uint16( &info->build_version);
2863
2864         size+=size_of_uint32( &info->unknown7);
2865         size+=size_of_uint32( &info->unknown8);
2866         size+=size_of_uint32( &info->unknown9);
2867         size+=size_of_uint32( &info->session_counter);
2868         size+=size_of_uint32( &info->unknown11);
2869         size+=size_of_uint32( &info->printer_errors);
2870         size+=size_of_uint32( &info->unknown13);
2871         size+=size_of_uint32( &info->unknown14);
2872         size+=size_of_uint32( &info->unknown15);
2873         size+=size_of_uint32( &info->unknown16);
2874         size+=size_of_uint32( &info->change_id);
2875         size+=size_of_uint32( &info->unknown18);
2876         size+=size_of_uint32( &info->status);
2877         size+=size_of_uint32( &info->unknown20);
2878         size+=size_of_uint32( &info->c_setprinter);
2879         
2880         size+=size_of_uint16( &info->unknown22);
2881         size+=size_of_uint16( &info->unknown23);
2882         size+=size_of_uint16( &info->unknown24);
2883         size+=size_of_uint16( &info->unknown25);
2884         size+=size_of_uint16( &info->unknown26);
2885         size+=size_of_uint16( &info->unknown27);
2886         size+=size_of_uint16( &info->unknown28);
2887         size+=size_of_uint16( &info->unknown29);
2888         
2889         return size;
2890 }
2891
2892 /*******************************************************************
2893 return the size required by a struct in the stream
2894 ********************************************************************/  
2895
2896 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
2897 {
2898         int size=0;
2899                 
2900         size+=size_of_uint32( &info->flags );   
2901         size+=size_of_relative_string( &info->description );
2902         size+=size_of_relative_string( &info->name );
2903         size+=size_of_relative_string( &info->comment );
2904
2905         return size;
2906 }
2907
2908 /*******************************************************************
2909 return the size required by a struct in the stream
2910 ********************************************************************/
2911
2912 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
2913 {
2914         uint32 size=0;
2915                 
2916         size += 4;
2917         /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
2918         size += sec_desc_size( info->secdesc );
2919
2920         size+=size_of_device_mode( info->devmode );
2921         
2922         size+=size_of_relative_string( &info->servername );
2923         size+=size_of_relative_string( &info->printername );
2924         size+=size_of_relative_string( &info->sharename );
2925         size+=size_of_relative_string( &info->portname );
2926         size+=size_of_relative_string( &info->drivername );
2927         size+=size_of_relative_string( &info->comment );
2928         size+=size_of_relative_string( &info->location );
2929         
2930         size+=size_of_relative_string( &info->sepfile );
2931         size+=size_of_relative_string( &info->printprocessor );
2932         size+=size_of_relative_string( &info->datatype );
2933         size+=size_of_relative_string( &info->parameters );
2934
2935         size+=size_of_uint32( &info->attributes );
2936         size+=size_of_uint32( &info->priority );
2937         size+=size_of_uint32( &info->defaultpriority );
2938         size+=size_of_uint32( &info->starttime );
2939         size+=size_of_uint32( &info->untiltime );
2940         size+=size_of_uint32( &info->status );
2941         size+=size_of_uint32( &info->cjobs );
2942         size+=size_of_uint32( &info->averageppm );      
2943         return size;
2944 }
2945
2946 /*******************************************************************
2947 return the size required by a struct in the stream
2948 ********************************************************************/
2949
2950 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
2951 {
2952         /* The 4 is for the self relative pointer.. */
2953         /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
2954         return 4 + (uint32)sec_desc_size( info->secdesc );
2955 }
2956
2957 /*******************************************************************
2958 return the size required by a struct in the stream
2959 ********************************************************************/
2960
2961 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
2962 {
2963         int size=0;
2964         size+=size_of_relative_string( &info->name );
2965
2966         return size;
2967 }
2968
2969 /*******************************************************************
2970 return the size required by a struct in the stream
2971 ********************************************************************/
2972
2973 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
2974 {
2975         int size=0;
2976         size+=size_of_uint32( &info->version ); 
2977         size+=size_of_relative_string( &info->name );
2978         size+=size_of_relative_string( &info->architecture );
2979         size+=size_of_relative_string( &info->driverpath );
2980         size+=size_of_relative_string( &info->datafile );
2981         size+=size_of_relative_string( &info->configfile );
2982
2983         return size;
2984 }
2985
2986 /*******************************************************************
2987 return the size required by a string array.
2988 ********************************************************************/
2989
2990 uint32 spoolss_size_string_array(uint16 *string)
2991 {
2992         uint32 i = 0;
2993
2994         if (string) {
2995                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
2996         }
2997         i=i+2; /* to count all chars including the leading zero */
2998         i=2*i; /* because we need the value in bytes */
2999         i=i+4; /* the offset pointer size */
3000
3001         return i;
3002 }
3003
3004 /*******************************************************************
3005 return the size required by a struct in the stream
3006 ********************************************************************/
3007
3008 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3009 {
3010         int size=0;
3011
3012         size+=size_of_uint32( &info->version ); 
3013         size+=size_of_relative_string( &info->name );
3014         size+=size_of_relative_string( &info->architecture );
3015         size+=size_of_relative_string( &info->driverpath );
3016         size+=size_of_relative_string( &info->datafile );
3017         size+=size_of_relative_string( &info->configfile );
3018         size+=size_of_relative_string( &info->helpfile );
3019         size+=size_of_relative_string( &info->monitorname );
3020         size+=size_of_relative_string( &info->defaultdatatype );
3021         
3022         size+=spoolss_size_string_array(info->dependentfiles);
3023
3024         return size;
3025 }
3026
3027 /*******************************************************************
3028 return the size required by a struct in the stream
3029 ********************************************************************/
3030
3031 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3032 {
3033         uint32 size=0;
3034
3035         size+=size_of_uint32( &info->version ); 
3036         size+=size_of_relative_string( &info->name );
3037         size+=size_of_relative_string( &info->architecture );
3038         size+=size_of_relative_string( &info->driverpath );
3039         size+=size_of_relative_string( &info->datafile );
3040         size+=size_of_relative_string( &info->configfile );
3041         size+=size_of_relative_string( &info->helpfile );
3042
3043         size+=spoolss_size_string_array(info->dependentfiles);
3044
3045         size+=size_of_relative_string( &info->monitorname );
3046         size+=size_of_relative_string( &info->defaultdatatype );
3047         
3048         size+=spoolss_size_string_array(info->previousdrivernames);
3049
3050         size+=size_of_nttime(&info->driver_date);
3051         size+=size_of_uint32( &info->padding ); 
3052         size+=size_of_uint32( &info->driver_version_low );      
3053         size+=size_of_uint32( &info->driver_version_high );     
3054         size+=size_of_relative_string( &info->mfgname );
3055         size+=size_of_relative_string( &info->oem_url );
3056         size+=size_of_relative_string( &info->hardware_id );
3057         size+=size_of_relative_string( &info->provider );
3058
3059         return size;
3060 }
3061
3062 /*******************************************************************
3063 return the size required by a struct in the stream
3064 ********************************************************************/  
3065
3066 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3067 {
3068         int size=0;
3069         size+=size_of_uint32( &info->jobid );
3070         size+=size_of_relative_string( &info->printername );
3071         size+=size_of_relative_string( &info->machinename );
3072         size+=size_of_relative_string( &info->username );
3073         size+=size_of_relative_string( &info->document );
3074         size+=size_of_relative_string( &info->datatype );
3075         size+=size_of_relative_string( &info->text_status );
3076         size+=size_of_uint32( &info->status );
3077         size+=size_of_uint32( &info->priority );
3078         size+=size_of_uint32( &info->position );
3079         size+=size_of_uint32( &info->totalpages );
3080         size+=size_of_uint32( &info->pagesprinted );
3081         size+=size_of_systemtime( &info->submitted );
3082
3083         return size;
3084 }
3085
3086 /*******************************************************************
3087 return the size required by a struct in the stream
3088 ********************************************************************/  
3089
3090 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3091 {
3092         int size=0;
3093
3094         size+=4; /* size of sec desc ptr */
3095
3096         size+=size_of_uint32( &info->jobid );
3097         size+=size_of_relative_string( &info->printername );
3098         size+=size_of_relative_string( &info->machinename );
3099         size+=size_of_relative_string( &info->username );
3100         size+=size_of_relative_string( &info->document );
3101         size+=size_of_relative_string( &info->notifyname );
3102         size+=size_of_relative_string( &info->datatype );
3103         size+=size_of_relative_string( &info->printprocessor );
3104         size+=size_of_relative_string( &info->parameters );
3105         size+=size_of_relative_string( &info->drivername );
3106         size+=size_of_device_mode( info->devmode );
3107         size+=size_of_relative_string( &info->text_status );
3108 /*      SEC_DESC sec_desc;*/
3109         size+=size_of_uint32( &info->status );
3110         size+=size_of_uint32( &info->priority );
3111         size+=size_of_uint32( &info->position );
3112         size+=size_of_uint32( &info->starttime );
3113         size+=size_of_uint32( &info->untiltime );
3114         size+=size_of_uint32( &info->totalpages );
3115         size+=size_of_uint32( &info->size );
3116         size+=size_of_systemtime( &info->submitted );
3117         size+=size_of_uint32( &info->timeelapsed );
3118         size+=size_of_uint32( &info->pagesprinted );
3119
3120         return size;
3121 }
3122
3123 /*******************************************************************
3124 return the size required by a struct in the stream
3125 ********************************************************************/
3126
3127 uint32 spoolss_size_form_1(FORM_1 *info)
3128 {
3129         int size=0;
3130
3131         size+=size_of_uint32( &info->flag );
3132         size+=size_of_relative_string( &info->name );
3133         size+=size_of_uint32( &info->width );
3134         size+=size_of_uint32( &info->length );
3135         size+=size_of_uint32( &info->left );
3136         size+=size_of_uint32( &info->top );
3137         size+=size_of_uint32( &info->right );
3138         size+=size_of_uint32( &info->bottom );
3139
3140         return size;
3141 }
3142
3143 /*******************************************************************
3144 return the size required by a struct in the stream
3145 ********************************************************************/  
3146
3147 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3148 {
3149         int size=0;
3150
3151         size+=size_of_relative_string( &info->port_name );
3152
3153         return size;
3154 }
3155
3156 /*******************************************************************
3157 return the size required by a struct in the stream
3158 ********************************************************************/  
3159
3160 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3161 {
3162         int size=0;
3163
3164         size=str_len_uni(&info->name);  /* the string length       */
3165         size=size+1;                    /* add the leading zero    */
3166         size=size*2;                    /* convert in char         */
3167
3168         return size;
3169 }
3170
3171 /*******************************************************************
3172 return the size required by a struct in the stream
3173 ********************************************************************/  
3174
3175 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3176 {
3177         int size=0;
3178
3179         size+=size_of_relative_string( &info->port_name );
3180         size+=size_of_relative_string( &info->monitor_name );
3181         size+=size_of_relative_string( &info->description );
3182
3183         size+=size_of_uint32( &info->port_type );
3184         size+=size_of_uint32( &info->reserved );
3185
3186         return size;
3187 }
3188
3189 /*******************************************************************
3190 return the size required by a struct in the stream
3191 ********************************************************************/  
3192
3193 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3194 {
3195         int size=0;
3196         size+=size_of_relative_string( &info->name );
3197
3198         return size;
3199 }
3200
3201 /*******************************************************************
3202 return the size required by a struct in the stream
3203 ********************************************************************/  
3204
3205 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3206 {
3207         int size=0;
3208         size+=size_of_relative_string( &info->name );
3209
3210         return size;
3211 }
3212
3213 /*******************************************************************
3214 return the size required by a struct in the stream
3215 ********************************************************************/  
3216
3217 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3218 {
3219         int size=0;
3220         size+=size_of_relative_string( &info->name );
3221
3222         return size;
3223 }
3224
3225 /*******************************************************************
3226 return the size required by a struct in the stream
3227 ********************************************************************/  
3228
3229 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3230 {
3231         int size=0;
3232         size+=size_of_relative_string( &info->name);
3233         size+=size_of_relative_string( &info->environment);
3234         size+=size_of_relative_string( &info->dll_name);
3235
3236         return size;
3237 }
3238
3239 /*******************************************************************
3240  * init a structure.
3241  ********************************************************************/
3242
3243 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
3244                                const POLICY_HND *hnd,
3245                                const fstring architecture,
3246                                uint32 level, uint32 clientmajor, uint32 clientminor,
3247                                NEW_BUFFER *buffer, uint32 offered)
3248 {      
3249         if (q_u == NULL)
3250                 return False;
3251
3252         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3253
3254         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3255
3256         q_u->level=level;
3257         q_u->clientmajorversion=clientmajor;
3258         q_u->clientminorversion=clientminor;
3259
3260         q_u->buffer=buffer;
3261         q_u->offered=offered;
3262
3263         return True;
3264 }
3265
3266 /*******************************************************************
3267  * read a structure.
3268  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3269  ********************************************************************/
3270
3271 BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3272 {
3273         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3274         depth++;
3275
3276         if(!prs_align(ps))
3277                 return False;
3278         
3279         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3280                 return False;
3281         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3282                 return False;
3283         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3284                 return False;
3285         
3286         if(!prs_align(ps))
3287                 return False;
3288         if(!prs_uint32("level", ps, depth, &q_u->level))
3289                 return False;
3290                 
3291         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3292                 return False;
3293
3294         if(!prs_align(ps))
3295                 return False;
3296
3297         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3298                 return False;
3299                 
3300         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3301                 return False;
3302         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3303                 return False;
3304
3305         return True;
3306 }
3307
3308 /*******************************************************************
3309  * read a structure.
3310  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3311  ********************************************************************/
3312
3313 BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3314 {
3315         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3316         depth++;
3317
3318         if (!prs_align(ps))
3319                 return False;
3320                 
3321         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3322                 return False;
3323
3324         if (!prs_align(ps))
3325                 return False;
3326         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3327                 return False;
3328         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3329                 return False;
3330         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3331                 return False;           
3332         if (!prs_werror("status", ps, depth, &r_u->status))
3333                 return False;
3334
3335         return True;            
3336 }
3337
3338 /*******************************************************************
3339  * init a structure.
3340  ********************************************************************/
3341
3342 BOOL make_spoolss_q_enumprinters(
3343         SPOOL_Q_ENUMPRINTERS *q_u, 
3344         uint32 flags, 
3345         fstring servername, 
3346         uint32 level, 
3347         NEW_BUFFER *buffer, 
3348         uint32 offered
3349 )
3350 {
3351         q_u->flags=flags;
3352         
3353         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3354         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3355
3356         q_u->level=level;
3357         q_u->buffer=buffer;
3358         q_u->offered=offered;
3359
3360         return True;
3361 }
3362
3363 /*******************************************************************
3364  * init a structure.
3365  ********************************************************************/
3366
3367 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
3368                                 fstring servername, uint32 level, 
3369                                 NEW_BUFFER *buffer, uint32 offered)
3370 {
3371         q_u->name_ptr = (servername != NULL) ? 1 : 0;
3372         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3373
3374         q_u->level=level;
3375         q_u->buffer=buffer;
3376         q_u->offered=offered;
3377
3378         return True;
3379 }
3380
3381 /*******************************************************************
3382  * read a structure.
3383  * called from spoolss_enumprinters (srv_spoolss.c)
3384  ********************************************************************/
3385
3386 BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3387 {
3388         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3389         depth++;
3390
3391         if (!prs_align(ps))
3392                 return False;
3393
3394         if (!prs_uint32("flags", ps, depth, &q_u->flags))
3395                 return False;
3396         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3397                 return False;
3398
3399         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3400                 return False;
3401                 
3402         if (!prs_align(ps))
3403                 return False;
3404         if (!prs_uint32("level", ps, depth, &q_u->level))
3405                 return False;
3406
3407         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3408                 return False;
3409
3410         if (!prs_align(ps))
3411                 return False;
3412         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3413                 return False;
3414
3415         return True;
3416 }
3417
3418 /*******************************************************************
3419  Parse a SPOOL_R_ENUMPRINTERS structure.
3420  ********************************************************************/
3421
3422 BOOL spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3423 {
3424         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3425         depth++;
3426
3427         if (!prs_align(ps))
3428                 return False;
3429                 
3430         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3431                 return False;
3432
3433         if (!prs_align(ps))
3434                 return False;
3435                 
3436         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3437                 return False;
3438                 
3439         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3440                 return False;
3441                 
3442         if (!prs_werror("status", ps, depth, &r_u->status))
3443                 return False;
3444
3445         return True;            
3446 }
3447
3448 /*******************************************************************
3449  * write a structure.
3450  * called from spoolss_r_enum_printers (srv_spoolss.c)
3451  *
3452  ********************************************************************/
3453
3454 BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3455 {       
3456         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3457         depth++;
3458
3459         if (!prs_align(ps))
3460                 return False;
3461                 
3462         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3463                 return False;
3464
3465         if (!prs_align(ps))
3466                 return False;
3467
3468         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3469                 return False;
3470                 
3471         if (!prs_werror("status", ps, depth, &r_u->status))
3472                 return False;
3473
3474         return True;            
3475 }
3476
3477 /*******************************************************************
3478  * read a structure.
3479  * called from spoolss_getprinter (srv_spoolss.c)
3480  ********************************************************************/
3481
3482 BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3483 {
3484         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3485         depth++;
3486
3487         if (!prs_align(ps))
3488                 return False;
3489
3490         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3491                 return False;
3492         if (!prs_uint32("level", ps, depth, &q_u->level))
3493                 return False;
3494
3495         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3496                 return False;
3497
3498         if (!prs_align(ps))
3499                 return False;
3500         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3501                 return False;
3502
3503         return True;
3504 }
3505
3506 /*******************************************************************
3507  * init a structure.
3508  ********************************************************************/
3509
3510 BOOL make_spoolss_q_getprinter(
3511         TALLOC_CTX *mem_ctx,
3512         SPOOL_Q_GETPRINTER *q_u, 
3513         const POLICY_HND *hnd, 
3514         uint32 level, 
3515         NEW_BUFFER *buffer, 
3516         uint32 offered
3517 )
3518 {
3519         if (q_u == NULL)
3520         {
3521                 return False;
3522         }
3523         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3524
3525         q_u->level=level;
3526         q_u->buffer=buffer;
3527         q_u->offered=offered;
3528
3529         return True;
3530 }
3531
3532 /*******************************************************************
3533  * init a structure.
3534  ********************************************************************/
3535 BOOL make_spoolss_q_setprinter(
3536         TALLOC_CTX *mem_ctx,
3537         SPOOL_Q_SETPRINTER *q_u, 
3538         const POLICY_HND *hnd, 
3539         uint32 level, 
3540         PRINTER_INFO_CTR *info, 
3541         uint32 command
3542 )
3543 {
3544         SEC_DESC *secdesc;
3545         DEVICEMODE *devmode;
3546
3547         if (q_u == NULL)
3548         {
3549                 return False;
3550         }
3551         
3552         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3553
3554         q_u->level = level;
3555         q_u->info.level = level;
3556         q_u->info.info_ptr = (info != NULL) ? 1 : 0;
3557         switch (level)
3558         {
3559         case 2:
3560                 secdesc = info->printers_2->secdesc;
3561                 devmode = info->printers_2->devmode;
3562                 
3563                 /* FIXMEE!!  HACK ALERT!!!  --jerry */
3564                 info->printers_2->devmode = NULL;
3565                 info->printers_2->secdesc = NULL;
3566                 
3567                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3568 #if 0   /* JERRY TEST */
3569                 q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF));
3570                 if (!q_u->secdesc_ctr)
3571                         return False;
3572                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3573                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3574                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3575                 q_u->secdesc_ctr->sec = secdesc;
3576
3577                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3578                 q_u->devmode_ctr.size = sizeof(DEVICEMODE) + (3*sizeof(uint32));
3579                 q_u->devmode_ctr.devmode = devmode;
3580 #else
3581                 q_u->secdesc_ctr = NULL;
3582         
3583                 q_u->devmode_ctr.devmode_ptr = 0;
3584                 q_u->devmode_ctr.size = 0;
3585                 q_u->devmode_ctr.devmode = NULL;
3586 #endif
3587                 break;
3588         default: 
3589                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3590                         break;
3591         }
3592
3593         
3594         q_u->command = command;
3595
3596         return True;
3597 }
3598
3599
3600 /*******************************************************************
3601 ********************************************************************/  
3602
3603 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3604 {               
3605         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3606         depth++;
3607
3608         if(!prs_align(ps))
3609                 return False;
3610         
3611         if(!prs_werror("status", ps, depth, &r_u->status))
3612                 return False;
3613
3614         return True;
3615 }
3616
3617 /*******************************************************************
3618  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3619 ********************************************************************/  
3620
3621 BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3622 {
3623         uint32 ptr_sec_desc = 0;
3624
3625         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3626         depth++;
3627
3628         if(!prs_align(ps))
3629                 return False;
3630
3631         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3632                 return False;
3633         if(!prs_uint32("level", ps, depth, &q_u->level))
3634                 return False;
3635
3636         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3637                 return False;
3638
3639         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3640                 return False;
3641         
3642         switch (q_u->level)
3643         {
3644                 case 2:
3645                 {
3646                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3647                         break;
3648                 }
3649                 case 3:
3650                 {
3651                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3652                         break;
3653                 }
3654         }
3655         if (ptr_sec_desc)
3656         {
3657                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3658                         return False;
3659         } else {
3660                 uint32 dummy;
3661
3662                 /* Parse a NULL security descriptor.  This should really
3663                    happen inside the sec_io_desc_buf() function. */
3664
3665                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3666                 if (!prs_uint32("size", ps, depth + 1, &dummy)) return False;
3667                 if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
3668                                                                        False;
3669         }
3670         
3671         if(!prs_uint32("command", ps, depth, &q_u->command))
3672                 return False;
3673
3674         return True;
3675 }
3676
3677 /*******************************************************************
3678 ********************************************************************/  
3679
3680 BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
3681 {               
3682         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
3683         depth++;
3684
3685         if(!prs_align(ps))
3686                 return False;
3687         
3688         if(!prs_werror("status", ps, depth, &r_u->status))
3689                 return False;
3690
3691         return True;
3692 }
3693
3694 /*******************************************************************
3695 ********************************************************************/  
3696
3697 BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
3698 {
3699
3700         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
3701         depth++;
3702
3703         if(!prs_align(ps))
3704                 return False;
3705
3706         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3707                 return False;
3708
3709         return True;
3710 }
3711
3712
3713 /*******************************************************************
3714 ********************************************************************/  
3715
3716 BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
3717 {               
3718         prs_debug(ps, depth, desc, "");
3719         depth++;
3720
3721         if(!prs_align(ps))
3722                 return False;
3723         
3724         if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3725                 return False;
3726
3727         if(!prs_align(ps))
3728                 return False;
3729         
3730         if(!prs_uint32("needed", ps, depth, &r_u->needed))
3731                 return False;
3732
3733         if(!prs_werror("status", ps, depth, &r_u->status))
3734                 return False;
3735
3736         return True;
3737 }
3738
3739 /*******************************************************************
3740 ********************************************************************/  
3741
3742 BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
3743 {
3744         prs_debug(ps, depth, desc, "");
3745         depth++;
3746
3747         if(!prs_align(ps))
3748                 return False;
3749
3750         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3751                 return False;
3752         if(!prs_uint32("level", ps, depth, &q_u->level))
3753                 return False;
3754         
3755         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3756                 return False;
3757
3758         if(!prs_align(ps))
3759                 return False;
3760         
3761         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3762                 return False;
3763
3764         return True;
3765 }
3766
3767 /*******************************************************************
3768 ********************************************************************/  
3769
3770 BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
3771 {               
3772         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
3773         depth++;
3774
3775         if (!prs_align(ps))
3776                 return False;
3777                 
3778         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3779                 return False;
3780
3781         if (!prs_align(ps))
3782                 return False;
3783                 
3784         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3785                 return False;
3786                 
3787         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3788                 return False;
3789                 
3790         if (!prs_werror("status", ps, depth, &r_u->status))
3791                 return False;
3792
3793         return True;            
3794 }
3795
3796 /*******************************************************************
3797 ********************************************************************/  
3798
3799 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
3800                                 uint32 firstjob,
3801                                 uint32 numofjobs,
3802                                 uint32 level,
3803                                 NEW_BUFFER *buffer,
3804                                 uint32 offered)
3805 {
3806         if (q_u == NULL)
3807         {
3808                 return False;
3809         }
3810         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3811         q_u->firstjob = firstjob;
3812         q_u->numofjobs = numofjobs;
3813         q_u->level = level;
3814         q_u->buffer= buffer;
3815         q_u->offered = offered;
3816         return True;
3817 }
3818
3819 /*******************************************************************
3820 ********************************************************************/  
3821
3822 BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
3823 {
3824         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
3825         depth++;
3826
3827         if (!prs_align(ps))
3828                 return False;
3829
3830         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
3831                 return False;
3832                 
3833         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
3834                 return False;
3835         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
3836                 return False;
3837         if (!prs_uint32("level", ps, depth, &q_u->level))
3838                 return False;
3839
3840         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3841                 return False;   
3842
3843         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3844                 return False;
3845
3846         return True;
3847 }
3848
3849 /*******************************************************************
3850 ********************************************************************/  
3851
3852 BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
3853 {               
3854         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
3855         depth++;
3856
3857         if(!prs_align(ps))
3858                 return False;
3859         
3860         if(!prs_werror("status", ps, depth, &r_u->status))
3861                 return False;
3862
3863         return True;
3864 }
3865
3866 /*******************************************************************
3867 ********************************************************************/  
3868
3869 BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
3870 {
3871         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
3872         depth++;
3873
3874         if(!prs_align(ps))
3875                 return False;
3876
3877         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3878                 return False;
3879         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
3880                 return False;
3881
3882         return True;
3883 }
3884
3885 /*******************************************************************
3886 ********************************************************************/  
3887
3888 BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
3889 {               
3890         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
3891         depth++;
3892
3893         if(!prs_align(ps))
3894                 return False;
3895         
3896         if(!prs_werror("status", ps, depth, &r_u->status))
3897                 return False;
3898
3899         return True;
3900 }
3901
3902 /*******************************************************************
3903 ********************************************************************/  
3904
3905 BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
3906 {
3907         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
3908         depth++;
3909
3910         if(!prs_align(ps))
3911                 return False;
3912
3913         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3914                 return False;
3915         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
3916                 return False;
3917         /* 
3918          * level is usually 0. If (level!=0) then I'm in trouble !
3919          * I will try to generate setjob command with level!=0, one day.
3920          */
3921         if(!prs_uint32("level", ps, depth, &q_u->level))
3922                 return False;
3923         if(!prs_uint32("command", ps, depth, &q_u->command))
3924                 return False;
3925
3926         return True;
3927 }
3928
3929 /*******************************************************************
3930  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
3931 ********************************************************************/  
3932
3933 BOOL spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
3934 {
3935         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
3936         depth++;
3937
3938         if (!prs_align(ps))
3939                 return False;
3940                 
3941         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3942                 return False;
3943
3944         if (!prs_align(ps))
3945                 return False;
3946                 
3947         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3948                 return False;
3949                 
3950         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3951                 return False;
3952                 
3953         if (!prs_werror("status", ps, depth, &r_u->status))
3954                 return False;
3955
3956         return True;            
3957 }
3958
3959 /*******************************************************************
3960  * init a structure.
3961  ********************************************************************/
3962
3963 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
3964                                 const char *name,
3965                                 const char *environment,
3966                                 uint32 level,
3967                                 NEW_BUFFER *buffer, uint32 offered)
3968 {
3969         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
3970         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
3971
3972         q_u->level=level;
3973         q_u->buffer=buffer;
3974         q_u->offered=offered;
3975
3976         return True;
3977 }
3978
3979 /*******************************************************************
3980  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
3981 ********************************************************************/  
3982
3983 BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
3984 {
3985
3986         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
3987         depth++;
3988
3989         if (!prs_align(ps))
3990                 return False;
3991                 
3992         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3993                 return False;
3994         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
3995                 return False;
3996                 
3997         if (!prs_align(ps))
3998                 return False;
3999         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4000                 return False;
4001         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4002                 return False;
4003                 
4004         if (!prs_align(ps))
4005                 return False;
4006         if (!prs_uint32("level", ps, depth, &q_u->level))
4007                 return False;
4008                 
4009         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4010                 return False;
4011
4012         if (!prs_align(ps))
4013                 return False;
4014                 
4015         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4016                 return False;
4017
4018         return True;
4019 }
4020
4021 /*******************************************************************
4022 ********************************************************************/  
4023
4024 BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4025 {
4026
4027         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4028         depth++;
4029
4030         if (!prs_align(ps))
4031                 return False;                   
4032         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4033                 return False;           
4034         if (!prs_uint32("level", ps, depth, &q_u->level))
4035                 return False;   
4036         
4037         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4038                 return False;
4039
4040         if (!prs_align(ps))
4041                 return False;
4042         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4043                 return False;
4044
4045         return True;
4046 }
4047
4048 /*******************************************************************
4049 ********************************************************************/  
4050
4051 BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4052 {
4053         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4054         depth++;
4055
4056         if (!prs_align(ps))
4057                 return False;
4058                 
4059         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4060                 return False;
4061
4062         if (!prs_align(ps))
4063                 return False;
4064                 
4065         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4066                 return False;
4067                 
4068         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4069                 return False;
4070                 
4071         if (!prs_werror("status", ps, depth, &r_u->status))
4072                 return False;
4073
4074         return True;
4075 }
4076
4077 /*******************************************************************
4078 ********************************************************************/  
4079
4080 BOOL spoolss_io_q_getform(char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4081 {
4082
4083         prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4084         depth++;
4085
4086         if (!prs_align(ps))
4087                 return False;                   
4088         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4089                 return False;           
4090         if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4091                 return False;
4092
4093         if (!prs_align(ps))
4094                 return False;
4095
4096         if (!prs_uint32("level", ps, depth, &q_u->level))
4097                 return False;   
4098         
4099         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4100                 return False;
4101
4102         if (!prs_align(ps))
4103                 return False;
4104         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4105                 return False;
4106
4107         return True;
4108 }
4109
4110 /*******************************************************************
4111 ********************************************************************/  
4112
4113 BOOL spoolss_io_r_getform(char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4114 {
4115         prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4116         depth++;
4117
4118         if (!prs_align(ps))
4119                 return False;
4120                 
4121         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4122                 return False;
4123
4124         if (!prs_align(ps))
4125                 return False;
4126                 
4127         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4128                 return False;
4129                 
4130         if (!prs_werror("status", ps, depth, &r_u->status))
4131                 return False;
4132
4133         return True;
4134 }
4135
4136 /*******************************************************************
4137  Parse a SPOOL_R_ENUMPORTS structure.
4138 ********************************************************************/  
4139
4140 BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4141 {
4142         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4143         depth++;
4144
4145         if (!prs_align(ps))
4146                 return False;
4147                 
4148         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4149                 return False;
4150
4151         if (!prs_align(ps))
4152                 return False;
4153                 
4154         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4155                 return False;
4156                 
4157         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4158                 return False;
4159                 
4160         if (!prs_werror("status", ps, depth, &r_u->status))
4161                 return False;
4162
4163         return True;            
4164 }
4165
4166 /*******************************************************************
4167 ********************************************************************/  
4168
4169 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4170 {
4171         prs_debug(ps, depth, desc, "");
4172         depth++;
4173
4174         if (!prs_align(ps))
4175                 return False;
4176
4177         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4178                 return False;
4179         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4180                 return False;
4181
4182         if (!prs_align(ps))
4183                 return False;
4184         if (!prs_uint32("level", ps, depth, &q_u->level))
4185                 return False;
4186                 
4187         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4188                 return False;
4189
4190         if (!prs_align(ps))
4191                 return False;
4192         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4193                 return False;
4194
4195         return True;
4196 }
4197
4198 /*******************************************************************
4199  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4200 ********************************************************************/  
4201
4202 BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4203 {       
4204         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4205         depth++;
4206                 
4207         if(!prs_align(ps))
4208                 return False;
4209
4210         if(!prs_uint32("flags", ps, depth, &il->flags))
4211                 return False;
4212         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4213                 return False;
4214         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4215                 return False;
4216         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4217                 return False;
4218                 
4219         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4220                 return False;
4221         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4222                 return False;
4223         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4224                 return False;
4225
4226         return True;
4227 }
4228
4229 /*******************************************************************
4230  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4231 ********************************************************************/  
4232
4233 BOOL spool_io_printer_info_level_3(char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4234 {       
4235         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4236         depth++;
4237                 
4238         if(!prs_align(ps))
4239                 return False;
4240
4241         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4242                 return False;
4243
4244         return True;
4245 }
4246
4247 /*******************************************************************
4248  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4249 ********************************************************************/  
4250
4251 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4252 {       
4253         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4254         depth++;
4255                 
4256         if(!prs_align(ps))
4257                 return False;
4258
4259         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4260                 return False;
4261         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4262                 return False;
4263         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4264                 return False;
4265         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4266                 return False;
4267
4268         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4269                 return False;
4270         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4271                 return False;
4272         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4273                 return False;
4274         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4275                 return False;
4276         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4277                 return False;
4278         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4279                 return False;
4280         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4281                 return False;
4282         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4283                 return False;
4284         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4285                 return False;
4286
4287         if(!prs_uint32("attributes", ps, depth, &il->attributes))
4288                 return False;
4289         if(!prs_uint32("priority", ps, depth, &il->priority))
4290                 return False;
4291         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4292                 return False;
4293         if(!prs_uint32("starttime", ps, depth, &il->starttime))
4294                 return False;
4295         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4296                 return False;
4297         if(!prs_werror("status", ps, depth, &il->status))
4298                 return False;
4299         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4300                 return False;
4301         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4302                 return False;
4303
4304         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4305                 return False;
4306         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4307                 return False;
4308         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4309                 return False;
4310         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4311                 return False;
4312         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4313                 return False;
4314         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4315                 return False;
4316         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4317                 return False;
4318         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4319                 return False;
4320         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4321                 return False;
4322         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4323                 return False;
4324         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4325                 return False;
4326
4327         return True;
4328 }
4329
4330 /*******************************************************************
4331 ********************************************************************/  
4332
4333 BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4334 {
4335         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4336         depth++;
4337
4338         if(!prs_align(ps))
4339                 return False;
4340         if(!prs_uint32("level", ps, depth, &il->level))
4341                 return False;
4342         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4343                 return False;
4344         
4345         /* if no struct inside just return */
4346         if (il->info_ptr==0) {
4347                 if (UNMARSHALLING(ps)) {
4348                         il->info_1=NULL;
4349                         il->info_2=NULL;
4350                 }
4351                 return True;
4352         }
4353                         
4354         switch (il->level) {
4355                 /*
4356                  * level 0 is used by setprinter when managing the queue
4357                  * (hold, stop, start a queue)
4358                  */
4359                 case 0:
4360                         break;
4361                 /* DOCUMENT ME!!! What is level 1 used for? */
4362                 case 1:
4363                 {
4364                         if (UNMARSHALLING(ps)) {
4365                                 if ((il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_1))) == NULL)
4366                                         return False;
4367                         }
4368                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4369                                 return False;
4370                         break;          
4371                 }
4372                 /* 
4373                  * level 2 is used by addprinter
4374                  * and by setprinter when updating printer's info
4375                  */     
4376                 case 2:
4377                         if (UNMARSHALLING(ps)) {
4378                                 if ((il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_2))) == NULL)
4379                                         return False;
4380                         }
4381                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4382                                 return False;
4383                         break;          
4384                 /* DOCUMENT ME!!! What is level 3 used for? */
4385                 case 3:
4386                 {
4387                         if (UNMARSHALLING(ps)) {
4388                                 if ((il->info_3=(SPOOL_PRINTER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_3))) == NULL)
4389                                         return False;
4390                         }
4391                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4392                                 return False;
4393                         break;          
4394                 }
4395         }
4396
4397         return True;
4398 }
4399
4400 /*******************************************************************
4401 ********************************************************************/  
4402
4403 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4404 {
4405         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4406         depth++;
4407
4408         if(!prs_align(ps))
4409                 return False;
4410         if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
4411                 return False;
4412         if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4413                 return False;
4414
4415         if(!prs_align(ps))
4416                 return False;
4417
4418         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4419                 return False;
4420         
4421         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4422                 return False;
4423         
4424         /* the 4 unknown are all 0 */
4425
4426         /* 
4427          * en fait ils sont pas inconnu
4428          * par recoupement avec rpcSetPrinter
4429          * c'est le devicemode 
4430          * et le security descriptor.
4431          */
4432         
4433         if(!prs_align(ps))
4434                 return False;
4435         if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
4436                 return False;
4437         if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
4438                 return False;
4439         if(!prs_uint32("unk2", ps, depth, &q_u->unk2))
4440                 return False;
4441         if(!prs_uint32("unk3", ps, depth, &q_u->unk3))
4442                 return False;
4443
4444         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4445                 return False;
4446         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4447                 return False;
4448
4449         return True;
4450 }
4451
4452 /*******************************************************************
4453 ********************************************************************/  
4454
4455 BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
4456                                prs_struct *ps, int depth)
4457 {
4458         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4459         depth++;
4460         
4461         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4462                 return False;
4463
4464         if(!prs_werror("status", ps, depth, &r_u->status))
4465                 return False;
4466
4467         return True;
4468 }
4469
4470 /*******************************************************************
4471 ********************************************************************/  
4472
4473 BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
4474                                           prs_struct *ps, int depth)
4475 {       
4476         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4477         
4478         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4479         depth++;
4480                 
4481         /* reading */
4482         if (UNMARSHALLING(ps)) {
4483                 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
4484                 if(il == NULL)
4485                         return False;
4486                 *q_u=il;
4487         }
4488         else {
4489                 il=*q_u;
4490         }
4491         
4492         if(!prs_align(ps))
4493                 return False;
4494
4495         if(!prs_uint32("cversion", ps, depth, &il->cversion))
4496                 return False;
4497         if(!prs_uint32("name", ps, depth, &il->name_ptr))
4498                 return False;
4499         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4500                 return False;
4501         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4502                 return False;
4503         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4504                 return False;
4505         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4506                 return False;
4507         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4508                 return False;
4509         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4510                 return False;
4511         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4512                 return False;
4513         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4514                 return False;
4515         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4516                 return False;
4517
4518         if(!prs_align(ps))
4519                 return False;
4520         
4521         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4522                 return False;
4523         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4524                 return False;
4525         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4526                 return False;
4527         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4528                 return False;
4529         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4530                 return False;
4531         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4532                 return False;
4533         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4534                 return False;
4535         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4536                 return False;
4537
4538         if(!prs_align(ps))
4539                 return False;
4540                 
4541         if (il->dependentfiles_ptr)
4542                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4543
4544         return True;
4545 }
4546
4547 /*******************************************************************
4548 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4549 ********************************************************************/  
4550
4551 BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4552                                           prs_struct *ps, int depth)
4553 {       
4554         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4555         
4556         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4557         depth++;
4558                 
4559         /* reading */
4560         if (UNMARSHALLING(ps)) {
4561                 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6));
4562                 if(il == NULL)
4563                         return False;
4564                 *q_u=il;
4565         }
4566         else {
4567                 il=*q_u;
4568         }
4569         
4570         if(!prs_align(ps))
4571                 return False;
4572
4573
4574         /* parse the main elements the packet */
4575
4576         if(!prs_uint32("version", ps, depth, &il->version))
4577                 return False;
4578
4579         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4580                 return False;   
4581         /*
4582          * If name_ptr is NULL then the next 4 bytes are the name_ptr. A driver 
4583          * with a NULL name just isn't a driver For example: "HP LaserJet 4si"
4584          * from W2K CDROM (which uses unidriver). JohnR 010205
4585          */
4586         if (!il->name_ptr) {
4587                 DEBUG(5,("spool_io_printer_driver_info_level_6: name_ptr is NULL! Get next value\n"));
4588                 if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4589                         return False;   
4590         }
4591         
4592         if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr))
4593                 return False;
4594         if(!prs_uint32("driverpath_ptr", ps, depth, &il->driverpath_ptr))
4595                 return False;
4596         if(!prs_uint32("datafile_ptr", ps, depth, &il->datafile_ptr))
4597                 return False;
4598         if(!prs_uint32("configfile_ptr", ps, depth, &il->configfile_ptr))
4599                 return False;
4600         if(!prs_uint32("helpfile_ptr", ps, depth, &il->helpfile_ptr))
4601                 return False;
4602         if(!prs_uint32("monitorname_ptr", ps, depth, &il->monitorname_ptr))
4603                 return False;
4604         if(!prs_uint32("defaultdatatype_ptr", ps, depth, &il->defaultdatatype_ptr))
4605                 return False;
4606         if(!prs_uint32("dependentfiles_len", ps, depth, &il->dependentfiles_len))
4607                 return False;
4608         if(!prs_uint32("dependentfiles_ptr", ps, depth, &il->dependentfiles_ptr))
4609                 return False;
4610         if(!prs_uint32("previousnames_len", ps, depth, &il->previousnames_len))
4611                 return False;
4612         if(!prs_uint32("previousnames_ptr", ps, depth, &il->previousnames_ptr))
4613                 return False;
4614         if(!smb_io_time("driverdate", &il->driverdate, ps, depth))
4615                 return False;
4616         if(!prs_uint32("dummy4", ps, depth, &il->dummy4))
4617                 return False;
4618         if(!prs_uint64("driverversion", ps, depth, &il->driverversion))
4619                 return False;
4620         if(!prs_uint32("mfgname_ptr", ps, depth, &il->mfgname_ptr))
4621                 return False;
4622         if(!prs_uint32("oemurl_ptr", ps, depth, &il->oemurl_ptr))
4623                 return False;
4624         if(!prs_uint32("hardwareid_ptr", ps, depth, &il->hardwareid_ptr))
4625                 return False;
4626         if(!prs_uint32("provider_ptr", ps, depth, &il->provider_ptr))
4627                 return False;
4628
4629         /* parse the structures in the packet */
4630
4631         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4632                 return False;
4633         if(!prs_align(ps))
4634                 return False;
4635
4636         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4637                 return False;
4638         if(!prs_align(ps))
4639                 return False;
4640
4641         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4642                 return False;
4643         if(!prs_align(ps))
4644                 return False;
4645
4646         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4647                 return False;
4648         if(!prs_align(ps))
4649                 return False;
4650
4651         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4652                 return False;
4653         if(!prs_align(ps))
4654                 return False;
4655
4656         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4657                 return False;
4658         if(!prs_align(ps))
4659                 return False;
4660
4661         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4662                 return False;
4663         if(!prs_align(ps))
4664                 return False;
4665
4666         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4667                 return False;
4668         if(!prs_align(ps))
4669                 return False;
4670         if (il->dependentfiles_ptr) {
4671                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
4672                         return False;
4673                 if(!prs_align(ps))
4674                         return False;
4675         }
4676         if (il->previousnames_ptr) {
4677                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
4678                         return False;
4679                 if(!prs_align(ps))
4680                         return False;
4681         }
4682         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
4683                 return False;
4684         if(!prs_align(ps))
4685                 return False;
4686         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
4687                 return False;
4688         if(!prs_align(ps))
4689                 return False;
4690         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
4691                 return False;
4692         if(!prs_align(ps))
4693                 return False;
4694         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
4695                 return False;
4696
4697         return True;
4698 }
4699
4700 /*******************************************************************
4701  convert a buffer of UNICODE strings null terminated
4702  the buffer is terminated by a NULL
4703  
4704  convert to an dos codepage array (null terminated)
4705  
4706  dynamically allocate memory
4707  
4708 ********************************************************************/  
4709 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
4710 {
4711         fstring f, *tar;
4712         int n = 0;
4713         char *src;
4714
4715         if (buf5==NULL) return False;
4716
4717         src = (char *)buf5->buffer;
4718         *ar = NULL;
4719
4720         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
4721                 rpcstr_pull(f, src, sizeof(f)-1, -1, 0);
4722                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
4723                 tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
4724                 if (!tar) return False;
4725                 else *ar = tar;
4726                 fstrcpy((*ar)[n], f);
4727                 n++;
4728         }
4729         fstrcpy((*ar)[n], "");
4730
4731         return True;
4732 }
4733
4734 /*******************************************************************
4735  read a UNICODE array with null terminated strings 
4736  and null terminated array 
4737  and size of array at beginning
4738 ********************************************************************/  
4739
4740 BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
4741 {
4742         if (buffer==NULL) return False;
4743
4744         buffer->undoc=0;
4745         buffer->uni_str_len=buffer->uni_max_len;
4746         
4747         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
4748                 return False;
4749
4750         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
4751                 return False;
4752
4753         return True;
4754 }
4755
4756 /*******************************************************************
4757 ********************************************************************/  
4758
4759 BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
4760 {
4761         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
4762         depth++;
4763
4764         if(!prs_align(ps))
4765                 return False;
4766         if(!prs_uint32("level", ps, depth, &il->level))
4767                 return False;
4768         if(!prs_uint32("ptr", ps, depth, &il->ptr))
4769                 return False;
4770
4771         if (il->ptr==0)
4772                 return True;
4773                 
4774         switch (il->level) {
4775                 case 3:
4776                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
4777                                 return False;
4778                         break;          
4779                 case 6:
4780                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
4781                                 return False;
4782                         break;          
4783         default:
4784                 return False;
4785         }
4786
4787         return True;
4788 }
4789
4790 /*******************************************************************
4791  init a SPOOL_Q_ADDPRINTERDRIVER struct
4792  ******************************************************************/
4793
4794 BOOL make_spoolss_q_addprinterdriver(
4795         TALLOC_CTX *mem_ctx,
4796         SPOOL_Q_ADDPRINTERDRIVER *q_u, 
4797         const char* srv_name, 
4798         uint32 level, 
4799         PRINTER_DRIVER_CTR *info)
4800 {
4801         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
4802         
4803         q_u->server_name_ptr = (srv_name!=NULL)?1:0;
4804         init_unistr2(&q_u->server_name, srv_name, strlen(srv_name)+1);
4805         
4806         q_u->level = level;
4807         
4808         q_u->info.level = level;
4809         q_u->info.ptr = (info!=NULL)?1:0;
4810         switch (level)
4811         {
4812         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
4813         case 3 :
4814                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
4815                 break;
4816                 
4817         /* info level 6 is supported by WinME and Win2k */
4818         case 6:
4819                 /* WRITEME!!  will add later  --jerry */
4820                 break;
4821                 
4822         default:
4823                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
4824                 break;
4825         }
4826         
4827         return True;
4828 }
4829
4830 BOOL make_spoolss_driver_info_3(
4831         TALLOC_CTX *mem_ctx,
4832         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
4833         DRIVER_INFO_3 *info3
4834 )
4835 {
4836         uint32          len = 0;
4837         uint16          *ptr = info3->dependentfiles;
4838         BOOL            done = False;
4839         BOOL            null_char = False;
4840         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
4841
4842         if (!(inf=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*)talloc_zero(mem_ctx, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3))))
4843                 return False;
4844         
4845         inf->cversion   = info3->version;
4846         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
4847         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
4848         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
4849         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
4850         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
4851         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
4852         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
4853         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
4854
4855         init_unistr2_from_unistr(&inf->name, &info3->name);
4856         init_unistr2_from_unistr(&inf->environment, &info3->architecture);
4857         init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
4858         init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
4859         init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
4860         init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
4861         init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
4862         init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
4863
4864         while (!done)
4865         {
4866                 switch (*ptr)
4867                 {
4868                         case 0:
4869                                 /* the null_char BOOL is used to help locate
4870                                    two '\0's back to back */
4871                                 if (null_char)
4872                                         done = True;
4873                                 else
4874                                         null_char = True;
4875                                 break;
4876                                         
4877                         default:
4878                                 null_char = False;
4879                                 ;;
4880                                 break;                          
4881                 }
4882                 len++;
4883                 ptr++;
4884         }
4885         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
4886         inf->dependentfilessize = len;
4887         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles))
4888         {
4889                 safe_free (inf);
4890                 return False;
4891         }
4892         
4893         *spool_drv_info = inf;
4894         
4895         return True;
4896 }
4897
4898 /*******************************************************************
4899  make a BUFFER5 struct from a uint16*
4900  ******************************************************************/
4901
4902 BOOL make_spoolss_buffer5(
4903         TALLOC_CTX *mem_ctx,
4904         BUFFER5 *buf5, 
4905         uint32 len, 
4906         uint16 *src
4907 )
4908 {
4909
4910         buf5->buf_len = len;
4911         if((buf5->buffer=(uint16*)talloc_memdup(mem_ctx, src, sizeof(uint16)*len)) == NULL)
4912         {
4913                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
4914                 return False;
4915         }
4916         
4917         return True;
4918 }
4919
4920 /*******************************************************************
4921  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
4922  ********************************************************************/  
4923
4924 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4925 {
4926         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
4927         depth++;
4928
4929         if(!prs_align(ps))
4930                 return False;
4931
4932         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
4933                 return False;
4934         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4935                 return False;
4936                 
4937         if(!prs_align(ps))
4938                 return False;
4939         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4940                 return False;
4941
4942         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
4943                 return False;
4944
4945         return True;
4946 }
4947
4948 /*******************************************************************
4949 ********************************************************************/  
4950
4951 BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
4952 {
4953         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
4954         depth++;
4955
4956         if(!prs_werror("status", ps, depth, &q_u->status))
4957                 return False;
4958
4959         return True;
4960 }
4961
4962 /*******************************************************************
4963 ********************************************************************/  
4964
4965 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
4966                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
4967 {
4968         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
4969         
4970         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
4971         
4972         if (*asc==NULL)
4973         {
4974                 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
4975                 if(*asc == NULL)
4976                         return False;
4977                 ZERO_STRUCTP(*asc);
4978         }       
4979
4980         d=*asc;
4981
4982         d->cversion=uni->cversion;
4983
4984         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
4985         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
4986         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
4987         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
4988         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
4989         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
4990         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
4991         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
4992
4993         DEBUGADD(8,( "version:         %d\n", d->cversion));
4994         DEBUGADD(8,( "name:            %s\n", d->name));
4995         DEBUGADD(8,( "environment:     %s\n", d->environment));
4996         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
4997         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
4998         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
4999         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5000         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5001         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5002
5003         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5004                 return True;
5005         
5006         free(*asc);
5007         return False;
5008 }
5009
5010 /*******************************************************************
5011 ********************************************************************/  
5012 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5013                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5014 {
5015         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5016         
5017         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5018         
5019         if (*asc==NULL)
5020         {
5021                 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_6 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_6));
5022                 if(*asc == NULL)
5023                         return False;
5024                 ZERO_STRUCTP(*asc);
5025         }       
5026
5027         d=*asc;
5028
5029         d->version=uni->version;
5030
5031         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5032         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5033         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5034         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5035         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5036         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5037         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5038         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5039
5040         DEBUGADD(8,( "version:         %d\n", d->version));
5041         DEBUGADD(8,( "name:            %s\n", d->name));
5042         DEBUGADD(8,( "environment:     %s\n", d->environment));
5043         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5044         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5045         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5046         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5047         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5048         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5049
5050         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5051                 goto error;
5052         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5053                 goto error;
5054         
5055         return True;
5056         
5057 error:
5058         free(*asc);
5059         return False;
5060 }
5061
5062 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5063                               NT_PRINTER_INFO_LEVEL_2  **asc)
5064 {
5065         NT_PRINTER_INFO_LEVEL_2 *d;
5066         time_t time_unix;
5067         
5068         DEBUG(7,("Converting from UNICODE to ASCII\n"));
5069         time_unix=time(NULL);
5070         
5071         if (*asc==NULL) {
5072                 DEBUGADD(8,("allocating memory\n"));
5073
5074                 *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
5075                 if(*asc == NULL)
5076                         return False;
5077                 ZERO_STRUCTP(*asc);
5078                 
5079                 /* we allocate memory iff called from 
5080                  * addprinter(ex) so we can do one time stuff here.
5081                  */
5082                 (*asc)->setuptime=time_unix;
5083
5084         }       
5085         DEBUGADD(8,("start converting\n"));
5086
5087         d=*asc;
5088                 
5089         d->attributes=uni->attributes;
5090         d->priority=uni->priority;
5091         d->default_priority=uni->default_priority;
5092         d->starttime=uni->starttime;
5093         d->untiltime=uni->untiltime;
5094         d->status=uni->status;
5095         d->cjobs=uni->cjobs;
5096         
5097         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5098         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5099         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5100         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5101         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5102         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5103         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5104         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5105         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5106         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5107         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5108
5109         return True;
5110 }
5111
5112 /*******************************************************************
5113  * init a structure.
5114  ********************************************************************/
5115
5116 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5117                                 fstring servername, fstring env_name, uint32 level,
5118                                 NEW_BUFFER *buffer, uint32 offered)
5119 {
5120         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5121         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5122
5123         q_u->level=level;
5124         q_u->buffer=buffer;
5125         q_u->offered=offered;
5126
5127         return True;
5128 }
5129
5130 /*******************************************************************
5131  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5132 ********************************************************************/  
5133
5134 BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5135 {
5136         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5137         depth++;
5138
5139         if(!prs_align(ps))
5140                 return False;
5141         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5142                 return False;
5143         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5144                 return False;
5145
5146         if(!prs_align(ps))
5147                 return False;
5148                 
5149         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5150                 return False;
5151         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5152                 return False;
5153                 
5154         if(!prs_align(ps))
5155                 return False;
5156
5157         if(!prs_uint32("level", ps, depth, &q_u->level))
5158                 return False;
5159                 
5160         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5161                 return False;
5162                 
5163         if(!prs_align(ps))
5164                 return False;
5165                 
5166         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5167                 return False;
5168
5169         return True;
5170 }
5171
5172 /*******************************************************************
5173  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5174 ********************************************************************/  
5175
5176 BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5177 {               
5178         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5179         depth++;
5180
5181         if (!prs_align(ps))
5182                 return False;
5183                 
5184         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5185                 return False;
5186
5187         if (!prs_align(ps))
5188                 return False;
5189                 
5190         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5191                 return False;
5192                 
5193         if (!prs_werror("status", ps, depth, &r_u->status))
5194                 return False;
5195
5196         return True;            
5197 }
5198
5199 /*******************************************************************
5200 ********************************************************************/  
5201
5202 BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5203 {               
5204         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5205         depth++;
5206
5207         if (!prs_align(ps))
5208                 return False;
5209                 
5210         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5211                 return False;
5212
5213         if (!prs_align(ps))
5214                 return False;
5215                 
5216         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5217                 return False;
5218                 
5219         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5220                 return False;
5221                 
5222         if (!prs_werror("status", ps, depth, &r_u->status))
5223                 return False;
5224
5225         return True;            
5226 }
5227
5228 /*******************************************************************
5229 ********************************************************************/  
5230
5231 BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5232 {
5233         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5234         depth++;
5235
5236         if (!prs_align(ps))
5237                 return False;
5238                 
5239         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5240                 return False;
5241         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5242                 return False;
5243                 
5244         if (!prs_align(ps))
5245                 return False;
5246                 
5247         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5248                 return False;
5249         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5250                 return False;
5251         
5252         if (!prs_align(ps))
5253                 return False;
5254                 
5255         if (!prs_uint32("level", ps, depth, &q_u->level))
5256                 return False;
5257                 
5258         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5259                 return False;
5260
5261         if (!prs_align(ps))
5262                 return False;
5263
5264         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5265                 return False;
5266
5267         return True;
5268 }
5269
5270 /*******************************************************************
5271 ********************************************************************/  
5272
5273 BOOL spoolss_io_q_addprintprocessor(char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5274 {
5275         prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5276         depth++;
5277
5278         if (!prs_align(ps))
5279                 return False;
5280                 
5281         if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5282                 return False;
5283         if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5284                 return False;
5285                 
5286         if (!prs_align(ps))
5287                 return False;
5288         if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5289                 return False;
5290                 
5291         if (!prs_align(ps))
5292                 return False;
5293         if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5294                 return False;
5295
5296         if (!prs_align(ps))
5297                 return False;
5298         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5299                 return False;
5300
5301         return True;
5302 }
5303
5304 /*******************************************************************
5305 ********************************************************************/  
5306
5307 BOOL spoolss_io_r_addprintprocessor(char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5308 {               
5309         prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5310         depth++;
5311
5312         if (!prs_align(ps))
5313                 return False;
5314                 
5315         if (!prs_werror("status", ps, depth, &r_u->status))
5316                 return False;
5317
5318         return True;            
5319 }
5320
5321 /*******************************************************************
5322 ********************************************************************/  
5323
5324 BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5325 {               
5326         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5327         depth++;
5328
5329         if (!prs_align(ps))
5330                 return False;
5331                 
5332         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5333                 return False;
5334
5335         if (!prs_align(ps))
5336                 return False;
5337                 
5338         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5339                 return False;
5340                 
5341         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5342                 return False;
5343                 
5344         if (!prs_werror("status", ps, depth, &r_u->status))
5345                 return False;
5346
5347         return True;            
5348 }
5349
5350 /*******************************************************************
5351 ********************************************************************/  
5352
5353 BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5354 {
5355         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5356         depth++;
5357
5358         if (!prs_align(ps))
5359                 return False;
5360                 
5361         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5362                 return False;
5363         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5364                 return False;
5365                 
5366         if (!prs_align(ps))
5367                 return False;
5368                 
5369         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5370                 return False;
5371         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5372                 return False;
5373         
5374         if (!prs_align(ps))
5375                 return False;
5376                 
5377         if (!prs_uint32("level", ps, depth, &q_u->level))
5378                 return False;
5379                 
5380         if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer))
5381                 return False;
5382
5383         if (!prs_align(ps))
5384                 return False;
5385
5386         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5387                 return False;
5388
5389         return True;
5390 }
5391
5392 /*******************************************************************
5393  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5394 ********************************************************************/  
5395
5396 BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
5397 {
5398         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
5399         depth++;
5400
5401         if (!prs_align(ps))
5402                 return False;
5403                 
5404         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5405                 return False;
5406         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5407                 return False;
5408                 
5409         if (!prs_align(ps))
5410                 return False;
5411                                 
5412         if (!prs_uint32("level", ps, depth, &q_u->level))
5413                 return False;
5414                 
5415         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5416                 return False;
5417
5418         if (!prs_align(ps))
5419                 return False;
5420
5421         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5422                 return False;
5423
5424         return True;
5425 }
5426
5427 /*******************************************************************
5428 ********************************************************************/  
5429
5430 BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
5431 {               
5432         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
5433         depth++;
5434
5435         if (!prs_align(ps))
5436                 return False;
5437                 
5438         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5439                 return False;
5440
5441         if (!prs_align(ps))
5442                 return False;
5443                 
5444         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5445                 return False;
5446                 
5447         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5448                 return False;
5449                 
5450         if (!prs_werror("status", ps, depth, &r_u->status))
5451                 return False;
5452
5453         return True;            
5454 }
5455
5456 /*******************************************************************
5457 ********************************************************************/  
5458
5459 BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
5460 {       
5461         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
5462         depth++;
5463
5464         if(!prs_align(ps))
5465                 return False;
5466         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
5467                 return False;
5468
5469         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
5470                 return False;
5471
5472         if(!prs_align(ps))
5473                 return False;
5474
5475         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
5476                 return False;
5477
5478         if(!prs_uint32("type", ps, depth, &r_u->type))
5479                 return False;
5480
5481         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
5482                 return False;
5483         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
5484                 return False;
5485         if(!prs_align(ps))
5486                 return False;
5487
5488         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
5489                 return False;
5490         if(!prs_werror("status", ps, depth, &r_u->status))
5491                 return False;
5492
5493         return True;
5494 }
5495
5496 /*******************************************************************
5497 ********************************************************************/  
5498
5499 BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
5500 {
5501         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
5502         depth++;
5503
5504         if(!prs_align(ps))
5505                 return False;
5506         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5507                 return False;
5508         if(!prs_uint32("index", ps, depth, &q_u->index))
5509                 return False;
5510         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
5511                 return False;
5512         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
5513                 return False;
5514
5515         return True;
5516 }
5517
5518 /*******************************************************************
5519 ********************************************************************/  
5520
5521 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
5522                 const POLICY_HND *hnd,
5523                 uint32 idx, uint32 valuelen, uint32 datalen)
5524 {
5525         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5526         q_u->index=idx;
5527         q_u->valuesize=valuelen;
5528         q_u->datasize=datalen;
5529
5530         return True;
5531 }
5532
5533 /*******************************************************************
5534 ********************************************************************/  
5535
5536 BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5537 {
5538         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5539         depth++;
5540
5541         if(!prs_align(ps))
5542                 return False;
5543         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5544                 return False;
5545         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5546                 return False;
5547
5548         if(!prs_align(ps))
5549                 return False;
5550
5551         if(!prs_uint32("type", ps, depth, &q_u->type))
5552                 return False;
5553
5554         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5555                 return False;
5556
5557         switch (q_u->type)
5558         {
5559                 case 0x1:
5560                 case 0x3:
5561                 case 0x4:
5562                 case 0x7:
5563             if (q_u->max_len) {
5564                 if (UNMARSHALLING(ps))
5565                                 q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
5566                         if(q_u->data == NULL)
5567                                 return False;
5568                         if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
5569                                 return False;
5570             }
5571                         if(!prs_align(ps))
5572                                 return False;
5573                         break;
5574         }       
5575         
5576         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
5577                 return False;
5578
5579         return True;
5580 }
5581
5582 /*******************************************************************
5583 ********************************************************************/  
5584
5585 BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
5586 {
5587         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
5588         depth++;
5589
5590         if(!prs_align(ps))
5591                 return False;
5592         if(!prs_werror("status",     ps, depth, &r_u->status))
5593                 return False;
5594
5595         return True;
5596 }
5597
5598 /*******************************************************************
5599 ********************************************************************/  
5600
5601 BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
5602                                 uint32 type, const uint8 *data, uint32 len)
5603 {
5604         DEBUG(5,("converting a specific param struct\n"));
5605
5606         if (*param == NULL)
5607         {
5608                 *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
5609                 if(*param == NULL)
5610                         return False;
5611                 memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
5612                 DEBUGADD(6,("Allocated a new PARAM struct\n"));
5613         }
5614         unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
5615         (*param)->type = type;
5616         
5617         /* le champ data n'est pas NULL termine */
5618         /* on stocke donc la longueur */
5619         
5620         (*param)->data_len=len;
5621         
5622         if (len) {
5623                 (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
5624                 if((*param)->data == NULL)
5625                         return False;
5626                 memcpy((*param)->data, data, len);
5627         }
5628                 
5629         DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
5630         dump_data(10, (char *)(*param)->data, (*param)->data_len);
5631
5632         return True;
5633 }
5634
5635 /*******************************************************************
5636 ********************************************************************/  
5637
5638 static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
5639 {
5640         prs_debug(ps, depth, desc, "spoolss_io_addform");
5641         depth++;
5642         if(!prs_align(ps))
5643                 return False;
5644
5645         if (ptr!=0)
5646         {
5647                 if(!prs_uint32("flags",    ps, depth, &f->flags))
5648                         return False;
5649                 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
5650                         return False;
5651                 if(!prs_uint32("size_x",   ps, depth, &f->size_x))
5652                         return False;
5653                 if(!prs_uint32("size_y",   ps, depth, &f->size_y))
5654                         return False;
5655                 if(!prs_uint32("left",     ps, depth, &f->left))
5656                         return False;
5657                 if(!prs_uint32("top",      ps, depth, &f->top))
5658                         return False;
5659                 if(!prs_uint32("right",    ps, depth, &f->right))
5660                         return False;
5661                 if(!prs_uint32("bottom",   ps, depth, &f->bottom))
5662                         return False;
5663
5664                 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
5665                         return False;
5666         }
5667
5668         return True;
5669 }
5670
5671 /*******************************************************************
5672 ********************************************************************/  
5673
5674 BOOL spoolss_io_q_deleteform(char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
5675 {
5676         prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
5677         depth++;
5678
5679         if(!prs_align(ps))
5680                 return False;
5681         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5682                 return False;
5683         if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
5684                 return False;
5685
5686         return True;
5687 }
5688
5689 /*******************************************************************
5690 ********************************************************************/  
5691
5692 BOOL spoolss_io_r_deleteform(char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
5693 {
5694         prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
5695         depth++;
5696
5697         if(!prs_align(ps))
5698                 return False;
5699         if(!prs_werror("status",        ps, depth, &r_u->status))
5700                 return False;
5701
5702         return True;
5703 }
5704
5705 /*******************************************************************
5706 ********************************************************************/  
5707
5708 BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
5709 {
5710         uint32 useless_ptr=0;
5711         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
5712         depth++;
5713
5714         if(!prs_align(ps))
5715                 return False;
5716         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5717                 return False;
5718         if(!prs_uint32("level",  ps, depth, &q_u->level))
5719                 return False;
5720         if(!prs_uint32("level2", ps, depth, &q_u->level2))
5721                 return False;
5722
5723         if (q_u->level==1)
5724         {
5725                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
5726                         return False;
5727                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
5728                         return False;
5729         }
5730
5731         return True;
5732 }
5733
5734 /*******************************************************************
5735 ********************************************************************/  
5736
5737 BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
5738 {
5739         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
5740         depth++;
5741
5742         if(!prs_align(ps))
5743                 return False;
5744         if(!prs_werror("status",        ps, depth, &r_u->status))
5745                 return False;
5746
5747         return True;
5748 }
5749
5750 /*******************************************************************
5751 ********************************************************************/  
5752
5753 BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
5754 {
5755         uint32 useless_ptr=0;
5756         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
5757         depth++;
5758
5759         if(!prs_align(ps))
5760                 return False;
5761         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5762                 return False;
5763         if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
5764                 return False;
5765               
5766         if(!prs_align(ps))
5767                 return False;
5768         
5769         if(!prs_uint32("level",  ps, depth, &q_u->level))
5770                 return False;
5771         if(!prs_uint32("level2", ps, depth, &q_u->level2))
5772                 return False;
5773
5774         if (q_u->level==1)
5775         {
5776                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
5777                         return False;
5778                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
5779                         return False;
5780         }
5781
5782         return True;
5783 }
5784
5785 /*******************************************************************
5786 ********************************************************************/  
5787
5788 BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
5789 {
5790         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
5791         depth++;
5792
5793         if(!prs_align(ps))
5794                 return False;
5795         if(!prs_werror("status",        ps, depth, &r_u->status))
5796                 return False;
5797
5798         return True;
5799 }
5800
5801 /*******************************************************************
5802  Parse a SPOOL_R_GETJOB structure.
5803 ********************************************************************/  
5804
5805 BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
5806 {               
5807         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
5808         depth++;
5809
5810         if (!prs_align(ps))
5811                 return False;
5812                 
5813         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5814                 return False;
5815
5816         if (!prs_align(ps))
5817                 return False;
5818                 
5819         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5820                 return False;
5821                 
5822         if (!prs_werror("status", ps, depth, &r_u->status))
5823                 return False;
5824
5825         return True;            
5826 }
5827
5828 /*******************************************************************
5829  Parse a SPOOL_Q_GETJOB structure.
5830 ********************************************************************/  
5831
5832 BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
5833 {
5834         prs_debug(ps, depth, desc, "");
5835         depth++;
5836
5837         if(!prs_align(ps))
5838                 return False;
5839
5840         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5841                 return False;
5842         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
5843                 return False;
5844         if(!prs_uint32("level", ps, depth, &q_u->level))
5845                 return False;
5846         
5847         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5848                 return False;
5849
5850         if(!prs_align(ps))
5851                 return False;
5852         
5853         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5854                 return False;
5855
5856         return True;
5857 }
5858
5859 void free_devmode(DEVICEMODE *devmode)
5860 {
5861         if (devmode!=NULL) {
5862                 safe_free(devmode->private);
5863                 safe_free(devmode);
5864         }
5865 }
5866
5867 void free_printer_info_1(PRINTER_INFO_1 *printer)
5868 {
5869         safe_free(printer);
5870 }
5871
5872 void free_printer_info_2(PRINTER_INFO_2 *printer)
5873 {
5874         if (printer!=NULL) {
5875                 free_devmode(printer->devmode);
5876                 printer->devmode = NULL;
5877                 safe_free(printer);
5878         }
5879 }
5880
5881 void free_printer_info_3(PRINTER_INFO_3 *printer)
5882 {
5883         if (printer!=NULL) {
5884                 safe_free(printer);
5885         }
5886 }
5887
5888 void free_job_info_2(JOB_INFO_2 *job)
5889 {
5890     if (job!=NULL)
5891         free_devmode(job->devmode);
5892 }
5893
5894 /*******************************************************************
5895  * init a structure.
5896  ********************************************************************/
5897
5898 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
5899                                const fstring string, uint32 printer, uint32 type)
5900 {      
5901         if (q_u == NULL)
5902                 return False;
5903
5904         init_unistr2(&q_u->string, string, strlen(string)+1);
5905
5906         q_u->printer=printer;
5907         q_u->type=type;
5908
5909         q_u->unknown0=0x0;
5910         q_u->unknown1=0x0;
5911
5912         return True;
5913 }
5914
5915 /*******************************************************************
5916  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
5917 ********************************************************************/  
5918
5919 BOOL spoolss_io_q_replyopenprinter(char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
5920 {
5921         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
5922         depth++;
5923
5924         if(!prs_align(ps))
5925                 return False;
5926
5927         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
5928                 return False;
5929
5930         if(!prs_align(ps))
5931                 return False;
5932
5933         if(!prs_uint32("printer", ps, depth, &q_u->printer))
5934                 return False;
5935         if(!prs_uint32("type", ps, depth, &q_u->type))
5936                 return False;
5937         
5938         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
5939                 return False;
5940         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
5941                 return False;
5942
5943         return True;
5944 }
5945
5946 /*******************************************************************
5947  Parse a SPOOL_R_REPLYOPENPRINTER structure.
5948 ********************************************************************/  
5949
5950 BOOL spoolss_io_r_replyopenprinter(char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
5951 {               
5952         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
5953         depth++;
5954
5955         if (!prs_align(ps))
5956                 return False;
5957
5958         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
5959                 return False;
5960
5961         if (!prs_werror("status", ps, depth, &r_u->status))
5962                 return False;
5963
5964         return True;            
5965 }
5966
5967 /*******************************************************************
5968  * init a structure.
5969  ********************************************************************/
5970
5971 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
5972 {      
5973         if (q_u == NULL)
5974                 return False;
5975
5976         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5977
5978         return True;
5979 }
5980
5981 /*******************************************************************
5982  Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
5983 ********************************************************************/  
5984
5985 BOOL spoolss_io_q_replycloseprinter(char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
5986 {
5987         prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
5988         depth++;
5989
5990         if(!prs_align(ps))
5991                 return False;
5992
5993         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5994                 return False;
5995
5996         return True;
5997 }
5998
5999 /*******************************************************************
6000  Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6001 ********************************************************************/  
6002
6003 BOOL spoolss_io_r_replycloseprinter(char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6004 {               
6005         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6006         depth++;
6007
6008         if (!prs_align(ps))
6009                 return False;
6010
6011         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6012                 return False;
6013
6014         if (!prs_werror("status", ps, depth, &r_u->status))
6015                 return False;
6016
6017         return True;            
6018 }
6019
6020 /*******************************************************************
6021  * init a structure.
6022  ********************************************************************/
6023
6024 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6025                                 uint32 change_low, uint32 change_high)
6026 {      
6027         if (q_u == NULL)
6028                 return False;
6029
6030         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6031
6032         q_u->change_low=change_low;
6033         q_u->change_high=change_high;
6034
6035         q_u->unknown0=0x0;
6036         q_u->unknown1=0x0;
6037
6038         q_u->info_ptr=1;
6039
6040         q_u->info.version=2;
6041         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6042         q_u->info.count=0;
6043
6044         return True;
6045 }
6046
6047 /*******************************************************************
6048  Parse a SPOOL_Q_REPLY_RRPCN structure.
6049 ********************************************************************/  
6050
6051 BOOL spoolss_io_q_reply_rrpcn(char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6052 {
6053         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6054         depth++;
6055
6056         if(!prs_align(ps))
6057                 return False;
6058
6059         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6060                 return False;
6061
6062         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6063                 return False;
6064
6065         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6066                 return False;
6067
6068         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6069                 return False;
6070
6071         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6072                 return False;
6073
6074         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6075                 return False;
6076
6077         if(q_u->info_ptr!=0)
6078                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6079                         return False;
6080                 
6081         return True;
6082 }
6083
6084 /*******************************************************************
6085  Parse a SPOOL_R_REPLY_RRPCN structure.
6086 ********************************************************************/  
6087
6088 BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6089 {               
6090         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6091         depth++;
6092
6093         if (!prs_align(ps))
6094                 return False;
6095
6096         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6097                 return False;
6098
6099         if (!prs_werror("status", ps, depth, &r_u->status))
6100                 return False;
6101
6102         return True;            
6103 }