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