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