5f1f10521fc1eb8c9c60943db563e1a684aec92a
[kai/samba.git] / source / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-2000,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
7  *  Copyright (C) Jean Fran├žois Micouleau      1998-2000.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24
25 #include "includes.h"
26
27 #ifdef TNG
28         #define prs_uint16 _prs_uint16
29         #define prs_uint32 _prs_uint32
30         #define prs_uint8s _prs_uint8s
31         #define prs_uint16s _prs_uint16s
32         #define prs_unistr _prs_unistr
33         #define init_unistr2 make_unistr2
34         #define init_buf_unistr2 make_buf_unistr2
35 #endif
36
37
38 extern int DEBUGLEVEL;
39 /*******************************************************************
40 return the length of a UNISTR string.
41 ********************************************************************/  
42 static uint32 str_len_uni(UNISTR *source)
43 {
44         uint32 i=0;
45         
46         while (source->buffer[i]!=0x0000)
47         {
48          i++;
49         }
50         return i;
51 }
52
53 /*******************************************************************
54 This should be moved in a more generic lib.
55 ********************************************************************/  
56 static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
57 {
58         if(!prs_uint16("year", ps, depth, &(systime->year)))
59                 return False;
60         if(!prs_uint16("month", ps, depth, &(systime->month)))
61                 return False;
62         if(!prs_uint16("dayofweek", ps, depth, &(systime->dayofweek)))
63                 return False;
64         if(!prs_uint16("day", ps, depth, &(systime->day)))
65                 return False;
66         if(!prs_uint16("hour", ps, depth, &(systime->hour)))
67                 return False;
68         if(!prs_uint16("minute", ps, depth, &(systime->minute)))
69                 return False;
70         if(!prs_uint16("second", ps, depth, &(systime->second)))
71                 return False;
72         if(!prs_uint16("milliseconds", ps, depth, &(systime->milliseconds)))
73                 return False;
74
75         return True;
76 }
77
78 /*******************************************************************
79 ********************************************************************/  
80 BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
81 {
82         systime->year=unixtime->tm_year+1900;
83         systime->month=unixtime->tm_mon+1;
84         systime->dayofweek=unixtime->tm_wday;
85         systime->day=unixtime->tm_mday;
86         systime->hour=unixtime->tm_hour;
87         systime->minute=unixtime->tm_min;
88         systime->second=unixtime->tm_sec;
89         systime->milliseconds=0;
90
91         return True;
92 }
93
94 /*******************************************************************
95 reads or writes an DOC_INFO structure.
96 ********************************************************************/  
97 static BOOL smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
98 {
99         if (info_1 == NULL) return False;
100
101         prs_debug(ps, depth, desc, "smb_io_doc_info_1");
102         depth++;
103  
104         if(!prs_align(ps))
105                 return False;
106         
107         if(!prs_uint32("p_docname",    ps, depth, &(info_1->p_docname)))
108                 return False;
109         if(!prs_uint32("p_outputfile", ps, depth, &(info_1->p_outputfile)))
110                 return False;
111         if(!prs_uint32("p_datatype",   ps, depth, &(info_1->p_datatype)))
112                 return False;
113
114         if(!smb_io_unistr2("", &(info_1->docname),    info_1->p_docname,    ps, depth))
115                 return False;
116         if(!smb_io_unistr2("", &(info_1->outputfile), info_1->p_outputfile, ps, depth))
117                 return False;
118         if(!smb_io_unistr2("", &(info_1->datatype),   info_1->p_datatype,   ps, depth))
119                 return False;
120
121         return True;
122 }
123
124 /*******************************************************************
125 reads or writes an DOC_INFO structure.
126 ********************************************************************/  
127 static BOOL smb_io_doc_info(char *desc, DOC_INFO *info, prs_struct *ps, int depth)
128 {
129         uint32 useless_ptr=0;
130         
131         if (info == NULL) return False;
132
133         prs_debug(ps, depth, desc, "smb_io_doc_info");
134         depth++;
135  
136         if(!prs_align(ps))
137                 return False;
138         
139         if(!prs_uint32("switch_value", ps, depth, &(info->switch_value)))
140                 return False;
141         
142         if(!prs_uint32("doc_info_X ptr", ps, depth, &(useless_ptr)))
143                 return False;
144
145         switch (info->switch_value)
146         {
147                 case 1: 
148                         if(!smb_io_doc_info_1("",&(info->doc_info_1), ps, depth))
149                                 return False;
150                         break;
151                 case 2:
152                         /*
153                           this is just a placeholder
154                           
155                           MSDN July 1998 says doc_info_2 is only on
156                           Windows 95, and as Win95 doesn't do RPC to print
157                           this case is nearly impossible
158                           
159                           Maybe one day with Windows for dishwasher 2037 ...
160                           
161                         */
162                         /* smb_io_doc_info_2("",&(info->doc_info_2), ps, depth); */
163                         break;
164                 default:
165                         DEBUG(0,("Something is obviously wrong somewhere !\n"));
166                         break;
167         }
168
169         return True;
170 }
171
172 /*******************************************************************
173 reads or writes an DOC_INFO_CONTAINER structure.
174 ********************************************************************/  
175 static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
176 {
177         if (cont == NULL) return False;
178
179         prs_debug(ps, depth, desc, "smb_io_doc_info_container");
180         depth++;
181  
182         if(!prs_align(ps))
183                 return False;
184         
185         if(!prs_uint32("level", ps, depth, &(cont->level)))
186                 return False;
187         
188         if(!smb_io_doc_info("",&(cont->docinfo), ps, depth))
189                 return False;
190
191         return True;
192 }
193
194 /*******************************************************************
195 reads or writes an NOTIFY OPTION TYPE structure.
196 ********************************************************************/  
197 static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
198 {
199         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
200         depth++;
201  
202         if (!prs_align(ps))
203                 return False;
204
205         if(!prs_uint16("type", ps, depth, &type->type))
206                 return False;
207         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
208                 return False;
209         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
210                 return False;
211         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
212                 return False;
213         if(!prs_uint32("count", ps, depth, &type->count))
214                 return False;
215         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
216                 return False;
217
218         return True;
219 }
220
221 /*******************************************************************
222 reads or writes an NOTIFY OPTION TYPE DATA.
223 ********************************************************************/  
224 static BOOL smb_io_notify_option_type_data(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
225 {
226         int i;
227
228         prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
229         depth++;
230  
231         /* if there are no fields just return */
232         if (type->fields_ptr==0)
233                 return True;
234
235         if(!prs_align(ps))
236                 return False;
237
238         if(!prs_uint32("count2", ps, depth, &type->count2))
239                 return False;
240         
241         if (type->count2 != type->count)
242                 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
243
244         /* parse the option type data */
245         for(i=0;i<type->count2;i++)
246                 if(!prs_uint16("fields",ps,depth,&(type->fields[i])))
247                         return False;
248         return True;
249 }
250
251 /*******************************************************************
252 reads or writes an NOTIFY OPTION structure.
253 ********************************************************************/  
254 static BOOL smb_io_notify_option_type_ctr(char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
255 {               
256         int i;
257         
258         prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
259         depth++;
260  
261         if(!prs_uint32("count", ps, depth, &ctr->count))
262                 return False;
263
264         /* reading */
265         if (UNMARSHALLING(ps))
266                 if((ctr->type=(SPOOL_NOTIFY_OPTION_TYPE *)malloc(ctr->count*sizeof(SPOOL_NOTIFY_OPTION_TYPE))) == NULL)
267                         return False;
268                 
269         /* the option type struct */
270         for(i=0;i<ctr->count;i++)
271                 if(!smb_io_notify_option_type("", &(ctr->type[i]) , ps, depth))
272                         return False;
273
274         /* the type associated with the option type struct */
275         for(i=0;i<ctr->count;i++)
276                 if(!smb_io_notify_option_type_data("", &(ctr->type[i]) , ps, depth))
277                         return False;
278         
279         return True;
280 }
281
282 /*******************************************************************
283 reads or writes an NOTIFY OPTION structure.
284 ********************************************************************/  
285 static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
286 {
287         prs_debug(ps, depth, desc, "smb_io_notify_option");
288         depth++;
289         
290         if(!prs_uint32("version", ps, depth, &option->version))
291                 return False;
292         if(!prs_uint32("flags", ps, depth, &option->flags))
293                 return False;
294         if(!prs_uint32("count", ps, depth, &option->count))
295                 return False;
296         if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
297                 return False;
298         
299         /* marshalling or unmarshalling, that would work */     
300         if (option->option_type_ptr!=0) {
301                 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
302                         return False;
303         }
304         else {
305                 option->ctr.type=NULL;
306                 option->ctr.count=0;
307         }
308         
309         return True;
310 }
311
312 /*******************************************************************
313 reads or writes an NOTIFY INFO DATA structure.
314 ********************************************************************/  
315 static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
316 {
317         uint32 useless_ptr=0xADDE0FF0;
318
319         uint32 how_many_words;
320         BOOL isvalue;
321         uint32 x;
322         
323         prs_debug(ps, depth, desc, "smb_io_notify_info_data");
324         depth++;
325
326         how_many_words=data->size;      
327         if (how_many_words==POINTER)
328         {
329                 how_many_words=TWO_VALUE;
330         }
331         
332         isvalue=data->enc_type;
333
334         if(!prs_align(ps))
335                 return False;
336         if(!prs_uint16("type",           ps, depth, &(data->type)))
337                 return False;
338         if(!prs_uint16("field",          ps, depth, &(data->field)))
339                 return False;
340         /*prs_align(ps);*/
341
342         if(!prs_uint32("how many words", ps, depth, &how_many_words))
343                 return False;
344         if(!prs_uint32("id",             ps, depth, &(data->id)))
345                 return False;
346         if(!prs_uint32("how many words", ps, depth, &how_many_words))
347                 return False;
348         /*prs_align(ps);*/
349
350         if (isvalue==True)
351         {
352                 if(!prs_uint32("value[0]", ps, depth, &(data->notify_data.value[0])))
353                         return False;
354                 if(!prs_uint32("value[1]", ps, depth, &(data->notify_data.value[1])))
355                         return False;
356                 /*prs_align(ps);*/
357         }
358         else
359         {
360                 /* it's a string */
361                 /* length in ascii including \0 */
362                 x=2*(data->notify_data.data.length+1);
363                 if(!prs_uint32("string length", ps, depth, &x ))
364                         return False;
365                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
366                         return False;
367                 /*prs_align(ps);*/
368         }
369
370         return True;
371 }
372
373 /*******************************************************************
374 reads or writes an NOTIFY INFO DATA structure.
375 ********************************************************************/  
376 BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
377                                      prs_struct *ps, int depth)
378 {
379         uint32 x;
380         BOOL isvalue;
381         
382         prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
383         depth++;
384         
385         if(!prs_align(ps))
386                 return False;
387
388         isvalue=data->enc_type;
389
390         if (isvalue==False)
391         {
392                 /* length of string in unicode include \0 */
393                 x=data->notify_data.data.length+1;
394                 if(!prs_uint32("string length", ps, depth, &x ))
395                         return False;
396                 if(!prs_uint16s(True,"string",ps,depth,data->notify_data.data.string,x))
397                         return False;
398         }
399         if(!prs_align(ps))
400                 return False;
401
402         return True;
403 }
404
405 /*******************************************************************
406 reads or writes an NOTIFY INFO structure.
407 ********************************************************************/  
408 static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
409 {
410         int i;
411
412         prs_debug(ps, depth, desc, "smb_io_notify_info");
413         depth++;
414  
415         if(!prs_align(ps))
416                 return False;
417
418         if(!prs_uint32("count", ps, depth, &(info->count)))
419                 return False;
420         if(!prs_uint32("version", ps, depth, &(info->version)))
421                 return False;
422         if(!prs_uint32("flags", ps, depth, &(info->flags)))
423                 return False;
424         if(!prs_uint32("count", ps, depth, &(info->count)))
425                 return False;
426
427         for (i=0;i<info->count;i++)
428         {
429                 if(!smb_io_notify_info_data(desc, &(info->data[i]), ps, depth))
430                         return False;
431         }
432
433         /* now do the strings at the end of the stream */       
434         for (i=0;i<info->count;i++)
435         {
436                 if(!smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth))
437                         return False;
438         }
439
440         return True;
441 }
442
443
444 /*******************************************************************
445 ********************************************************************/  
446 static BOOL spool_io_user_level_1(char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
447 {
448         prs_debug(ps, depth, desc, "");
449         depth++;
450
451         /* reading */
452         if (ps->io)
453                 ZERO_STRUCTP(q_u);
454
455         if (!prs_align(ps))
456                 return False;
457         if (!prs_uint32("size", ps, depth, &(q_u->size)))
458                 return False;
459         if (!prs_uint32("client_name_ptr", ps, depth, &(q_u->client_name_ptr)))
460                 return False;
461         if (!prs_uint32("user_name_ptr", ps, depth, &(q_u->user_name_ptr)))
462                 return False;
463         if (!prs_uint32("build", ps, depth, &(q_u->build)))
464                 return False;
465         if (!prs_uint32("major", ps, depth, &(q_u->major)))
466                 return False;
467         if (!prs_uint32("minor", ps, depth, &(q_u->minor)))
468                 return False;
469         if (!prs_uint32("processor", ps, depth, &(q_u->processor)))
470                 return False;
471
472         if (!smb_io_unistr2("", &(q_u->client_name), q_u->client_name_ptr, ps, depth))
473                 return False;
474         if (!prs_align(ps))
475                 return False;
476         if (!smb_io_unistr2("", &(q_u->user_name),   q_u->user_name_ptr,   ps, depth))
477                 return False;
478
479         return True;
480 }
481
482 /*******************************************************************
483 ********************************************************************/  
484 static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
485 {
486         if (q_u==NULL)
487                 return False;
488
489         prs_debug(ps, depth, desc, "spool_io_user_level");
490         depth++;
491
492         if (!prs_align(ps))
493                 return False;
494         if (!prs_uint32("level", ps, depth, &q_u->level))
495                 return False;
496         if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
497                 return False;
498         
499         switch (q_u->level) {   
500         case 1:
501                 if (!spool_io_user_level_1("", &(q_u->user1), ps, depth))
502                         return False;
503                 break;
504         default:
505                 return False;   
506         }       
507
508         return True;
509 }
510
511 /*******************************************************************
512  * read or write a DEVICEMODE struct.
513  * on reading allocate memory for the private member
514  ********************************************************************/
515 static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
516 {
517         prs_debug(ps, depth, desc, "spoolss_io_devmode");
518         depth++;
519
520         if (!prs_uint16s(True,"devicename", ps, depth, devmode->devicename.buffer, 32))
521                 return False;
522         if (!prs_uint16("specversion",      ps, depth, &(devmode->specversion)))
523                 return False;
524         if (!prs_uint16("driverversion",    ps, depth, &(devmode->driverversion)))
525                 return False;
526         if (!prs_uint16("size",             ps, depth, &(devmode->size)))
527                 return False;
528         if (!prs_uint16("driverextra",      ps, depth, &(devmode->driverextra)))
529                 return False;
530         if (!prs_uint32("fields",           ps, depth, &(devmode->fields)))
531                 return False;
532         if (!prs_uint16("orientation",      ps, depth, &(devmode->orientation)))
533                 return False;
534         if (!prs_uint16("papersize",        ps, depth, &(devmode->papersize)))
535                 return False;
536         if (!prs_uint16("paperlength",      ps, depth, &(devmode->paperlength)))
537                 return False;
538         if (!prs_uint16("paperwidth",       ps, depth, &(devmode->paperwidth)))
539                 return False;
540         if (!prs_uint16("scale",            ps, depth, &(devmode->scale)))
541                 return False;
542         if (!prs_uint16("copies",           ps, depth, &(devmode->copies)))
543                 return False;
544         if (!prs_uint16("defaultsource",    ps, depth, &(devmode->defaultsource)))
545                 return False;
546         if (!prs_uint16("printquality",     ps, depth, &(devmode->printquality)))
547                 return False;
548         if (!prs_uint16("color",            ps, depth, &(devmode->color)))
549                 return False;
550         if (!prs_uint16("duplex",           ps, depth, &(devmode->duplex)))
551                 return False;
552         if (!prs_uint16("yresolution",      ps, depth, &(devmode->yresolution)))
553                 return False;
554         if (!prs_uint16("ttoption",         ps, depth, &(devmode->ttoption)))
555                 return False;
556         if (!prs_uint16("collate",          ps, depth, &(devmode->collate)))
557                 return False;
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         {
591                 if (UNMARSHALLING(ps)) {
592                         devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8));
593                         if(devmode->private == NULL)
594                                 return False;
595                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra)); 
596                 }
597                         
598                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
599                 if (!prs_uint8s(True, "private",  ps, depth, devmode->private, devmode->driverextra))
600                         return False;
601         }
602
603         return True;
604 }
605
606 /*******************************************************************
607  Read or write a DEVICEMODE container
608 ********************************************************************/  
609 static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
610 {
611         if (dm_c==NULL)
612                 return False;
613
614         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
615         depth++;
616
617         if(!prs_align(ps))
618                 return False;
619         
620         if (!prs_uint32("size", ps, depth, &dm_c->size))
621                 return False;
622
623         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
624                 return False;
625
626         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
627                 if (UNMARSHALLING(ps))
628                         /* if while reading there is no DEVMODE ... */
629                         dm_c->devmode=NULL;
630                 return True;
631         }
632         
633         /* so we have a DEVICEMODE to follow */         
634         if (UNMARSHALLING(ps)) {
635                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
636                 dm_c->devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
637                 if(dm_c->devmode == NULL)
638                         return False;
639                 ZERO_STRUCTP(dm_c->devmode);
640         }
641         
642         /* this is bad code, shouldn't be there */
643         if (!prs_uint32("size", ps, depth, &dm_c->size))
644                 return False;
645                 
646         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
647                 return False;
648
649         return True;
650 }
651
652 /*******************************************************************
653 ********************************************************************/  
654 static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
655 {
656         if (pd==NULL)
657                 return False;
658
659         prs_debug(ps, depth, desc, "spoolss_io_printer_default");
660         depth++;
661
662         if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
663                 return False;
664
665         if (!smb_io_unistr2("datatype", &(pd->datatype), pd->datatype_ptr, ps,depth))
666                 return False;
667         
668         if (!prs_align(ps))
669                 return False;
670
671         if (!spoolss_io_devmode_cont("", &(pd->devmode_cont), ps, depth))
672                 return False;
673
674         if (!prs_uint32("access_required", ps, depth, &pd->access_required))
675                 return False;
676
677         return True;
678 }
679
680 /*******************************************************************
681  * init a structure.
682  ********************************************************************/
683 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, 
684                                         uint32 access_required, fstring clientname, fstring user_name)
685 {
686         DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
687         q_u->printername_ptr = (printername!=NULL)?1:0;
688         init_unistr2(&(q_u->printername), printername, strlen(printername));
689
690         q_u->printer_default.datatype_ptr = 0;
691 /*
692         q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
693         init_unistr2(&(q_u->printer_default.datatype), datatype, strlen(datatype));
694 */
695         q_u->printer_default.devmode_cont.size=0;
696         q_u->printer_default.devmode_cont.devmode_ptr=0;
697         q_u->printer_default.devmode_cont.devmode=NULL;
698         q_u->printer_default.access_required=access_required;
699         q_u->user_switch=1;
700         q_u->user_ctr.level=1;
701         q_u->user_ctr.ptr=1;
702         q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+8;
703         q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
704         q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
705         q_u->user_ctr.user1.build=1381;
706         q_u->user_ctr.user1.major=2;
707         q_u->user_ctr.user1.minor=0;
708         q_u->user_ctr.user1.processor=0;
709         init_unistr2(&(q_u->user_ctr.user1.client_name), clientname, strlen(clientname));
710         init_unistr2(&(q_u->user_ctr.user1.user_name), user_name, strlen(user_name));
711         
712         return True;
713 }
714
715 /*******************************************************************
716  * read a structure.
717  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
718  ********************************************************************/
719 BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
720 {
721         if (q_u == NULL)
722                 return False;
723
724         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
725         depth++;
726
727         if (!prs_align(ps))
728                 return False;
729
730         if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
731                 return False;
732         if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
733                 return False;
734         
735         if (!prs_align(ps))
736                 return False;
737
738         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
739                 return False;
740                 
741         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
742                 return False;   
743         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
744                 return False;
745                 
746         return True;
747 }
748
749 /*******************************************************************
750  * write a structure.
751  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
752  * called from spoolss_open_printer_ex (cli_spoolss.c)
753  ********************************************************************/
754 BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
755 {
756         if (r_u == NULL) return False;
757
758         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
759         depth++;
760         
761         if (!prs_align(ps))
762                 return False;
763
764         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
765                 return False;
766
767         if (!prs_uint32("status code", ps, depth, &(r_u->status)))
768                 return False;
769
770         return True;
771 }
772 /*******************************************************************
773  * make a structure.
774  ********************************************************************/
775 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
776                                 POLICY_HND *handle,
777                                 char *valuename,
778                                 uint32 size)
779 {
780         int len_name = valuename != NULL ? strlen(valuename) : 0;
781
782         if (q_u == NULL) return False;
783
784         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
785
786         memcpy(&(q_u->handle), handle, sizeof(q_u->handle));
787         init_unistr2(&(q_u->valuename), valuename, len_name);
788         q_u->size = size;
789
790         return True;
791 }
792
793 /*******************************************************************
794  * read a structure.
795  * called from spoolss_q_getprinterdata (srv_spoolss.c)
796  ********************************************************************/
797 BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
798 {
799         if (q_u == NULL) return False;
800
801         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
802         depth++;
803
804         if (!prs_align(ps))
805                 return False;
806         if (!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
807                 return False;
808         if (!prs_align(ps))
809                 return False;
810         if (!smb_io_unistr2("valuename", &(q_u->valuename),True,ps,depth))
811                 return False;
812         if (!prs_align(ps))
813                 return False;
814         if (!prs_uint32("size", ps, depth, &(q_u->size)))
815                 return False;
816
817         return True;
818 }
819
820 /*******************************************************************
821  * write a structure.
822  * called from spoolss_r_getprinterdata (srv_spoolss.c)
823  ********************************************************************/
824 BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
825 {
826         if (r_u == NULL)
827                 return False;
828
829         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
830         depth++;
831
832         if (!prs_align(ps))
833                 return False;
834         if (!prs_uint32("type", ps, depth, &(r_u->type)))
835                 return False;
836         if (!prs_uint32("size", ps, depth, &(r_u->size)))
837                 return False;
838         
839         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
840                 return False;
841                 
842         if (!prs_align(ps))
843                 return False;
844         
845         if (!prs_uint32("needed", ps, depth, &(r_u->needed)))
846                 return False;
847         if (!prs_uint32("status", ps, depth, &(r_u->status)))
848                 return False;
849                 
850         return True;
851 }
852
853 /*******************************************************************
854  * make a structure.
855  ********************************************************************/
856 BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
857 {
858         if (q_u == NULL) return False;
859
860         DEBUG(5,("make_spoolss_q_closeprinter\n"));
861
862         memcpy(&(q_u->handle), hnd, sizeof(q_u->handle));
863
864         return True;
865 }
866
867 /*******************************************************************
868  * read a structure.
869  * called from static spoolss_q_closeprinter (srv_spoolss.c)
870  * called from spoolss_closeprinter (cli_spoolss.c)
871  ********************************************************************/
872 BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
873 {
874         if (q_u == NULL) return False;
875
876         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
877         depth++;
878
879         if (!prs_align(ps))
880                 return False;
881
882         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
883                 return False;
884
885         return True;
886 }
887
888 /*******************************************************************
889  * write a structure.
890  * called from static spoolss_r_closeprinter (srv_spoolss.c)
891  * called from spoolss_closeprinter (cli_spoolss.c)
892  ********************************************************************/
893 BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
894 {
895         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
896         depth++;
897         
898         if (!prs_align(ps))
899                 return False;
900
901         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
902                 return False;
903         if (!prs_uint32("status", ps, depth, &r_u->status))
904                 return False;
905         
906         return True;
907 }
908
909 /*******************************************************************
910  * read a structure.
911  * called from spoolss_q_startdocprinter (srv_spoolss.c)
912  ********************************************************************/
913 BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
914 {
915         if (q_u == NULL) return False;
916
917         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
918         depth++;
919
920         if(!prs_align(ps))
921                 return False;
922
923         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
924                 return False;
925         
926         if(!smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth))
927                 return False;
928
929         return True;
930 }
931
932 /*******************************************************************
933  * write a structure.
934  * called from spoolss_r_startdocprinter (srv_spoolss.c)
935  ********************************************************************/
936 BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
937 {
938         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
939         depth++;
940         if(!prs_uint32("jobid", ps, depth, &(r_u->jobid)))
941                 return False;
942         if(!prs_uint32("status", ps, depth, &(r_u->status)))
943                 return False;
944
945         return True;
946 }
947
948 /*******************************************************************
949  * read a structure.
950  * called from spoolss_q_enddocprinter (srv_spoolss.c)
951  ********************************************************************/
952 BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
953 {
954         if (q_u == NULL) return False;
955
956         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
957         depth++;
958
959         if(!prs_align(ps))
960                 return False;
961
962         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
963                 return False;
964
965         return True;
966 }
967
968 /*******************************************************************
969  * write a structure.
970  * called from spoolss_r_enddocprinter (srv_spoolss.c)
971  ********************************************************************/
972 BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
973 {
974         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
975         depth++;
976         if(!prs_uint32("status", ps, depth, &(r_u->status)))
977                 return False;
978
979         return True;
980 }
981
982 /*******************************************************************
983  * read a structure.
984  * called from spoolss_q_startpageprinter (srv_spoolss.c)
985  ********************************************************************/
986 BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
987 {
988         if (q_u == NULL) return False;
989
990         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
991         depth++;
992
993         if(!prs_align(ps))
994                 return False;
995
996         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
997                 return False;
998
999         return True;
1000 }
1001
1002 /*******************************************************************
1003  * write a structure.
1004  * called from spoolss_r_startpageprinter (srv_spoolss.c)
1005  ********************************************************************/
1006 BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1007 {
1008         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1009         depth++;
1010         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1011                 return False;
1012
1013         return True;
1014 }
1015
1016 /*******************************************************************
1017  * read a structure.
1018  * called from spoolss_q_endpageprinter (srv_spoolss.c)
1019  ********************************************************************/
1020 BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1021 {
1022         if (q_u == NULL) return False;
1023
1024         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1025         depth++;
1026
1027         if(!prs_align(ps))
1028                 return False;
1029
1030         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
1031                 return False;
1032
1033         return True;
1034 }
1035
1036 /*******************************************************************
1037  * write a structure.
1038  * called from spoolss_r_endpageprinter (srv_spoolss.c)
1039  ********************************************************************/
1040 BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1041 {
1042         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1043         depth++;
1044         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1045                 return False;
1046
1047         return True;
1048 }
1049
1050 /*******************************************************************
1051  * read a structure.
1052  * called from spoolss_q_writeprinter (srv_spoolss.c)
1053  ********************************************************************/
1054 BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1055 {
1056         if (q_u == NULL) return False;
1057
1058         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1059         depth++;
1060
1061         if(!prs_align(ps))
1062                 return False;
1063
1064         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
1065                 return False;
1066         if(!prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size)))
1067                 return False;
1068         
1069         if (q_u->buffer_size!=0)
1070         {
1071                 q_u->buffer=(uint8 *)malloc(q_u->buffer_size*sizeof(uint8));
1072                 if(q_u->buffer == NULL)
1073                         return False;   
1074                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1075                         return False;
1076         }
1077         if(!prs_align(ps))
1078                 return False;
1079         if(!prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2)))
1080                 return False;
1081
1082         return True;
1083 }
1084
1085 /*******************************************************************
1086  * write a structure.
1087  * called from spoolss_r_writeprinter (srv_spoolss.c)
1088  ********************************************************************/
1089 BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1090 {
1091         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1092         depth++;
1093         if(!prs_uint32("buffer_written", ps, depth, &(r_u->buffer_written)))
1094                 return False;
1095         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1096                 return False;
1097
1098         return True;
1099 }
1100
1101 /*******************************************************************
1102  * read a structure.
1103  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1104  ********************************************************************/
1105 BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1106 {
1107         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1108         depth++;
1109
1110         if(!prs_align(ps))
1111                 return False;
1112
1113         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1114                 return False;
1115         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1116                 return False;
1117         if(!prs_uint32("options", ps, depth, &q_u->options))
1118                 return False;
1119         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1120                 return False;
1121         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1122                 return False;
1123
1124         if(!prs_align(ps))
1125                 return False;
1126                 
1127         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1128                 return False;
1129
1130         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1131                 return False;
1132         
1133         if (q_u->option_ptr!=0) {
1134         
1135                 if (UNMARSHALLING(ps))
1136                         if((q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1137                                 return False;
1138         
1139                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1140                         return False;
1141         }
1142         
1143         return True;
1144 }
1145
1146 /*******************************************************************
1147  * write a structure.
1148  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1149  ********************************************************************/
1150 BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1151 {
1152         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1153         depth++;
1154
1155         if(!prs_uint32("status", ps, depth, &r_u->status))
1156                 return False;
1157
1158         return True;
1159 }
1160
1161 /*******************************************************************
1162  * read a structure.
1163  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1164  ********************************************************************/
1165 BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1166 {
1167         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1168         depth++;
1169
1170         if(!prs_align(ps))
1171                 return False;
1172
1173         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1174                 return False;
1175
1176         if(!prs_uint32("change", ps, depth, &q_u->change))
1177                 return False;
1178         
1179         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1180                 return False;
1181         
1182         if (q_u->option_ptr!=0) {
1183         
1184                 if (UNMARSHALLING(ps))
1185                         if((q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1186                                 return False;
1187         
1188                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1189                         return False;
1190         }
1191
1192         return True;
1193 }
1194
1195 /*******************************************************************
1196  * write a structure.
1197  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1198  ********************************************************************/
1199 BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1200 {
1201         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1202         depth++;
1203
1204         if(!prs_align(ps))
1205                 return False;
1206                 
1207         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1208                 return False;
1209
1210         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1211                 return False;
1212         
1213         if(!prs_align(ps))
1214                 return False;
1215         if(!prs_uint32("status", ps, depth, &r_u->status))
1216                 return False;
1217
1218         return True;
1219 }
1220
1221 /*******************************************************************
1222  * return the length of a uint16 (obvious, but the code is clean)
1223  ********************************************************************/
1224 static uint32 size_of_uint16(uint16 *value)
1225 {
1226         return (sizeof(*value));
1227 }
1228
1229 /*******************************************************************
1230  * return the length of a uint32 (obvious, but the code is clean)
1231  ********************************************************************/
1232 static uint32 size_of_uint32(uint32 *value)
1233 {
1234         return (sizeof(*value));
1235 }
1236 /*******************************************************************
1237  * return the length of a UNICODE string in number of char, includes:
1238  * - the leading zero
1239  * - the relative pointer size
1240  ********************************************************************/
1241 static uint32 size_of_relative_string(UNISTR *string)
1242 {
1243         uint32 size=0;
1244         
1245         size=str_len_uni(string);       /* the string length       */
1246         size=size+1;                    /* add the leading zero    */
1247         size=size*2;                    /* convert in char         */
1248         size=size+4;                    /* add the size of the ptr */   
1249
1250         return size;
1251 }
1252
1253 /*******************************************************************
1254  * return the length of a uint32 (obvious, but the code is clean)
1255  ********************************************************************/
1256 static uint32 size_of_device_mode(DEVICEMODE *devmode)
1257 {
1258         if (devmode==NULL)
1259                 return (4);
1260         else 
1261                 return (4+devmode->size+devmode->driverextra);
1262 }
1263
1264 /*******************************************************************
1265  * return the length of a uint32 (obvious, but the code is clean)
1266  ********************************************************************/
1267 static uint32 size_of_systemtime(SYSTEMTIME *systime)
1268 {
1269         if (systime==NULL)
1270                 return (4);
1271         else 
1272                 return (sizeof(SYSTEMTIME) +4);
1273 }
1274
1275 /*******************************************************************
1276  * write a UNICODE string.
1277  * used by all the RPC structs passing a buffer
1278  ********************************************************************/
1279 static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
1280 {
1281         if (uni == NULL)
1282                 return False;
1283
1284         prs_debug(ps, depth, desc, "spoolss_smb_io_unistr");
1285         depth++;
1286         if (!prs_unistr("unistr", ps, depth, uni))
1287                 return False;
1288
1289         return True;
1290 }
1291
1292
1293 /*******************************************************************
1294  * write a UNICODE string and its relative pointer.
1295  * used by all the RPC structs passing a buffer
1296  *
1297  * As I'm a nice guy, I'm forcing myself to explain this code.
1298  * MS did a good job in the overall spoolss code except in some
1299  * functions where they are passing the API buffer directly in the
1300  * RPC request/reply. That's to maintain compatiility at the API level.
1301  * They could have done it the good way the first time.
1302  *
1303  * So what happen is: the strings are written at the buffer's end, 
1304  * in the reverse order of the original structure. Some pointers to
1305  * the strings are also in the buffer. Those are relative to the
1306  * buffer's start.
1307  *
1308  * If you don't understand or want to change that function,
1309  * first get in touch with me: jfm@samba.org
1310  *
1311  ********************************************************************/
1312 static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
1313 {
1314         prs_struct *ps=&(buffer->prs);
1315         
1316         if (MARSHALLING(ps)) {
1317                 uint32 struct_offset = prs_offset(ps);
1318                 uint32 relative_offset;
1319                 
1320                 buffer->string_at_end -= 2*(str_len_uni(string)+1);
1321                 prs_set_offset(ps, buffer->string_at_end);
1322                 
1323                 /* write the string */
1324                 if (!spoolss_smb_io_unistr(desc, string, ps, depth))
1325                         return False;
1326
1327                 prs_set_offset(ps, struct_offset);
1328                 
1329                 relative_offset=buffer->string_at_end - buffer->struct_start;
1330                 /* write its offset */
1331                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1332                         return False;
1333         }
1334         else {
1335                 uint32 old_offset;
1336                 
1337                 /* read the offset */
1338                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1339                         return False;
1340
1341                 old_offset = prs_offset(ps);
1342                 prs_set_offset(ps, buffer->string_at_end+buffer->struct_start);
1343
1344                 /* read the string */
1345                 if (!spoolss_smb_io_unistr(desc, string, ps, depth))
1346                         return False;
1347
1348                 prs_set_offset(ps, old_offset);
1349         }
1350         return True;
1351 }
1352
1353
1354 /*******************************************************************
1355  * write a array of UNICODE strings and its relative pointer.
1356  * used by 2 RPC structs
1357  ********************************************************************/
1358 static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
1359 {
1360         UNISTR chaine;
1361         
1362         prs_struct *ps=&(buffer->prs);
1363         
1364         if (MARSHALLING(ps)) {
1365                 uint32 struct_offset = prs_offset(ps);
1366                 uint32 relative_offset;
1367                 uint16 *p;
1368                 uint16 *q;
1369                 uint16 zero=0;
1370                 p=*string;
1371                 q=*string;
1372                 
1373                 /* first write the last 0 */
1374                 buffer->string_at_end -= 2;
1375                 prs_set_offset(ps, buffer->string_at_end);
1376
1377                 if(!prs_uint16("leading zero", ps, depth, &zero))
1378                         return False;
1379
1380                 do
1381                 {       
1382                         while (*q!=0)
1383                                 q++;
1384
1385                         memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
1386
1387                         buffer->string_at_end -= (q-p+1)*sizeof(uint16);
1388
1389                         prs_set_offset(ps, buffer->string_at_end);
1390
1391                         /* write the string */
1392                         if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
1393                                 return False;
1394                         q++;
1395                         p=q;
1396
1397                 } while (*p!=0); /* end on the last leading 0 */
1398                 
1399                 prs_set_offset(ps, struct_offset);
1400                 
1401                 relative_offset=buffer->string_at_end - buffer->struct_start;
1402                 /* write its offset */
1403                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1404                         return False;
1405         }
1406         else {
1407                 uint32 old_offset;
1408                 uint16 *chaine2=NULL;
1409                 int l_chaine=0;
1410                 int l_chaine2=0;
1411                 
1412                 *string=NULL;
1413                                 
1414                 /* read the offset */
1415                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1416                         return False;
1417
1418                 old_offset = prs_offset(ps);
1419                 prs_set_offset(ps, buffer->string_at_end + buffer->struct_start);
1420         
1421                 do {
1422                         if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
1423                                 return False;
1424                         
1425                         l_chaine=str_len_uni(&chaine);
1426                         if((chaine2=(uint16 *)Realloc(chaine2, (l_chaine2+l_chaine+1)*sizeof(uint16))) == NULL)
1427                                 return False;
1428                         memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
1429                         l_chaine2+=l_chaine+1;
1430                 
1431                 } while(l_chaine!=0);
1432                 
1433                 *string=chaine2;
1434
1435                 prs_set_offset(ps, old_offset);
1436         }
1437         return True;
1438 }
1439
1440
1441 /*******************************************************************
1442  Parse a DEVMODE structure and its relative pointer.
1443 ********************************************************************/
1444 static BOOL new_smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
1445 {
1446         prs_struct *ps=&(buffer->prs);
1447
1448         prs_debug(ps, depth, desc, "new_smb_io_reldevmode");
1449         depth++;
1450
1451         if (MARSHALLING(ps)) {
1452                 uint32 struct_offset = prs_offset(ps);
1453                 uint32 relative_offset;
1454                 
1455                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
1456                 
1457                 prs_set_offset(ps, buffer->string_at_end);
1458                 
1459                 /* write the DEVMODE */
1460                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1461                         return False;
1462
1463                 prs_set_offset(ps, struct_offset);
1464                 
1465                 relative_offset=buffer->string_at_end - buffer->struct_start;
1466                 /* write its offset */
1467                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1468                         return False;
1469         }
1470         else {
1471                 uint32 old_offset;
1472                 
1473                 /* read the offset */
1474                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1475                         return False;
1476
1477                 old_offset = prs_offset(ps);
1478                 prs_set_offset(ps, buffer->string_at_end + buffer->struct_start);
1479
1480                 /* read the string */
1481                 if((*devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL)
1482                         return False;
1483                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1484                         return False;
1485
1486                 prs_set_offset(ps, old_offset);
1487         }
1488         return True;
1489 }
1490
1491
1492 /*******************************************************************
1493  Parse a PRINTER_INFO_0 structure.
1494 ********************************************************************/  
1495 BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
1496 {
1497         prs_struct *ps=&(buffer->prs);
1498
1499         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
1500         depth++;        
1501         
1502         buffer->struct_start=prs_offset(ps);
1503
1504         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1505                 return False;
1506         if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
1507                 return False;
1508         
1509         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
1510                 return False;
1511         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
1512                 return False;
1513         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
1514                 return False;
1515
1516         if(!prs_uint16("year", ps, depth, &info->year))
1517                 return False;
1518         if(!prs_uint16("month", ps, depth, &info->month))
1519                 return False;
1520         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
1521                 return False;
1522         if(!prs_uint16("day", ps, depth, &info->day))
1523                 return False;
1524         if(!prs_uint16("hour", ps, depth, &info->hour))
1525                 return False;
1526         if(!prs_uint16("minute", ps, depth, &info->minute))
1527                 return False;
1528         if(!prs_uint16("second", ps, depth, &info->second))
1529                 return False;
1530         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
1531                 return False;
1532
1533         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
1534                 return False;
1535         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
1536                 return False;
1537
1538         if(!prs_uint16("major_version", ps, depth, &info->major_version))
1539                 return False;
1540         if(!prs_uint16("build_version", ps, depth, &info->build_version))
1541                 return False;
1542         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
1543                 return False;
1544         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
1545                 return False;
1546         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
1547                 return False;
1548         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
1549                 return False;
1550         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
1551                 return False;
1552         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
1553                 return False;
1554         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
1555                 return False;
1556         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
1557                 return False;
1558         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
1559                 return False;
1560         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
1561                 return False;
1562         if(!prs_uint32("change_id", ps, depth, &info->change_id))
1563                 return False;
1564         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
1565                 return False;
1566         if(!prs_uint32("status"   , ps, depth, &info->status))
1567                 return False;
1568         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
1569                 return False;
1570         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
1571                 return False;
1572         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
1573                 return False;
1574         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
1575                 return False;
1576         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
1577                 return False;
1578         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
1579                 return False;
1580         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
1581                 return False;
1582         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
1583                 return False;
1584         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
1585                 return False;
1586         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
1587                 return False;
1588
1589         return True;
1590 }
1591
1592 /*******************************************************************
1593  Parse a PRINTER_INFO_1 structure.
1594 ********************************************************************/  
1595 BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
1596 {
1597         prs_struct *ps=&(buffer->prs);
1598
1599         prs_debug(ps, depth, desc, "new_smb_io_printer_info_1");
1600         depth++;        
1601         
1602         buffer->struct_start=prs_offset(ps);
1603
1604         if (!prs_uint32("flags", ps, depth, &info->flags))
1605                 return False;
1606         if (!new_smb_io_relstr("description", buffer, depth, &info->description))
1607                 return False;
1608         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1609                 return False;
1610         if (!new_smb_io_relstr("comment", buffer, depth, &info->comment))
1611                 return False;   
1612
1613         return True;
1614 }
1615
1616 /*******************************************************************
1617  Parse a PRINTER_INFO_2 structure.
1618 ********************************************************************/  
1619 BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
1620 {
1621         /* hack for the SEC DESC */
1622         uint32 pipo=0;
1623
1624         prs_struct *ps=&(buffer->prs);
1625
1626         prs_debug(ps, depth, desc, "new_smb_io_printer_info_2");
1627         depth++;        
1628         
1629         buffer->struct_start=prs_offset(ps);
1630         
1631         if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
1632                 return False;
1633         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1634                 return False;
1635         if (!new_smb_io_relstr("sharename", buffer, depth, &info->sharename))
1636                 return False;
1637         if (!new_smb_io_relstr("portname", buffer, depth, &info->portname))
1638                 return False;
1639         if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername))
1640                 return False;
1641         if (!new_smb_io_relstr("comment", buffer, depth, &info->comment))
1642                 return False;
1643         if (!new_smb_io_relstr("location", buffer, depth, &info->location))
1644                 return False;
1645
1646         /* NT parses the DEVMODE at the end of the struct */
1647         if (!new_smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1648                 return False;
1649         
1650         if (!new_smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
1651                 return False;
1652         if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1653                 return False;
1654         if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
1655                 return False;
1656         if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
1657                 return False;
1658
1659         if (!prs_uint32("security descriptor", ps, depth, &pipo))
1660                 return False;
1661         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1662                 return False;
1663         if (!prs_uint32("priority", ps, depth, &info->priority))
1664                 return False;
1665         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
1666                 return False;
1667         if (!prs_uint32("starttime", ps, depth, &info->starttime))
1668                 return False;
1669         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
1670                 return False;
1671         if (!prs_uint32("status", ps, depth, &info->status))
1672                 return False;
1673         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
1674                 return False;
1675         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
1676                 return False;
1677
1678         return True;
1679 }
1680
1681 /*******************************************************************
1682  Parse a DRIVER_INFO_1 structure.
1683 ********************************************************************/
1684 BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
1685 {
1686         prs_struct *ps=&(buffer->prs);
1687
1688         prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_1");
1689         depth++;        
1690         
1691         buffer->struct_start=prs_offset(ps);
1692
1693         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1694                 return False;
1695
1696         return True;
1697 }
1698
1699
1700 /*******************************************************************
1701  Parse a DRIVER_INFO_2 structure.
1702 ********************************************************************/
1703 BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
1704 {
1705         prs_struct *ps=&(buffer->prs);
1706
1707         prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_2");
1708         depth++;        
1709         
1710         buffer->struct_start=prs_offset(ps);
1711
1712         if (!prs_uint32("version", ps, depth, &info->version))
1713                 return False;
1714         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1715                 return False;
1716         if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
1717                 return False;
1718         if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1719                 return False;
1720         if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
1721                 return False;
1722         if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
1723                 return False;
1724
1725         return True;
1726 }
1727
1728
1729 /*******************************************************************
1730  Parse a DRIVER_INFO_3 structure.
1731 ********************************************************************/
1732 BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
1733 {
1734         prs_struct *ps=&(buffer->prs);
1735
1736         prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_3");
1737         depth++;        
1738         
1739         buffer->struct_start=prs_offset(ps);
1740
1741         if (!prs_uint32("version", ps, depth, &info->version))
1742                 return False;
1743         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1744                 return False;
1745         if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
1746                 return False;
1747         if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1748                 return False;
1749         if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
1750                 return False;
1751         if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
1752                 return False;
1753         if (!new_smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1754                 return False;
1755
1756         if (!new_smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1757                 return False;
1758
1759         if (!new_smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1760                 return False;
1761         if (!new_smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1762                 return False;
1763
1764         return True;
1765 }
1766
1767
1768 /*******************************************************************
1769  Parse a JOB_INFO_1 structure.
1770 ********************************************************************/  
1771 BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
1772 {
1773         prs_struct *ps=&(buffer->prs);
1774
1775         prs_debug(ps, depth, desc, "new_smb_io_job_info_1");
1776         depth++;        
1777         
1778         buffer->struct_start=prs_offset(ps);
1779
1780         if (!prs_uint32("jobid", ps, depth, &info->jobid))
1781                 return False;
1782         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1783                 return False;
1784         if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename))
1785                 return False;
1786         if (!new_smb_io_relstr("username", buffer, depth, &info->username))
1787                 return False;
1788         if (!new_smb_io_relstr("document", buffer, depth, &info->document))
1789                 return False;
1790         if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
1791                 return False;
1792         if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status))
1793                 return False;
1794         if (!prs_uint32("status", ps, depth, &info->status))
1795                 return False;
1796         if (!prs_uint32("priority", ps, depth, &info->priority))
1797                 return False;
1798         if (!prs_uint32("position", ps, depth, &info->position))
1799                 return False;
1800         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
1801                 return False;
1802         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
1803                 return False;
1804         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
1805                 return False;
1806
1807         return True;
1808 }
1809
1810 /*******************************************************************
1811  Parse a JOB_INFO_2 structure.
1812 ********************************************************************/  
1813 BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
1814 {       
1815         int pipo=0;
1816         prs_struct *ps=&(buffer->prs);
1817         
1818         prs_debug(ps, depth, desc, "new_smb_io_job_info_2");
1819         depth++;        
1820
1821         buffer->struct_start=prs_offset(ps);
1822         
1823         if (!prs_uint32("jobid",ps, depth, &info->jobid))
1824                 return False;
1825         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1826                 return False;
1827         if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename))
1828                 return False;
1829         if (!new_smb_io_relstr("username", buffer, depth, &info->username))
1830                 return False;
1831         if (!new_smb_io_relstr("document", buffer, depth, &info->document))
1832                 return False;
1833         if (!new_smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
1834                 return False;
1835         if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
1836                 return False;
1837
1838         if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1839                 return False;
1840         if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
1841                 return False;
1842         if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername))
1843                 return False;
1844         if (!new_smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1845                 return False;
1846         if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status))
1847                 return False;
1848
1849 /*      SEC_DESC sec_desc;*/
1850         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
1851                 return False;
1852
1853         if (!prs_uint32("status",ps, depth, &info->status))
1854                 return False;
1855         if (!prs_uint32("priority",ps, depth, &info->priority))
1856                 return False;
1857         if (!prs_uint32("position",ps, depth, &info->position)) 
1858                 return False;
1859         if (!prs_uint32("starttime",ps, depth, &info->starttime))
1860                 return False;
1861         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
1862                 return False;
1863         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
1864                 return False;
1865         if (!prs_uint32("size",ps, depth, &info->size))
1866                 return False;
1867         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
1868                 return False;
1869         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
1870                 return False;
1871         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
1872                 return False;
1873
1874         return True;
1875 }
1876
1877 /*******************************************************************
1878 ********************************************************************/  
1879 BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
1880 {
1881         prs_struct *ps=&(buffer->prs);
1882         
1883         prs_debug(ps, depth, desc, "new_smb_io_form_1");
1884         depth++;
1885                 
1886         buffer->struct_start=prs_offset(ps);
1887         
1888         if (!prs_uint32("flag", ps, depth, &(info->flag)))
1889                 return False;
1890                 
1891         if (!new_smb_io_relstr("name", buffer, depth, &(info->name)))
1892                 return False;
1893
1894         if (!prs_uint32("width", ps, depth, &(info->width)))
1895                 return False;
1896         if (!prs_uint32("length", ps, depth, &(info->length)))
1897                 return False;
1898         if (!prs_uint32("left", ps, depth, &(info->left)))
1899                 return False;
1900         if (!prs_uint32("top", ps, depth, &(info->top)))
1901                 return False;
1902         if (!prs_uint32("right", ps, depth, &(info->right)))
1903                 return False;
1904         if (!prs_uint32("bottom", ps, depth, &(info->bottom)))
1905                 return False;
1906
1907         return True;
1908 }
1909
1910 /*******************************************************************
1911  Read/write a BUFFER struct.
1912 ********************************************************************/  
1913 static BOOL new_spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER *buffer)
1914 {
1915         if (buffer == NULL)
1916                 return False;
1917
1918         prs_debug(ps, depth, desc, "new_spoolss_io_buffer");
1919         depth++;
1920         
1921         if (!prs_uint32("ptr", ps, depth, &(buffer->ptr)))
1922                 return False;
1923         
1924         /* reading */
1925         if (UNMARSHALLING(ps)) {
1926                 buffer->size=0;
1927                 buffer->string_at_end=0;
1928                 
1929                 if (buffer->ptr==0) {
1930                         if (!prs_init(&(buffer->prs), 0, 4, UNMARSHALL))
1931                                 return False;
1932                         return True;
1933                 }
1934                 
1935                 if (!prs_uint32("size", ps, depth, &buffer->size))
1936                         return False;
1937                                         
1938                 if (!prs_init(&(buffer->prs), buffer->size, 4, UNMARSHALL))
1939                         return False;
1940
1941                 if (!prs_append_some_prs_data(&(buffer->prs), ps, prs_offset(ps), buffer->size))
1942                         return False;
1943
1944                 if (!prs_set_offset(&buffer->prs, 0))
1945                         return False;
1946
1947                 if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
1948                         return False;
1949
1950                 buffer->string_at_end=buffer->size;
1951                 
1952                 return True;
1953         }
1954         else {
1955                 /* writing */
1956                 if (buffer->ptr==0)
1957                         return True;
1958                 
1959                 if (!prs_uint32("size", ps, depth, &(buffer->size)))
1960                         return False;
1961                 if (!prs_append_some_prs_data(ps, &(buffer->prs), 0, buffer->size))
1962                         return False;
1963
1964                 return True;
1965         }
1966 }
1967
1968 /*******************************************************************
1969  move a BUFFER from the query to the reply.
1970 ********************************************************************/  
1971 void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
1972 {
1973         prs_switch_type(&(src->prs), MARSHALL);
1974         prs_set_offset(&(src->prs), 0);
1975         prs_force_dynamic(&(src->prs));
1976
1977         *dest=src;
1978 }
1979
1980 /*******************************************************************
1981  create a BUFFER struct.
1982 ********************************************************************/  
1983 BOOL new_spoolss_allocate_buffer(NEW_BUFFER **buffer)
1984 {
1985         if (buffer==NULL)
1986                 return False;
1987                 
1988         if((*buffer=(NEW_BUFFER *)malloc(sizeof(NEW_BUFFER))) == NULL) {
1989                 DEBUG(0,("new_spoolss_allocate_buffer: malloc fail for size %u.\n",
1990                                 (unsigned int)sizeof(NEW_BUFFER) ));
1991                 return False;
1992         }
1993         
1994         (*buffer)->ptr=0x0;
1995         (*buffer)->size=0;
1996         (*buffer)->string_at_end=0;     
1997         return True;
1998 }
1999
2000 /*******************************************************************
2001  Destroy a BUFFER struct.
2002 ********************************************************************/  
2003 void new_spoolss_free_buffer(NEW_BUFFER *buffer)
2004 {
2005         if (buffer==NULL)
2006                 return;
2007                 
2008         prs_mem_free(&(buffer->prs));
2009         buffer->ptr=0x0;
2010         buffer->size=0;
2011         buffer->string_at_end=0;
2012         
2013         free(buffer);
2014 }
2015
2016 /*******************************************************************
2017  Get the size of a BUFFER struct.
2018 ********************************************************************/  
2019 uint32 new_get_buffer_size(NEW_BUFFER *buffer)
2020 {
2021         return (buffer->size);
2022 }
2023
2024
2025 /*******************************************************************
2026  Parse a DRIVER_DIRECTORY_1 structure.
2027 ********************************************************************/  
2028 BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2029 {
2030         prs_struct *ps=&(buffer->prs);
2031
2032         prs_debug(ps, depth, desc, "new_smb_io_driverdir_1");
2033         depth++;
2034
2035         buffer->struct_start=prs_offset(ps);
2036
2037         if (!spoolss_smb_io_unistr(desc, &info->name, ps, depth))
2038                 return False;
2039
2040         return True;
2041 }
2042
2043 /*******************************************************************
2044  Parse a PORT_INFO_1 structure.
2045 ********************************************************************/  
2046 BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2047 {
2048         prs_struct *ps=&(buffer->prs);
2049
2050         prs_debug(ps, depth, desc, "new_smb_io_port_1");
2051         depth++;
2052
2053         buffer->struct_start=prs_offset(ps);
2054
2055         if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name))
2056                 return False;
2057
2058         return True;
2059 }
2060
2061 /*******************************************************************
2062  Parse a PORT_INFO_2 structure.
2063 ********************************************************************/  
2064 BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2065 {
2066         prs_struct *ps=&(buffer->prs);
2067
2068         prs_debug(ps, depth, desc, "new_smb_io_port_2");
2069         depth++;
2070
2071         buffer->struct_start=prs_offset(ps);
2072
2073         if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name))
2074                 return False;
2075         if(!new_smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2076                 return False;
2077         if(!new_smb_io_relstr("description", buffer, depth, &info->description))
2078                 return False;
2079         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2080                 return False;
2081         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2082                 return False;
2083
2084         return True;
2085 }
2086
2087
2088 /*******************************************************************
2089 ********************************************************************/  
2090 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2091 {
2092         prs_struct *ps=&(buffer->prs);
2093
2094         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2095         depth++;        
2096
2097         buffer->struct_start=prs_offset(ps);
2098         
2099         if (new_smb_io_relstr("name", buffer, depth, &info->name))
2100                 return False;
2101
2102         return True;
2103 }
2104
2105 /*******************************************************************
2106 ********************************************************************/  
2107 BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2108 {
2109         prs_struct *ps=&(buffer->prs);
2110
2111         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2112         depth++;        
2113
2114         buffer->struct_start=prs_offset(ps);
2115         
2116         if (new_smb_io_relstr("name", buffer, depth, &info->name))
2117                 return False;
2118
2119         return True;
2120 }
2121
2122 /*******************************************************************
2123 ********************************************************************/  
2124 BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2125 {
2126         prs_struct *ps=&(buffer->prs);
2127
2128         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2129         depth++;        
2130
2131         buffer->struct_start=prs_offset(ps);
2132
2133         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
2134                 return False;
2135
2136         return True;
2137 }
2138
2139 /*******************************************************************
2140 ********************************************************************/  
2141 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2142 {
2143         prs_struct *ps=&(buffer->prs);
2144
2145         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2146         depth++;        
2147
2148         buffer->struct_start=prs_offset(ps);
2149
2150         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
2151                 return False;
2152         if (!new_smb_io_relstr("environment", buffer, depth, &info->environment))
2153                 return False;
2154         if (!new_smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2155                 return False;
2156
2157         return True;
2158 }
2159
2160 /*******************************************************************
2161 return the size required by a struct in the stream
2162 ********************************************************************/  
2163 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2164 {
2165         int size=0;
2166         
2167         size+=size_of_relative_string( &info->printername );
2168         size+=size_of_relative_string( &info->servername );
2169
2170         size+=size_of_uint32( &info->cjobs);
2171         size+=size_of_uint32( &info->total_jobs);
2172         size+=size_of_uint32( &info->total_bytes);
2173
2174         size+=size_of_uint16( &info->year);
2175         size+=size_of_uint16( &info->month);
2176         size+=size_of_uint16( &info->dayofweek);
2177         size+=size_of_uint16( &info->day);
2178         size+=size_of_uint16( &info->hour);
2179         size+=size_of_uint16( &info->minute);
2180         size+=size_of_uint16( &info->second);
2181         size+=size_of_uint16( &info->milliseconds);
2182
2183         size+=size_of_uint32( &info->global_counter);
2184         size+=size_of_uint32( &info->total_pages);
2185
2186         size+=size_of_uint16( &info->major_version);
2187         size+=size_of_uint16( &info->build_version);
2188
2189         size+=size_of_uint32( &info->unknown7);
2190         size+=size_of_uint32( &info->unknown8);
2191         size+=size_of_uint32( &info->unknown9);
2192         size+=size_of_uint32( &info->session_counter);
2193         size+=size_of_uint32( &info->unknown11);
2194         size+=size_of_uint32( &info->printer_errors);
2195         size+=size_of_uint32( &info->unknown13);
2196         size+=size_of_uint32( &info->unknown14);
2197         size+=size_of_uint32( &info->unknown15);
2198         size+=size_of_uint32( &info->unknown16);
2199         size+=size_of_uint32( &info->change_id);
2200         size+=size_of_uint32( &info->unknown18);
2201         size+=size_of_uint32( &info->status);
2202         size+=size_of_uint32( &info->unknown20);
2203         size+=size_of_uint32( &info->c_setprinter);
2204         
2205         size+=size_of_uint16( &info->unknown22);
2206         size+=size_of_uint16( &info->unknown23);
2207         size+=size_of_uint16( &info->unknown24);
2208         size+=size_of_uint16( &info->unknown25);
2209         size+=size_of_uint16( &info->unknown26);
2210         size+=size_of_uint16( &info->unknown27);
2211         size+=size_of_uint16( &info->unknown28);
2212         size+=size_of_uint16( &info->unknown29);
2213         
2214         return size;
2215 }
2216
2217 /*******************************************************************
2218 return the size required by a struct in the stream
2219 ********************************************************************/  
2220 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
2221 {
2222         int size=0;
2223                 
2224         size+=size_of_uint32( &(info->flags) ); 
2225         size+=size_of_relative_string( &(info->description) );
2226         size+=size_of_relative_string( &(info->name) );
2227         size+=size_of_relative_string( &(info->comment) );
2228
2229         return size;
2230 }
2231
2232 /*******************************************************************
2233 return the size required by a struct in the stream
2234 ********************************************************************/
2235 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
2236 {
2237         int size=0;
2238                 
2239         size+=4;      /* the security descriptor */
2240         
2241         size+=size_of_device_mode( info->devmode );
2242         
2243         size+=size_of_relative_string( &info->servername );
2244         size+=size_of_relative_string( &info->printername );
2245         size+=size_of_relative_string( &info->sharename );
2246         size+=size_of_relative_string( &info->portname );
2247         size+=size_of_relative_string( &info->drivername );
2248         size+=size_of_relative_string( &info->comment );
2249         size+=size_of_relative_string( &info->location );
2250         
2251         size+=size_of_relative_string( &info->sepfile );
2252         size+=size_of_relative_string( &info->printprocessor );
2253         size+=size_of_relative_string( &info->datatype );
2254         size+=size_of_relative_string( &info->parameters );
2255
2256         size+=size_of_uint32( &info->attributes );
2257         size+=size_of_uint32( &info->priority );
2258         size+=size_of_uint32( &info->defaultpriority );
2259         size+=size_of_uint32( &info->starttime );
2260         size+=size_of_uint32( &info->untiltime );
2261         size+=size_of_uint32( &info->status );
2262         size+=size_of_uint32( &info->cjobs );
2263         size+=size_of_uint32( &info->averageppm );      
2264         return size;
2265 }
2266
2267 /*******************************************************************
2268 return the size required by a struct in the stream
2269 ********************************************************************/
2270 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
2271 {
2272         int size=0;
2273         size+=size_of_relative_string( &info->name );
2274
2275         return size;
2276 }
2277
2278 /*******************************************************************
2279 return the size required by a struct in the stream
2280 ********************************************************************/
2281 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
2282 {
2283         int size=0;
2284         size+=size_of_uint32( &info->version ); 
2285         size+=size_of_relative_string( &info->name );
2286         size+=size_of_relative_string( &info->architecture );
2287         size+=size_of_relative_string( &info->driverpath );
2288         size+=size_of_relative_string( &info->datafile );
2289         size+=size_of_relative_string( &info->configfile );
2290
2291         return size;
2292 }
2293
2294 /*******************************************************************
2295 return the size required by a struct in the stream
2296 ********************************************************************/
2297 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
2298 {
2299         int size=0;
2300         uint16 *string;
2301         int i=0;
2302
2303         size+=size_of_uint32( &info->version ); 
2304         size+=size_of_relative_string( &info->name );
2305         size+=size_of_relative_string( &info->architecture );
2306         size+=size_of_relative_string( &info->driverpath );
2307         size+=size_of_relative_string( &info->datafile );
2308         size+=size_of_relative_string( &info->configfile );
2309         size+=size_of_relative_string( &info->helpfile );
2310         size+=size_of_relative_string( &info->monitorname );
2311         size+=size_of_relative_string( &info->defaultdatatype );
2312         
2313         string=info->dependentfiles;
2314         
2315         for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
2316
2317         i=i+2; /* to count all chars including the leading zero */
2318         i=2*i; /* because we need the value in bytes */
2319         i=i+4; /* the offset pointer size */
2320
2321         size+=i;
2322
2323         return size;
2324 }
2325
2326 /*******************************************************************
2327 return the size required by a struct in the stream
2328 ********************************************************************/  
2329 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
2330 {
2331         int size=0;
2332         size+=size_of_uint32( &info->jobid );
2333         size+=size_of_relative_string( &info->printername );
2334         size+=size_of_relative_string( &info->machinename );
2335         size+=size_of_relative_string( &info->username );
2336         size+=size_of_relative_string( &info->document );
2337         size+=size_of_relative_string( &info->datatype );
2338         size+=size_of_relative_string( &info->text_status );
2339         size+=size_of_uint32( &info->status );
2340         size+=size_of_uint32( &info->priority );
2341         size+=size_of_uint32( &info->position );
2342         size+=size_of_uint32( &info->totalpages );
2343         size+=size_of_uint32( &info->pagesprinted );
2344         size+=size_of_systemtime( &info->submitted );
2345
2346         return size;
2347 }
2348
2349 /*******************************************************************
2350 return the size required by a struct in the stream
2351 ********************************************************************/  
2352 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
2353 {
2354         int size=0;
2355
2356         size+=4; /* size of sec desc ptr */
2357
2358         size+=size_of_uint32( &info->jobid );
2359         size+=size_of_relative_string( &info->printername );
2360         size+=size_of_relative_string( &info->machinename );
2361         size+=size_of_relative_string( &info->username );
2362         size+=size_of_relative_string( &info->document );
2363         size+=size_of_relative_string( &info->notifyname );
2364         size+=size_of_relative_string( &info->datatype );
2365         size+=size_of_relative_string( &info->printprocessor );
2366         size+=size_of_relative_string( &info->parameters );
2367         size+=size_of_relative_string( &info->drivername );
2368         size+=size_of_device_mode( info->devmode );
2369         size+=size_of_relative_string( &info->text_status );
2370 /*      SEC_DESC sec_desc;*/
2371         size+=size_of_uint32( &info->status );
2372         size+=size_of_uint32( &info->priority );
2373         size+=size_of_uint32( &info->position );
2374         size+=size_of_uint32( &info->starttime );
2375         size+=size_of_uint32( &info->untiltime );
2376         size+=size_of_uint32( &info->totalpages );
2377         size+=size_of_uint32( &info->size );
2378         size+=size_of_systemtime( &info->submitted );
2379         size+=size_of_uint32( &info->timeelapsed );
2380         size+=size_of_uint32( &info->pagesprinted );
2381
2382         return size;
2383 }
2384
2385 /*******************************************************************
2386 return the size required by a struct in the stream
2387 ********************************************************************/
2388 uint32 spoolss_size_form_1(FORM_1 *info)
2389 {
2390         int size=0;
2391
2392         size+=size_of_uint32( &(info->flag) );
2393         size+=size_of_relative_string( &(info->name) );
2394         size+=size_of_uint32( &(info->width) );
2395         size+=size_of_uint32( &(info->length) );
2396         size+=size_of_uint32( &(info->left) );
2397         size+=size_of_uint32( &(info->top) );
2398         size+=size_of_uint32( &(info->right) );
2399         size+=size_of_uint32( &(info->bottom) );
2400
2401         return size;
2402 }
2403
2404 /*******************************************************************
2405 return the size required by a struct in the stream
2406 ********************************************************************/  
2407 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
2408 {
2409         int size=0;
2410
2411         size+=size_of_relative_string( &info->port_name );
2412
2413         return size;
2414 }
2415
2416 /*******************************************************************
2417 return the size required by a struct in the stream
2418 ********************************************************************/  
2419 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
2420 {
2421         int size=0;
2422
2423         size=str_len_uni(&info->name);  /* the string length       */
2424         size=size+1;                    /* add the leading zero    */
2425         size=size*2;                    /* convert in char         */
2426
2427         return size;
2428 }
2429
2430 /*******************************************************************
2431 return the size required by a struct in the stream
2432 ********************************************************************/  
2433 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
2434 {
2435         int size=0;
2436
2437         size+=size_of_relative_string( &info->port_name );
2438         size+=size_of_relative_string( &info->monitor_name );
2439         size+=size_of_relative_string( &info->description );
2440
2441         size+=size_of_uint32( &info->port_type );
2442         size+=size_of_uint32( &info->reserved );
2443
2444         return size;
2445 }
2446
2447 /*******************************************************************
2448 return the size required by a struct in the stream
2449 ********************************************************************/  
2450 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
2451 {
2452         int size=0;
2453         size+=size_of_relative_string( &info->name );
2454
2455         return size;
2456 }
2457
2458 /*******************************************************************
2459 return the size required by a struct in the stream
2460 ********************************************************************/  
2461 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
2462 {
2463         int size=0;
2464         size+=size_of_relative_string( &info->name );
2465
2466         return size;
2467 }
2468
2469 /*******************************************************************
2470 return the size required by a struct in the stream
2471 ********************************************************************/  
2472 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
2473 {
2474         int size=0;
2475         size+=size_of_relative_string( &info->name );
2476
2477         return size;
2478 }
2479
2480 /*******************************************************************
2481 return the size required by a struct in the stream
2482 ********************************************************************/  
2483 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
2484 {
2485         int size=0;
2486         size+=size_of_relative_string( &info->name);
2487         size+=size_of_relative_string( &info->environment);
2488         size+=size_of_relative_string( &info->dll_name);
2489
2490         return size;
2491 }
2492
2493 /*******************************************************************
2494  * init a structure.
2495  ********************************************************************/
2496 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
2497                                const POLICY_HND *hnd, fstring architecture,
2498                                uint32 level, uint32 clientmajor, uint32 clientminor,
2499                                NEW_BUFFER *buffer, uint32 offered)
2500 {      
2501         if (q_u == NULL)
2502         {
2503                 return False;
2504         }
2505
2506         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2507
2508         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
2509
2510         q_u->level=level;
2511         q_u->clientmajorversion=clientmajor;
2512         q_u->clientminorversion=clientminor;
2513
2514         q_u->buffer=buffer;
2515         q_u->offered=offered;
2516
2517         return True;
2518 }
2519
2520 /*******************************************************************
2521  * read a structure.
2522  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2523  ********************************************************************/
2524 BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
2525 {
2526         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
2527         depth++;
2528
2529         if(!prs_align(ps))
2530                 return False;
2531         
2532         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2533                 return False;
2534         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
2535                 return False;
2536         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
2537                 return False;
2538         
2539         if(!prs_align(ps))
2540                 return False;
2541                 if(!prs_uint32("level", ps, depth, &q_u->level))
2542                 return False;
2543                 
2544         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2545                 return False;
2546
2547         if(!prs_align(ps))
2548                 return False;
2549
2550         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2551                 return False;
2552                 
2553         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
2554                 return False;
2555         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
2556                 return False;
2557
2558         return True;
2559 }
2560
2561 /*******************************************************************
2562  * read a structure.
2563  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2564  ********************************************************************/
2565 BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
2566 {
2567         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
2568         depth++;
2569
2570         if (!prs_align(ps))
2571                 return False;
2572                 
2573         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2574                 return False;
2575
2576         if (!prs_align(ps))
2577                 return False;
2578         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2579                 return False;
2580         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
2581                 return False;
2582         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
2583                 return False;           
2584         if (!prs_uint32("status", ps, depth, &r_u->status))
2585                 return False;
2586
2587         return True;            
2588 }
2589
2590 /*******************************************************************
2591  * init a structure.
2592  ********************************************************************/
2593 BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, 
2594                                 fstring servername, uint32 level, 
2595                                 NEW_BUFFER *buffer, uint32 offered)
2596 {
2597         q_u->flags=flags;
2598         
2599         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
2600         init_unistr2(&(q_u->servername), servername, strlen(servername));
2601
2602         q_u->level=level;
2603         q_u->buffer=buffer;
2604         q_u->offered=offered;
2605
2606         return True;
2607 }
2608
2609 /*******************************************************************
2610  * read a structure.
2611  * called from spoolss_enumprinters (srv_spoolss.c)
2612  ********************************************************************/
2613 BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
2614 {
2615         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
2616         depth++;
2617
2618         if (!prs_align(ps))
2619                 return False;
2620
2621         if (!prs_uint32("flags", ps, depth, &q_u->flags))
2622                 return False;
2623         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
2624                 return False;
2625
2626         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
2627                 return False;
2628                 
2629         if (!prs_align(ps))
2630                 return False;
2631         if (!prs_uint32("level", ps, depth, &q_u->level))
2632                 return False;
2633
2634         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2635                 return False;
2636
2637         if (!prs_align(ps))
2638                 return False;
2639         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2640                 return False;
2641
2642         return True;
2643 }
2644
2645 /*******************************************************************
2646  Parse a SPOOL_R_ENUMPRINTERS structure.
2647  ********************************************************************/
2648 BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
2649 {
2650         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinters");
2651         depth++;
2652
2653         if (!prs_align(ps))
2654                 return False;
2655                 
2656         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2657                 return False;
2658
2659         if (!prs_align(ps))
2660                 return False;
2661                 
2662         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2663                 return False;
2664                 
2665         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2666                 return False;
2667                 
2668         if (!prs_uint32("status", ps, depth, &r_u->status))
2669                 return False;
2670
2671         return True;            
2672 }
2673
2674 /*******************************************************************
2675  * write a structure.
2676  * called from spoolss_r_enum_printers (srv_spoolss.c)
2677  *
2678  ********************************************************************/
2679 BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
2680 {       
2681         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
2682         depth++;
2683
2684         if (!prs_align(ps))
2685                 return False;
2686                 
2687         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2688                 return False;
2689
2690         if (!prs_align(ps))
2691                 return False;
2692                 
2693         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2694                 return False;
2695                 
2696         if (!prs_uint32("status", ps, depth, &r_u->status))
2697                 return False;
2698
2699         return True;            
2700 }
2701
2702 /*******************************************************************
2703  * read a structure.
2704  * called from spoolss_getprinter (srv_spoolss.c)
2705  ********************************************************************/
2706 BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
2707 {
2708         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
2709         depth++;
2710
2711         if (!prs_align(ps))
2712                 return False;
2713
2714         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2715                 return False;
2716         if (!prs_uint32("level", ps, depth, &q_u->level))
2717                 return False;
2718
2719         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2720                 return False;
2721
2722         if (!prs_align(ps))
2723                 return False;
2724         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2725                 return False;
2726
2727         return True;
2728 }
2729
2730 /*******************************************************************
2731  * init a structure.
2732  ********************************************************************/
2733 BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, 
2734                                 NEW_BUFFER *buffer, uint32 offered)
2735 {
2736         if (q_u == NULL)
2737         {
2738                 return False;
2739         }
2740         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2741
2742         q_u->level=level;
2743         q_u->buffer=buffer;
2744         q_u->offered=offered;
2745
2746         return True;
2747 }
2748
2749 /*******************************************************************
2750 ********************************************************************/  
2751 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
2752 {               
2753         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
2754         depth++;
2755
2756         if(!prs_align(ps))
2757                 return False;
2758         
2759         if(!prs_uint32("status", ps, depth, &(r_u->status)))
2760                 return False;
2761
2762         return True;
2763 }
2764
2765 /*******************************************************************
2766 ********************************************************************/  
2767 BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
2768 {
2769         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
2770         depth++;
2771
2772         if(!prs_align(ps))
2773                 return False;
2774
2775         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
2776                 return False;
2777         if(!prs_uint32("level", ps, depth, &q_u->level))
2778                 return False;
2779
2780         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
2781                 return False;
2782
2783         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
2784                 return False;
2785         
2786         if(!prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer))
2787                 return False;
2788         if(!prs_uint32("security.data", ps, depth, &q_u->security.data))
2789                 return False;
2790         
2791         if(!prs_uint32("command", ps, depth, &q_u->command))
2792                 return False;
2793
2794         return True;
2795 }
2796
2797 /*******************************************************************
2798 ********************************************************************/  
2799 BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
2800 {               
2801         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
2802         depth++;
2803
2804         if(!prs_align(ps))
2805                 return False;
2806         
2807         if(!prs_uint32("status", ps, depth, &(r_u->status)))
2808                 return False;
2809
2810         return True;
2811 }
2812
2813 /*******************************************************************
2814 ********************************************************************/  
2815 BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
2816 {
2817
2818         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
2819         depth++;
2820
2821         if(!prs_align(ps))
2822                 return False;
2823
2824         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
2825                 return False;
2826
2827         return True;
2828 }
2829
2830
2831 /*******************************************************************
2832 ********************************************************************/  
2833 BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
2834 {               
2835         prs_debug(ps, depth, desc, "");
2836         depth++;
2837
2838         if(!prs_align(ps))
2839                 return False;
2840         
2841         if(!prs_uint32("status", ps, depth, &r_u->status))
2842                 return False;
2843
2844         return True;
2845 }
2846
2847 /*******************************************************************
2848 ********************************************************************/  
2849 BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
2850 {
2851         prs_debug(ps, depth, desc, "");
2852         depth++;
2853
2854         if(!prs_align(ps))
2855                 return False;
2856
2857         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2858                 return False;
2859         if(!prs_uint32("level", ps, depth, &q_u->level))
2860                 return False;
2861         
2862         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2863                 return False;
2864
2865         if(!prs_align(ps))
2866                 return False;
2867         
2868         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2869                 return False;
2870
2871         return True;
2872 }
2873
2874 /*******************************************************************
2875 ********************************************************************/  
2876 BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
2877 {               
2878         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
2879         depth++;
2880
2881         if (!prs_align(ps))
2882                 return False;
2883                 
2884         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2885                 return False;
2886
2887         if (!prs_align(ps))
2888                 return False;
2889                 
2890         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2891                 return False;
2892                 
2893         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2894                 return False;
2895                 
2896         if (!prs_uint32("status", ps, depth, &r_u->status))
2897                 return False;
2898
2899         return True;            
2900 }
2901
2902
2903 /*******************************************************************
2904 ********************************************************************/  
2905 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
2906                                 uint32 firstjob,
2907                                 uint32 numofjobs,
2908                                 uint32 level,
2909                                 NEW_BUFFER *buffer,
2910                                 uint32 offered)
2911 {
2912         if (q_u == NULL)
2913         {
2914                 return False;
2915         }
2916         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2917         q_u->firstjob = firstjob;
2918         q_u->numofjobs = numofjobs;
2919         q_u->level = level;
2920         q_u->buffer= buffer;
2921         q_u->offered = offered;
2922         return True;
2923 }
2924
2925 /*******************************************************************
2926 ********************************************************************/  
2927 BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
2928 {
2929         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
2930         depth++;
2931
2932         if (!prs_align(ps))
2933                 return False;
2934
2935         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
2936                 return False;
2937                 
2938         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
2939                 return False;
2940         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
2941                 return False;
2942         if (!prs_uint32("level", ps, depth, &q_u->level))
2943                 return False;
2944
2945         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2946                 return False;   
2947
2948         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2949                 return False;
2950
2951         return True;
2952 }
2953
2954 /*******************************************************************
2955 ********************************************************************/  
2956 BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
2957 {               
2958         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
2959         depth++;
2960
2961         if(!prs_align(ps))
2962                 return False;
2963         
2964         if(!prs_uint32("status", ps, depth, &(r_u->status)))
2965                 return False;
2966
2967         return True;
2968 }
2969
2970 /*******************************************************************
2971 ********************************************************************/  
2972 BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
2973 {
2974         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
2975         depth++;
2976
2977         if(!prs_align(ps))
2978                 return False;
2979
2980         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
2981                 return False;
2982         if(!prs_uint32("jobid", ps, depth, &(q_u->jobid)))
2983                 return False;
2984
2985         return True;
2986 }
2987
2988 /*******************************************************************
2989 ********************************************************************/  
2990 BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
2991 {               
2992         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
2993         depth++;
2994
2995         if(!prs_align(ps))
2996                 return False;
2997         
2998         if(!prs_uint32("status", ps, depth, &(r_u->status)))
2999                 return False;
3000
3001         return True;
3002 }
3003
3004 /*******************************************************************
3005 ********************************************************************/  
3006 BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
3007 {
3008         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
3009         depth++;
3010
3011         if(!prs_align(ps))
3012                 return False;
3013
3014         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
3015                 return False;
3016         if(!prs_uint32("jobid", ps, depth, &(q_u->jobid)))
3017                 return False;
3018         /* 
3019          * level is usually 0. If (level!=0) then I'm in trouble !
3020          * I will try to generate setjob command with level!=0, one day.
3021          */
3022         if(!prs_uint32("level", ps, depth, &(q_u->level)))
3023                 return False;
3024         if(!prs_uint32("command", ps, depth, &(q_u->command)))
3025                 return False;
3026
3027         return True;
3028 }
3029
3030 /*******************************************************************
3031  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
3032 ********************************************************************/  
3033 BOOL new_spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
3034 {
3035         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinterdrivers");
3036         depth++;
3037
3038         if (!prs_align(ps))
3039                 return False;
3040                 
3041         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3042                 return False;
3043
3044         if (!prs_align(ps))
3045                 return False;
3046                 
3047         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3048                 return False;
3049                 
3050         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3051                 return False;
3052                 
3053         if (!prs_uint32("status", ps, depth, &r_u->status))
3054                 return False;
3055
3056         return True;            
3057 }
3058
3059
3060 /*******************************************************************
3061  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
3062 ********************************************************************/  
3063 BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
3064 {
3065
3066         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
3067         depth++;
3068
3069         if (!prs_align(ps))
3070                 return False;
3071                 
3072         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3073                 return False;
3074         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
3075                 return False;
3076                 
3077         if (!prs_align(ps))
3078                 return False;
3079         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
3080                 return False;
3081         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3082                 return False;
3083                 
3084         if (!prs_align(ps))
3085                 return False;
3086         if (!prs_uint32("level", ps, depth, &q_u->level))
3087                 return False;
3088                 
3089         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3090                 return False;
3091
3092         if (!prs_align(ps))
3093                 return False;
3094                 
3095         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3096                 return False;
3097
3098         return True;
3099 }
3100
3101 /*******************************************************************
3102 ********************************************************************/  
3103 BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
3104 {
3105
3106         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
3107         depth++;
3108
3109         if (!prs_align(ps))
3110                 return False;                   
3111         if (!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
3112                 return False;           
3113         if (!prs_uint32("level", ps, depth, &(q_u->level)))
3114                 return False;   
3115         
3116         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3117                 return False;
3118
3119         if (!prs_align(ps))
3120                 return False;
3121         if (!prs_uint32("offered", ps, depth, &(q_u->offered)))
3122                 return False;
3123
3124         return True;
3125 }
3126
3127 /*******************************************************************
3128 ********************************************************************/  
3129 BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
3130 {
3131         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumforms");
3132         depth++;
3133
3134         if (!prs_align(ps))
3135                 return False;
3136                 
3137         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3138                 return False;
3139
3140         if (!prs_align(ps))
3141                 return False;
3142                 
3143         if (!prs_uint32("size of buffer needed", ps, depth, &(r_u->needed)))
3144                 return False;
3145                 
3146         if (!prs_uint32("numofforms", ps, depth, &(r_u->numofforms)))
3147                 return False;
3148                 
3149         if (!prs_uint32("status", ps, depth, &(r_u->status)))
3150                 return False;
3151
3152         return True;
3153                 
3154 }
3155
3156 /*******************************************************************
3157  Parse a SPOOL_R_ENUMPORTS structure.
3158 ********************************************************************/  
3159 BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
3160 {
3161         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumports");
3162         depth++;
3163
3164         if (!prs_align(ps))
3165                 return False;
3166                 
3167         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3168                 return False;
3169
3170         if (!prs_align(ps))
3171                 return False;
3172                 
3173         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3174                 return False;
3175                 
3176         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3177                 return False;
3178                 
3179         if (!prs_uint32("status", ps, depth, &r_u->status))
3180                 return False;
3181
3182         return True;            
3183 }
3184
3185 /*******************************************************************
3186 ********************************************************************/  
3187 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
3188 {
3189         prs_debug(ps, depth, desc, "");
3190         depth++;
3191
3192         if (!prs_align(ps))
3193                 return False;
3194
3195         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
3196                 return False;
3197         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
3198                 return False;
3199
3200         if (!prs_align(ps))
3201                 return False;
3202         if (!prs_uint32("level", ps, depth, &q_u->level))
3203                 return False;
3204                 
3205         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3206                 return False;
3207
3208         if (!prs_align(ps))
3209                 return False;
3210         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3211                 return False;
3212
3213         return True;
3214 }
3215
3216 /*******************************************************************
3217  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
3218 ********************************************************************/  
3219 BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
3220 {       
3221         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
3222         depth++;
3223                 
3224         if(!prs_align(ps))
3225                 return False;
3226
3227         if(!prs_uint32("flags", ps, depth, &il->flags))
3228                 return False;
3229         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
3230                 return False;
3231         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
3232                 return False;
3233         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3234                 return False;
3235                 
3236         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
3237                 return False;
3238         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3239                 return False;
3240         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3241                 return False;
3242
3243         return True;
3244 }
3245
3246 /*******************************************************************
3247  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
3248 ********************************************************************/  
3249 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
3250 {       
3251         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
3252         depth++;
3253                 
3254         if(!prs_align(ps))
3255                 return False;
3256
3257         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
3258                 return False;
3259         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
3260                 return False;
3261         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
3262                 return False;
3263         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
3264                 return False;
3265         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
3266                 return False;
3267         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3268                 return False;
3269         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
3270                 return False;
3271         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
3272                 return False;
3273         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
3274                 return False;
3275         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
3276                 return False;
3277         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
3278                 return False;
3279         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
3280                 return False;
3281         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3282                 return False;
3283
3284         if(!prs_uint32("attributes", ps, depth, &il->attributes))
3285                 return False;
3286         if(!prs_uint32("priority", ps, depth, &il->priority))
3287                 return False;
3288         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
3289                 return False;
3290         if(!prs_uint32("starttime", ps, depth, &il->starttime))
3291                 return False;
3292         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
3293                 return False;
3294         if(!prs_uint32("status", ps, depth, &il->status))
3295                 return False;
3296         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
3297                 return False;
3298         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
3299                 return False;
3300
3301         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
3302                 return False;
3303         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
3304                 return False;
3305         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
3306                 return False;
3307         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
3308                 return False;
3309         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
3310                 return False;
3311         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3312                 return False;
3313         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
3314                 return False;
3315         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
3316                 return False;
3317         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
3318                 return False;
3319         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
3320                 return False;
3321         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
3322                 return False;
3323
3324         return True;
3325 }
3326
3327 /*******************************************************************
3328 ********************************************************************/  
3329 BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
3330 {
3331         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
3332         depth++;
3333
3334         if(!prs_align(ps))
3335                 return False;
3336         if(!prs_uint32("level", ps, depth, &il->level))
3337                 return False;
3338         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
3339                 return False;
3340         
3341         /* if no struct inside just return */
3342         if (il->info_ptr==0) {
3343                 if (UNMARSHALLING(ps)) {
3344                         il->info_1=NULL;
3345                         il->info_2=NULL;
3346                 }
3347                 return True;
3348         }
3349                         
3350         switch (il->level) {
3351                 /*
3352                  * level 0 is used by setprinter when managing the queue
3353                  * (hold, stop, start a queue)
3354                  */
3355                 case 0:
3356                         break;
3357                 /* 
3358                  * level 2 is used by addprinter
3359                  * and by setprinter when updating printer's info
3360                  */     
3361                 case 1:
3362                         if (UNMARSHALLING(ps)) {
3363                                 il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_1));
3364                                 if(il->info_1 == NULL)
3365                                         return False;
3366                         }
3367                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
3368                                 return False;
3369                         break;          
3370                 case 2:
3371                         if (UNMARSHALLING(ps)) {
3372                                 il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
3373                                 if(il->info_2 == NULL)
3374                                         return False;
3375                         }
3376                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
3377                                 return False;
3378                         break;          
3379         }
3380
3381         return True;
3382 }
3383
3384 /*******************************************************************
3385 ********************************************************************/  
3386 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
3387 {
3388         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
3389         depth++;
3390
3391         /*
3392          * I think that's one of the few well written functions.
3393          * the sub-structures are correctly parsed and analysed
3394          * the info level are handled in a nice way.
3395          */
3396
3397         if(!prs_align(ps))
3398                 return False;
3399         if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
3400                 return False;
3401         if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
3402                 return False;
3403
3404         if(!prs_align(ps))
3405                 return False;
3406
3407         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3408                 return False;
3409         
3410         if(!spool_io_printer_info_level("", &(q_u->info), ps, depth))
3411                 return False;
3412         
3413         /* the 4 unknown are all 0 */
3414
3415         /* 
3416          * en fait ils sont pas inconnu
3417          * par recoupement avec rpcSetPrinter
3418          * c'est le devicemode 
3419          * et le security descriptor.
3420          */
3421         
3422         if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
3423                 return False;
3424         if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
3425                 return False;
3426         if(!prs_uint32("unk2", ps, depth, &q_u->unk2))
3427                 return False;
3428         if(!prs_uint32("unk3", ps, depth, &q_u->unk3))
3429                 return False;
3430
3431         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
3432                 return False;
3433         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
3434                 return False;
3435
3436         return True;
3437 }
3438
3439
3440 /*******************************************************************
3441 ********************************************************************/  
3442 BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth)
3443 {
3444         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
3445         depth++;
3446         
3447         if(!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
3448                 return False;
3449
3450         if(!prs_uint32("status", ps, depth, &(r_u->status)))
3451                 return False;
3452
3453         return True;
3454 }
3455
3456 /*******************************************************************
3457 ********************************************************************/  
3458 BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
3459                                           prs_struct *ps, int depth)
3460 {       
3461         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
3462         
3463         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
3464         depth++;
3465                 
3466         /* reading */
3467         if (UNMARSHALLING(ps)) {
3468                 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
3469                 if(il == NULL)
3470                         return False;
3471                 ZERO_STRUCTP(il);
3472                 *q_u=il;
3473         }
3474         else {
3475                 il=*q_u;
3476         }
3477         
3478         if(!prs_align(ps))
3479                 return False;
3480
3481         if(!prs_uint32("cversion", ps, depth, &il->cversion))
3482                 return False;
3483         if(!prs_uint32("name", ps, depth, &il->name_ptr))
3484                 return False;
3485         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
3486                 return False;
3487         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
3488                 return False;
3489         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
3490                 return False;
3491         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
3492                 return False;
3493         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
3494                 return False;
3495         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
3496                 return False;
3497         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3498                 return False;
3499         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
3500                 return False;
3501         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
3502                 return False;
3503
3504         if(!prs_align(ps))
3505                 return False;
3506         
3507         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3508                 return False;
3509         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3510                 return False;
3511         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3512                 return False;
3513         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3514                 return False;
3515         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3516                 return False;
3517         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3518                 return False;
3519         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3520                 return False;
3521         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3522                 return False;
3523
3524         if(!prs_align(ps))
3525                 return False;
3526                 
3527         if (il->dependentfiles_ptr)
3528                 smb_io_buffer5("", &(il->dependentfiles), ps, depth);
3529
3530         return True;
3531 }
3532
3533
3534 /*******************************************************************
3535  convert a buffer of UNICODE strings null terminated
3536  the buffer is terminated by a NULL
3537  
3538  convert to an ascii array (null terminated)
3539  
3540  dynamically allocate memory
3541  
3542 ********************************************************************/  
3543 BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar)
3544 {
3545         char **array;
3546         char *string;
3547         char *destend;
3548         char *dest;
3549         uint32 n;
3550         uint32 i;
3551
3552         uint16 *src;
3553
3554         if (buf5==NULL) return False;
3555
3556         array=NULL;
3557         n=0;
3558         i=0;
3559         src=buf5->buffer;
3560
3561         string=(char *)malloc(sizeof(char)*buf5->buf_len);
3562         if(string == NULL)
3563                 return False;
3564
3565         destend = string + buf5->buf_len;
3566         dest=string;
3567
3568         while (dest < destend)
3569         {
3570                 *(dest++) = (char)*(src++);
3571         }
3572                 
3573         /* that ugly for the first one but that's working */
3574         array=(char **)Realloc(array, sizeof(char *)*(i+1));
3575         if(array == NULL)
3576                 return False;
3577         array[i++]=string;
3578         
3579         while ( n < buf5->buf_len )
3580         {
3581                 if ( *(string++) == '\0' )
3582                 {
3583                         array=(char **)Realloc(array, sizeof(char *)*(i+1));
3584                         if(array == NULL)
3585                                 return False;
3586                         array[i++]=string;                      
3587                 }
3588                 n++;
3589         }               
3590         *ar=array;
3591         
3592         DEBUG(10,("Number of dependent files: [%d]\n", i-1));
3593
3594         return True;
3595 }
3596
3597 /*******************************************************************
3598  read a UNICODE array with null terminated strings 
3599  and null terminated array 
3600  and size of array at beginning
3601 ********************************************************************/  
3602 BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
3603 {
3604         if (buffer==NULL) return False;
3605
3606         buffer->undoc=0;
3607         buffer->uni_str_len=buffer->uni_max_len;
3608         
3609         if(!prs_uint32("buffer_size", ps, depth, &(buffer->uni_max_len)))
3610                 return False;
3611
3612         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
3613                 return False;
3614
3615         return True;
3616 }
3617
3618 /*******************************************************************
3619 ********************************************************************/  
3620 BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
3621 {
3622         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
3623         depth++;
3624
3625         if(!prs_align(ps))
3626                 return False;
3627         if(!prs_uint32("level", ps, depth, &il->level))
3628                 return False;
3629         if(!prs_uint32("ptr", ps, depth, &il->ptr))
3630                 return False;
3631
3632         if (il->ptr==0)
3633                 return True;
3634                 
3635         switch (il->level) {
3636                 case 3:
3637                         if(!spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth))
3638                                 return False;
3639                         break;          
3640         }
3641
3642         return True;
3643 }
3644
3645 /*******************************************************************
3646 ********************************************************************/  
3647 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
3648 {
3649         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
3650         depth++;
3651
3652         if(!prs_align(ps))
3653                 return False;
3654
3655         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
3656                 return False;
3657         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
3658                 return False;
3659                 
3660         if(!prs_align(ps))
3661                 return False;
3662         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3663                 return False;
3664
3665         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
3666                 return False;
3667
3668         return True;
3669 }
3670
3671 /*******************************************************************
3672 ********************************************************************/  
3673 BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
3674 {
3675         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
3676         depth++;
3677
3678         if(!prs_uint32("status", ps, depth, &q_u->status))
3679                 return False;
3680
3681         return True;
3682 }
3683
3684
3685 /*******************************************************************
3686 ********************************************************************/  
3687 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
3688                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
3689 {
3690         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
3691         
3692         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
3693         
3694         if (*asc==NULL)
3695         {
3696                 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
3697                 if(*asc == NULL)
3698                         return False;
3699                 ZERO_STRUCTP(*asc);
3700         }       
3701
3702         d=*asc;
3703
3704         d->cversion=uni->cversion;
3705
3706         unistr2_to_ascii(d->name,            &(uni->name),            sizeof(d->name)-1);
3707         unistr2_to_ascii(d->environment,     &(uni->environment),     sizeof(d->environment)-1);
3708         unistr2_to_ascii(d->driverpath,      &(uni->driverpath),      sizeof(d->driverpath)-1);
3709         unistr2_to_ascii(d->datafile,        &(uni->datafile),        sizeof(d->datafile)-1);
3710         unistr2_to_ascii(d->configfile,      &(uni->configfile),      sizeof(d->configfile)-1);
3711         unistr2_to_ascii(d->helpfile,        &(uni->helpfile),        sizeof(d->helpfile)-1);
3712         unistr2_to_ascii(d->monitorname,     &(uni->monitorname),     sizeof(d->monitorname)-1);
3713         unistr2_to_ascii(d->defaultdatatype, &(uni->defaultdatatype), sizeof(d->defaultdatatype)-1);
3714
3715         DEBUGADD(8,( "version:         %d\n", d->cversion));
3716         DEBUGADD(8,( "name:            %s\n", d->name));
3717         DEBUGADD(8,( "environment:     %s\n", d->environment));
3718         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
3719         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
3720         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
3721         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
3722         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
3723         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
3724
3725         uniarray_2_ascarray(&(uni->dependentfiles), &(d->dependentfiles) );
3726
3727         return True;
3728 }
3729
3730 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
3731                               NT_PRINTER_INFO_LEVEL_2  **asc)
3732 {
3733         NT_PRINTER_INFO_LEVEL_2 *d;
3734         NTTIME time_nt;
3735         time_t time_unix;
3736         
3737         DEBUG(7,("Converting from UNICODE to ASCII\n"));
3738         time_unix=time(NULL);
3739         
3740         if (*asc==NULL)
3741         {
3742                 DEBUGADD(8,("allocating memory\n"));
3743
3744                 *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
3745                 if(*asc == NULL)
3746                         return False;
3747                 ZERO_STRUCTP(*asc);
3748                 
3749                 /* we allocate memory iff called from 
3750                  * addprinter(ex) so we can do one time stuff here.
3751                  */
3752                 (*asc)->setuptime=time_unix;
3753
3754         }       
3755         DEBUGADD(8,("start converting\n"));
3756
3757         d=*asc;
3758                 
3759         d->attributes=uni->attributes;
3760         d->priority=uni->priority;
3761         d->default_priority=uni->default_priority;
3762         d->starttime=uni->starttime;
3763         d->untiltime=uni->untiltime;
3764         d->status=uni->status;
3765         d->cjobs=uni->cjobs;
3766
3767         unix_to_nt_time(&time_nt, time_unix);
3768         d->changeid=time_nt.low;
3769         
3770         d->c_setprinter++;
3771
3772         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
3773         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
3774         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
3775         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
3776         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
3777         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
3778         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
3779         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
3780         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
3781         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
3782
3783         return True;
3784 }
3785
3786 /*******************************************************************
3787  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
3788 ********************************************************************/  
3789 BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
3790 {
3791         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
3792         depth++;
3793
3794         if(!prs_align(ps))
3795                 return False;
3796         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3797                 return False;
3798         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
3799                 return False;
3800
3801         if(!prs_align(ps))
3802                 return False;
3803                 
3804         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
3805                 return False;
3806         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3807                 return False;
3808                 
3809         if(!prs_align(ps))
3810                 return False;
3811
3812         if(!prs_uint32("level", ps, depth, &q_u->level))
3813                 return False;
3814                 
3815         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3816                 return False;
3817                 
3818         if(!prs_align(ps))
3819                 return False;
3820                 
3821 &