added support for deleting printers into the spoolss system
[ira/wip.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_deleteprinter (srv_spoolss.c)
870  * called from spoolss_deleteprinter (cli_spoolss.c)
871  ********************************************************************/
872 BOOL spoolss_io_q_deleteprinter(char *desc, SPOOL_Q_DELETEPRINTER *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_deleteprinter");
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_deleteprinter (srv_spoolss.c)
891  * called from spoolss_deleteprinter (cli_spoolss.c)
892  ********************************************************************/
893 BOOL spoolss_io_r_deleteprinter(char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
894 {
895         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
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 /*******************************************************************
911  * read a structure.
912  * called from static spoolss_q_closeprinter (srv_spoolss.c)
913  * called from spoolss_closeprinter (cli_spoolss.c)
914  ********************************************************************/
915 BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
916 {
917         if (q_u == NULL) return False;
918
919         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
920         depth++;
921
922         if (!prs_align(ps))
923                 return False;
924
925         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
926                 return False;
927
928         return True;
929 }
930
931 /*******************************************************************
932  * write a structure.
933  * called from static spoolss_r_closeprinter (srv_spoolss.c)
934  * called from spoolss_closeprinter (cli_spoolss.c)
935  ********************************************************************/
936 BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
937 {
938         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
939         depth++;
940         
941         if (!prs_align(ps))
942                 return False;
943
944         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
945                 return False;
946         if (!prs_uint32("status", ps, depth, &r_u->status))
947                 return False;
948         
949         return True;
950 }
951
952 /*******************************************************************
953  * read a structure.
954  * called from spoolss_q_startdocprinter (srv_spoolss.c)
955  ********************************************************************/
956 BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
957 {
958         if (q_u == NULL) return False;
959
960         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
961         depth++;
962
963         if(!prs_align(ps))
964                 return False;
965
966         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
967                 return False;
968         
969         if(!smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth))
970                 return False;
971
972         return True;
973 }
974
975 /*******************************************************************
976  * write a structure.
977  * called from spoolss_r_startdocprinter (srv_spoolss.c)
978  ********************************************************************/
979 BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
980 {
981         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
982         depth++;
983         if(!prs_uint32("jobid", ps, depth, &(r_u->jobid)))
984                 return False;
985         if(!prs_uint32("status", ps, depth, &(r_u->status)))
986                 return False;
987
988         return True;
989 }
990
991 /*******************************************************************
992  * read a structure.
993  * called from spoolss_q_enddocprinter (srv_spoolss.c)
994  ********************************************************************/
995 BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
996 {
997         if (q_u == NULL) return False;
998
999         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1000         depth++;
1001
1002         if(!prs_align(ps))
1003                 return False;
1004
1005         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
1006                 return False;
1007
1008         return True;
1009 }
1010
1011 /*******************************************************************
1012  * write a structure.
1013  * called from spoolss_r_enddocprinter (srv_spoolss.c)
1014  ********************************************************************/
1015 BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1016 {
1017         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1018         depth++;
1019         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1020                 return False;
1021
1022         return True;
1023 }
1024
1025 /*******************************************************************
1026  * read a structure.
1027  * called from spoolss_q_startpageprinter (srv_spoolss.c)
1028  ********************************************************************/
1029 BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1030 {
1031         if (q_u == NULL) return False;
1032
1033         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1034         depth++;
1035
1036         if(!prs_align(ps))
1037                 return False;
1038
1039         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
1040                 return False;
1041
1042         return True;
1043 }
1044
1045 /*******************************************************************
1046  * write a structure.
1047  * called from spoolss_r_startpageprinter (srv_spoolss.c)
1048  ********************************************************************/
1049 BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1050 {
1051         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1052         depth++;
1053         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1054                 return False;
1055
1056         return True;
1057 }
1058
1059 /*******************************************************************
1060  * read a structure.
1061  * called from spoolss_q_endpageprinter (srv_spoolss.c)
1062  ********************************************************************/
1063 BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1064 {
1065         if (q_u == NULL) return False;
1066
1067         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1068         depth++;
1069
1070         if(!prs_align(ps))
1071                 return False;
1072
1073         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
1074                 return False;
1075
1076         return True;
1077 }
1078
1079 /*******************************************************************
1080  * write a structure.
1081  * called from spoolss_r_endpageprinter (srv_spoolss.c)
1082  ********************************************************************/
1083 BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1084 {
1085         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1086         depth++;
1087         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1088                 return False;
1089
1090         return True;
1091 }
1092
1093 /*******************************************************************
1094  * read a structure.
1095  * called from spoolss_q_writeprinter (srv_spoolss.c)
1096  ********************************************************************/
1097 BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1098 {
1099         if (q_u == NULL) return False;
1100
1101         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1102         depth++;
1103
1104         if(!prs_align(ps))
1105                 return False;
1106
1107         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
1108                 return False;
1109         if(!prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size)))
1110                 return False;
1111         
1112         if (q_u->buffer_size!=0)
1113         {
1114                 q_u->buffer=(uint8 *)malloc(q_u->buffer_size*sizeof(uint8));
1115                 if(q_u->buffer == NULL)
1116                         return False;   
1117                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1118                         return False;
1119         }
1120         if(!prs_align(ps))
1121                 return False;
1122         if(!prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2)))
1123                 return False;
1124
1125         return True;
1126 }
1127
1128 /*******************************************************************
1129  * write a structure.
1130  * called from spoolss_r_writeprinter (srv_spoolss.c)
1131  ********************************************************************/
1132 BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1133 {
1134         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1135         depth++;
1136         if(!prs_uint32("buffer_written", ps, depth, &(r_u->buffer_written)))
1137                 return False;
1138         if(!prs_uint32("status", ps, depth, &(r_u->status)))
1139                 return False;
1140
1141         return True;
1142 }
1143
1144 /*******************************************************************
1145  * read a structure.
1146  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1147  ********************************************************************/
1148 BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1149 {
1150         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1151         depth++;
1152
1153         if(!prs_align(ps))
1154                 return False;
1155
1156         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1157                 return False;
1158         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1159                 return False;
1160         if(!prs_uint32("options", ps, depth, &q_u->options))
1161                 return False;
1162         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1163                 return False;
1164         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1165                 return False;
1166
1167         if(!prs_align(ps))
1168                 return False;
1169                 
1170         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1171                 return False;
1172
1173         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1174                 return False;
1175         
1176         if (q_u->option_ptr!=0) {
1177         
1178                 if (UNMARSHALLING(ps))
1179                         if((q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1180                                 return False;
1181         
1182                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1183                         return False;
1184         }
1185         
1186         return True;
1187 }
1188
1189 /*******************************************************************
1190  * write a structure.
1191  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1192  ********************************************************************/
1193 BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1194 {
1195         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1196         depth++;
1197
1198         if(!prs_uint32("status", ps, depth, &r_u->status))
1199                 return False;
1200
1201         return True;
1202 }
1203
1204 /*******************************************************************
1205  * read a structure.
1206  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1207  ********************************************************************/
1208 BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1209 {
1210         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1211         depth++;
1212
1213         if(!prs_align(ps))
1214                 return False;
1215
1216         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1217                 return False;
1218
1219         if(!prs_uint32("change", ps, depth, &q_u->change))
1220                 return False;
1221         
1222         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1223                 return False;
1224         
1225         if (q_u->option_ptr!=0) {
1226         
1227                 if (UNMARSHALLING(ps))
1228                         if((q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1229                                 return False;
1230         
1231                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1232                         return False;
1233         }
1234
1235         return True;
1236 }
1237
1238 /*******************************************************************
1239  * write a structure.
1240  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1241  ********************************************************************/
1242 BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1243 {
1244         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1245         depth++;
1246
1247         if(!prs_align(ps))
1248                 return False;
1249                 
1250         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1251                 return False;
1252
1253         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1254                 return False;
1255         
1256         if(!prs_align(ps))
1257                 return False;
1258         if(!prs_uint32("status", ps, depth, &r_u->status))
1259                 return False;
1260
1261         return True;
1262 }
1263
1264 /*******************************************************************
1265  * return the length of a uint16 (obvious, but the code is clean)
1266  ********************************************************************/
1267 static uint32 size_of_uint16(uint16 *value)
1268 {
1269         return (sizeof(*value));
1270 }
1271
1272 /*******************************************************************
1273  * return the length of a uint32 (obvious, but the code is clean)
1274  ********************************************************************/
1275 static uint32 size_of_uint32(uint32 *value)
1276 {
1277         return (sizeof(*value));
1278 }
1279 /*******************************************************************
1280  * return the length of a UNICODE string in number of char, includes:
1281  * - the leading zero
1282  * - the relative pointer size
1283  ********************************************************************/
1284 static uint32 size_of_relative_string(UNISTR *string)
1285 {
1286         uint32 size=0;
1287         
1288         size=str_len_uni(string);       /* the string length       */
1289         size=size+1;                    /* add the leading zero    */
1290         size=size*2;                    /* convert in char         */
1291         size=size+4;                    /* add the size of the ptr */   
1292
1293         return size;
1294 }
1295
1296 /*******************************************************************
1297  * return the length of a uint32 (obvious, but the code is clean)
1298  ********************************************************************/
1299 static uint32 size_of_device_mode(DEVICEMODE *devmode)
1300 {
1301         if (devmode==NULL)
1302                 return (4);
1303         else 
1304                 return (4+devmode->size+devmode->driverextra);
1305 }
1306
1307 /*******************************************************************
1308  * return the length of a uint32 (obvious, but the code is clean)
1309  ********************************************************************/
1310 static uint32 size_of_systemtime(SYSTEMTIME *systime)
1311 {
1312         if (systime==NULL)
1313                 return (4);
1314         else 
1315                 return (sizeof(SYSTEMTIME) +4);
1316 }
1317
1318 /*******************************************************************
1319  * write a UNICODE string.
1320  * used by all the RPC structs passing a buffer
1321  ********************************************************************/
1322 static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
1323 {
1324         if (uni == NULL)
1325                 return False;
1326
1327         prs_debug(ps, depth, desc, "spoolss_smb_io_unistr");
1328         depth++;
1329         if (!prs_unistr("unistr", ps, depth, uni))
1330                 return False;
1331
1332         return True;
1333 }
1334
1335
1336 /*******************************************************************
1337  * write a UNICODE string and its relative pointer.
1338  * used by all the RPC structs passing a buffer
1339  *
1340  * As I'm a nice guy, I'm forcing myself to explain this code.
1341  * MS did a good job in the overall spoolss code except in some
1342  * functions where they are passing the API buffer directly in the
1343  * RPC request/reply. That's to maintain compatiility at the API level.
1344  * They could have done it the good way the first time.
1345  *
1346  * So what happen is: the strings are written at the buffer's end, 
1347  * in the reverse order of the original structure. Some pointers to
1348  * the strings are also in the buffer. Those are relative to the
1349  * buffer's start.
1350  *
1351  * If you don't understand or want to change that function,
1352  * first get in touch with me: jfm@samba.org
1353  *
1354  ********************************************************************/
1355 static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
1356 {
1357         prs_struct *ps=&(buffer->prs);
1358         
1359         if (MARSHALLING(ps)) {
1360                 uint32 struct_offset = prs_offset(ps);
1361                 uint32 relative_offset;
1362                 
1363                 buffer->string_at_end -= 2*(str_len_uni(string)+1);
1364                 prs_set_offset(ps, buffer->string_at_end);
1365                 
1366                 /* write the string */
1367                 if (!spoolss_smb_io_unistr(desc, string, ps, depth))
1368                         return False;
1369
1370                 prs_set_offset(ps, struct_offset);
1371                 
1372                 relative_offset=buffer->string_at_end - buffer->struct_start;
1373                 /* write its offset */
1374                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1375                         return False;
1376         }
1377         else {
1378                 uint32 old_offset;
1379                 
1380                 /* read the offset */
1381                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1382                         return False;
1383
1384                 old_offset = prs_offset(ps);
1385                 prs_set_offset(ps, buffer->string_at_end+buffer->struct_start);
1386
1387                 /* read the string */
1388                 if (!spoolss_smb_io_unistr(desc, string, ps, depth))
1389                         return False;
1390
1391                 prs_set_offset(ps, old_offset);
1392         }
1393         return True;
1394 }
1395
1396
1397 /*******************************************************************
1398  * write a array of UNICODE strings and its relative pointer.
1399  * used by 2 RPC structs
1400  ********************************************************************/
1401 static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
1402 {
1403         UNISTR chaine;
1404         
1405         prs_struct *ps=&(buffer->prs);
1406         
1407         if (MARSHALLING(ps)) {
1408                 uint32 struct_offset = prs_offset(ps);
1409                 uint32 relative_offset;
1410                 uint16 *p;
1411                 uint16 *q;
1412                 uint16 zero=0;
1413                 p=*string;
1414                 q=*string;
1415                 
1416                 /* first write the last 0 */
1417                 buffer->string_at_end -= 2;
1418                 prs_set_offset(ps, buffer->string_at_end);
1419
1420                 if(!prs_uint16("leading zero", ps, depth, &zero))
1421                         return False;
1422
1423                 do
1424                 {       
1425                         while (*q!=0)
1426                                 q++;
1427
1428                         memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
1429
1430                         buffer->string_at_end -= (q-p+1)*sizeof(uint16);
1431
1432                         prs_set_offset(ps, buffer->string_at_end);
1433
1434                         /* write the string */
1435                         if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
1436                                 return False;
1437                         q++;
1438                         p=q;
1439
1440                 } while (*p!=0); /* end on the last leading 0 */
1441                 
1442                 prs_set_offset(ps, struct_offset);
1443                 
1444                 relative_offset=buffer->string_at_end - buffer->struct_start;
1445                 /* write its offset */
1446                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1447                         return False;
1448         }
1449         else {
1450                 uint32 old_offset;
1451                 uint16 *chaine2=NULL;
1452                 int l_chaine=0;
1453                 int l_chaine2=0;
1454                 
1455                 *string=NULL;
1456                                 
1457                 /* read the offset */
1458                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1459                         return False;
1460
1461                 old_offset = prs_offset(ps);
1462                 prs_set_offset(ps, buffer->string_at_end + buffer->struct_start);
1463         
1464                 do {
1465                         if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
1466                                 return False;
1467                         
1468                         l_chaine=str_len_uni(&chaine);
1469                         if((chaine2=(uint16 *)Realloc(chaine2, (l_chaine2+l_chaine+1)*sizeof(uint16))) == NULL)
1470                                 return False;
1471                         memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
1472                         l_chaine2+=l_chaine+1;
1473                 
1474                 } while(l_chaine!=0);
1475                 
1476                 *string=chaine2;
1477
1478                 prs_set_offset(ps, old_offset);
1479         }
1480         return True;
1481 }
1482
1483
1484 /*******************************************************************
1485  Parse a DEVMODE structure and its relative pointer.
1486 ********************************************************************/
1487 static BOOL new_smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
1488 {
1489         prs_struct *ps=&(buffer->prs);
1490
1491         prs_debug(ps, depth, desc, "new_smb_io_reldevmode");
1492         depth++;
1493
1494         if (MARSHALLING(ps)) {
1495                 uint32 struct_offset = prs_offset(ps);
1496                 uint32 relative_offset;
1497                 
1498                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
1499                 
1500                 prs_set_offset(ps, buffer->string_at_end);
1501                 
1502                 /* write the DEVMODE */
1503                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1504                         return False;
1505
1506                 prs_set_offset(ps, struct_offset);
1507                 
1508                 relative_offset=buffer->string_at_end - buffer->struct_start;
1509                 /* write its offset */
1510                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1511                         return False;
1512         }
1513         else {
1514                 uint32 old_offset;
1515                 
1516                 /* read the offset */
1517                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1518                         return False;
1519
1520                 old_offset = prs_offset(ps);
1521                 prs_set_offset(ps, buffer->string_at_end + buffer->struct_start);
1522
1523                 /* read the string */
1524                 if((*devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL)
1525                         return False;
1526                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
1527                         return False;
1528
1529                 prs_set_offset(ps, old_offset);
1530         }
1531         return True;
1532 }
1533
1534
1535 /*******************************************************************
1536  Parse a PRINTER_INFO_0 structure.
1537 ********************************************************************/  
1538 BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
1539 {
1540         prs_struct *ps=&(buffer->prs);
1541
1542         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
1543         depth++;        
1544         
1545         buffer->struct_start=prs_offset(ps);
1546
1547         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1548                 return False;
1549         if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
1550                 return False;
1551         
1552         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
1553                 return False;
1554         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
1555                 return False;
1556         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
1557                 return False;
1558
1559         if(!prs_uint16("year", ps, depth, &info->year))
1560                 return False;
1561         if(!prs_uint16("month", ps, depth, &info->month))
1562                 return False;
1563         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
1564                 return False;
1565         if(!prs_uint16("day", ps, depth, &info->day))
1566                 return False;
1567         if(!prs_uint16("hour", ps, depth, &info->hour))
1568                 return False;
1569         if(!prs_uint16("minute", ps, depth, &info->minute))
1570                 return False;
1571         if(!prs_uint16("second", ps, depth, &info->second))
1572                 return False;
1573         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
1574                 return False;
1575
1576         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
1577                 return False;
1578         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
1579                 return False;
1580
1581         if(!prs_uint16("major_version", ps, depth, &info->major_version))
1582                 return False;
1583         if(!prs_uint16("build_version", ps, depth, &info->build_version))
1584                 return False;
1585         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
1586                 return False;
1587         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
1588                 return False;
1589         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
1590                 return False;
1591         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
1592                 return False;
1593         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
1594                 return False;
1595         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
1596                 return False;
1597         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
1598                 return False;
1599         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
1600                 return False;
1601         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
1602                 return False;
1603         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
1604                 return False;
1605         if(!prs_uint32("change_id", ps, depth, &info->change_id))
1606                 return False;
1607         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
1608                 return False;
1609         if(!prs_uint32("status"   , ps, depth, &info->status))
1610                 return False;
1611         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
1612                 return False;
1613         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
1614                 return False;
1615         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
1616                 return False;
1617         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
1618                 return False;
1619         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
1620                 return False;
1621         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
1622                 return False;
1623         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
1624                 return False;
1625         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
1626                 return False;
1627         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
1628                 return False;
1629         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
1630                 return False;
1631
1632         return True;
1633 }
1634
1635 /*******************************************************************
1636  Parse a PRINTER_INFO_1 structure.
1637 ********************************************************************/  
1638 BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
1639 {
1640         prs_struct *ps=&(buffer->prs);
1641
1642         prs_debug(ps, depth, desc, "new_smb_io_printer_info_1");
1643         depth++;        
1644         
1645         buffer->struct_start=prs_offset(ps);
1646
1647         if (!prs_uint32("flags", ps, depth, &info->flags))
1648                 return False;
1649         if (!new_smb_io_relstr("description", buffer, depth, &info->description))
1650                 return False;
1651         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1652                 return False;
1653         if (!new_smb_io_relstr("comment", buffer, depth, &info->comment))
1654                 return False;   
1655
1656         return True;
1657 }
1658
1659 /*******************************************************************
1660  Parse a PRINTER_INFO_2 structure.
1661 ********************************************************************/  
1662 BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
1663 {
1664         /* hack for the SEC DESC */
1665         uint32 pipo=0;
1666
1667         prs_struct *ps=&(buffer->prs);
1668
1669         prs_debug(ps, depth, desc, "new_smb_io_printer_info_2");
1670         depth++;        
1671         
1672         buffer->struct_start=prs_offset(ps);
1673         
1674         if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
1675                 return False;
1676         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1677                 return False;
1678         if (!new_smb_io_relstr("sharename", buffer, depth, &info->sharename))
1679                 return False;
1680         if (!new_smb_io_relstr("portname", buffer, depth, &info->portname))
1681                 return False;
1682         if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername))
1683                 return False;
1684         if (!new_smb_io_relstr("comment", buffer, depth, &info->comment))
1685                 return False;
1686         if (!new_smb_io_relstr("location", buffer, depth, &info->location))
1687                 return False;
1688
1689         /* NT parses the DEVMODE at the end of the struct */
1690         if (!new_smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1691                 return False;
1692         
1693         if (!new_smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
1694                 return False;
1695         if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1696                 return False;
1697         if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
1698                 return False;
1699         if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
1700                 return False;
1701
1702         if (!prs_uint32("security descriptor", ps, depth, &pipo))
1703                 return False;
1704         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1705                 return False;
1706         if (!prs_uint32("priority", ps, depth, &info->priority))
1707                 return False;
1708         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
1709                 return False;
1710         if (!prs_uint32("starttime", ps, depth, &info->starttime))
1711                 return False;
1712         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
1713                 return False;
1714         if (!prs_uint32("status", ps, depth, &info->status))
1715                 return False;
1716         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
1717                 return False;
1718         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
1719                 return False;
1720
1721         return True;
1722 }
1723
1724 /*******************************************************************
1725  Parse a DRIVER_INFO_1 structure.
1726 ********************************************************************/
1727 BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
1728 {
1729         prs_struct *ps=&(buffer->prs);
1730
1731         prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_1");
1732         depth++;        
1733         
1734         buffer->struct_start=prs_offset(ps);
1735
1736         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1737                 return False;
1738
1739         return True;
1740 }
1741
1742
1743 /*******************************************************************
1744  Parse a DRIVER_INFO_2 structure.
1745 ********************************************************************/
1746 BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
1747 {
1748         prs_struct *ps=&(buffer->prs);
1749
1750         prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_2");
1751         depth++;        
1752         
1753         buffer->struct_start=prs_offset(ps);
1754
1755         if (!prs_uint32("version", ps, depth, &info->version))
1756                 return False;
1757         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1758                 return False;
1759         if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
1760                 return False;
1761         if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1762                 return False;
1763         if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
1764                 return False;
1765         if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
1766                 return False;
1767
1768         return True;
1769 }
1770
1771
1772 /*******************************************************************
1773  Parse a DRIVER_INFO_3 structure.
1774 ********************************************************************/
1775 BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
1776 {
1777         prs_struct *ps=&(buffer->prs);
1778
1779         prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_3");
1780         depth++;        
1781         
1782         buffer->struct_start=prs_offset(ps);
1783
1784         if (!prs_uint32("version", ps, depth, &info->version))
1785                 return False;
1786         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
1787                 return False;
1788         if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
1789                 return False;
1790         if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1791                 return False;
1792         if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
1793                 return False;
1794         if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
1795                 return False;
1796         if (!new_smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1797                 return False;
1798
1799         if (!new_smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1800                 return False;
1801
1802         if (!new_smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1803                 return False;
1804         if (!new_smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1805                 return False;
1806
1807         return True;
1808 }
1809
1810
1811 /*******************************************************************
1812  Parse a JOB_INFO_1 structure.
1813 ********************************************************************/  
1814 BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
1815 {
1816         prs_struct *ps=&(buffer->prs);
1817
1818         prs_debug(ps, depth, desc, "new_smb_io_job_info_1");
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("datatype", buffer, depth, &info->datatype))
1834                 return False;
1835         if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status))
1836                 return False;
1837         if (!prs_uint32("status", ps, depth, &info->status))
1838                 return False;
1839         if (!prs_uint32("priority", ps, depth, &info->priority))
1840                 return False;
1841         if (!prs_uint32("position", ps, depth, &info->position))
1842                 return False;
1843         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
1844                 return False;
1845         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
1846                 return False;
1847         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
1848                 return False;
1849
1850         return True;
1851 }
1852
1853 /*******************************************************************
1854  Parse a JOB_INFO_2 structure.
1855 ********************************************************************/  
1856 BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
1857 {       
1858         int pipo=0;
1859         prs_struct *ps=&(buffer->prs);
1860         
1861         prs_debug(ps, depth, desc, "new_smb_io_job_info_2");
1862         depth++;        
1863
1864         buffer->struct_start=prs_offset(ps);
1865         
1866         if (!prs_uint32("jobid",ps, depth, &info->jobid))
1867                 return False;
1868         if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
1869                 return False;
1870         if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename))
1871                 return False;
1872         if (!new_smb_io_relstr("username", buffer, depth, &info->username))
1873                 return False;
1874         if (!new_smb_io_relstr("document", buffer, depth, &info->document))
1875                 return False;
1876         if (!new_smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
1877                 return False;
1878         if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
1879                 return False;
1880
1881         if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1882                 return False;
1883         if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
1884                 return False;
1885         if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername))
1886                 return False;
1887         if (!new_smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1888                 return False;
1889         if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status))
1890                 return False;
1891
1892 /*      SEC_DESC sec_desc;*/
1893         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
1894                 return False;
1895
1896         if (!prs_uint32("status",ps, depth, &info->status))
1897                 return False;
1898         if (!prs_uint32("priority",ps, depth, &info->priority))
1899                 return False;
1900         if (!prs_uint32("position",ps, depth, &info->position)) 
1901                 return False;
1902         if (!prs_uint32("starttime",ps, depth, &info->starttime))
1903                 return False;
1904         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
1905                 return False;
1906         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
1907                 return False;
1908         if (!prs_uint32("size",ps, depth, &info->size))
1909                 return False;
1910         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
1911                 return False;
1912         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
1913                 return False;
1914         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
1915                 return False;
1916
1917         return True;
1918 }
1919
1920 /*******************************************************************
1921 ********************************************************************/  
1922 BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
1923 {
1924         prs_struct *ps=&(buffer->prs);
1925         
1926         prs_debug(ps, depth, desc, "new_smb_io_form_1");
1927         depth++;
1928                 
1929         buffer->struct_start=prs_offset(ps);
1930         
1931         if (!prs_uint32("flag", ps, depth, &(info->flag)))
1932                 return False;
1933                 
1934         if (!new_smb_io_relstr("name", buffer, depth, &(info->name)))
1935                 return False;
1936
1937         if (!prs_uint32("width", ps, depth, &(info->width)))
1938                 return False;
1939         if (!prs_uint32("length", ps, depth, &(info->length)))
1940                 return False;
1941         if (!prs_uint32("left", ps, depth, &(info->left)))
1942                 return False;
1943         if (!prs_uint32("top", ps, depth, &(info->top)))
1944                 return False;
1945         if (!prs_uint32("right", ps, depth, &(info->right)))
1946                 return False;
1947         if (!prs_uint32("bottom", ps, depth, &(info->bottom)))
1948                 return False;
1949
1950         return True;
1951 }
1952
1953 /*******************************************************************
1954  Read/write a BUFFER struct.
1955 ********************************************************************/  
1956 static BOOL new_spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER *buffer)
1957 {
1958         if (buffer == NULL)
1959                 return False;
1960
1961         prs_debug(ps, depth, desc, "new_spoolss_io_buffer");
1962         depth++;
1963         
1964         if (!prs_uint32("ptr", ps, depth, &(buffer->ptr)))
1965                 return False;
1966         
1967         /* reading */
1968         if (UNMARSHALLING(ps)) {
1969                 buffer->size=0;
1970                 buffer->string_at_end=0;
1971                 
1972                 if (buffer->ptr==0) {
1973                         if (!prs_init(&(buffer->prs), 0, 4, UNMARSHALL))
1974                                 return False;
1975                         return True;
1976                 }
1977                 
1978                 if (!prs_uint32("size", ps, depth, &buffer->size))
1979                         return False;
1980                                         
1981                 if (!prs_init(&(buffer->prs), buffer->size, 4, UNMARSHALL))
1982                         return False;
1983
1984                 if (!prs_append_some_prs_data(&(buffer->prs), ps, prs_offset(ps), buffer->size))
1985                         return False;
1986
1987                 if (!prs_set_offset(&buffer->prs, 0))
1988                         return False;
1989
1990                 if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
1991                         return False;
1992
1993                 buffer->string_at_end=buffer->size;
1994                 
1995                 return True;
1996         }
1997         else {
1998                 /* writing */
1999                 if (buffer->ptr==0)
2000                         return True;
2001                 
2002                 if (!prs_uint32("size", ps, depth, &(buffer->size)))
2003                         return False;
2004                 if (!prs_append_some_prs_data(ps, &(buffer->prs), 0, buffer->size))
2005                         return False;
2006
2007                 return True;
2008         }
2009 }
2010
2011 /*******************************************************************
2012  move a BUFFER from the query to the reply.
2013 ********************************************************************/  
2014 void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
2015 {
2016         prs_switch_type(&(src->prs), MARSHALL);
2017         prs_set_offset(&(src->prs), 0);
2018         prs_force_dynamic(&(src->prs));
2019
2020         *dest=src;
2021 }
2022
2023 /*******************************************************************
2024  create a BUFFER struct.
2025 ********************************************************************/  
2026 BOOL new_spoolss_allocate_buffer(NEW_BUFFER **buffer)
2027 {
2028         if (buffer==NULL)
2029                 return False;
2030                 
2031         if((*buffer=(NEW_BUFFER *)malloc(sizeof(NEW_BUFFER))) == NULL) {
2032                 DEBUG(0,("new_spoolss_allocate_buffer: malloc fail for size %u.\n",
2033                                 (unsigned int)sizeof(NEW_BUFFER) ));
2034                 return False;
2035         }
2036         
2037         (*buffer)->ptr=0x0;
2038         (*buffer)->size=0;
2039         (*buffer)->string_at_end=0;     
2040         return True;
2041 }
2042
2043 /*******************************************************************
2044  Destroy a BUFFER struct.
2045 ********************************************************************/  
2046 void new_spoolss_free_buffer(NEW_BUFFER *buffer)
2047 {
2048         if (buffer==NULL)
2049                 return;
2050                 
2051         prs_mem_free(&(buffer->prs));
2052         buffer->ptr=0x0;
2053         buffer->size=0;
2054         buffer->string_at_end=0;
2055         
2056         free(buffer);
2057 }
2058
2059 /*******************************************************************
2060  Get the size of a BUFFER struct.
2061 ********************************************************************/  
2062 uint32 new_get_buffer_size(NEW_BUFFER *buffer)
2063 {
2064         return (buffer->size);
2065 }
2066
2067
2068 /*******************************************************************
2069  Parse a DRIVER_DIRECTORY_1 structure.
2070 ********************************************************************/  
2071 BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2072 {
2073         prs_struct *ps=&(buffer->prs);
2074
2075         prs_debug(ps, depth, desc, "new_smb_io_driverdir_1");
2076         depth++;
2077
2078         buffer->struct_start=prs_offset(ps);
2079
2080         if (!spoolss_smb_io_unistr(desc, &info->name, ps, depth))
2081                 return False;
2082
2083         return True;
2084 }
2085
2086 /*******************************************************************
2087  Parse a PORT_INFO_1 structure.
2088 ********************************************************************/  
2089 BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2090 {
2091         prs_struct *ps=&(buffer->prs);
2092
2093         prs_debug(ps, depth, desc, "new_smb_io_port_1");
2094         depth++;
2095
2096         buffer->struct_start=prs_offset(ps);
2097
2098         if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name))
2099                 return False;
2100
2101         return True;
2102 }
2103
2104 /*******************************************************************
2105  Parse a PORT_INFO_2 structure.
2106 ********************************************************************/  
2107 BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2108 {
2109         prs_struct *ps=&(buffer->prs);
2110
2111         prs_debug(ps, depth, desc, "new_smb_io_port_2");
2112         depth++;
2113
2114         buffer->struct_start=prs_offset(ps);
2115
2116         if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name))
2117                 return False;
2118         if(!new_smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2119                 return False;
2120         if(!new_smb_io_relstr("description", buffer, depth, &info->description))
2121                 return False;
2122         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2123                 return False;
2124         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2125                 return False;
2126
2127         return True;
2128 }
2129
2130
2131 /*******************************************************************
2132 ********************************************************************/  
2133 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2134 {
2135         prs_struct *ps=&(buffer->prs);
2136
2137         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2138         depth++;        
2139
2140         buffer->struct_start=prs_offset(ps);
2141         
2142         if (new_smb_io_relstr("name", buffer, depth, &info->name))
2143                 return False;
2144
2145         return True;
2146 }
2147
2148 /*******************************************************************
2149 ********************************************************************/  
2150 BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2151 {
2152         prs_struct *ps=&(buffer->prs);
2153
2154         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2155         depth++;        
2156
2157         buffer->struct_start=prs_offset(ps);
2158         
2159         if (new_smb_io_relstr("name", buffer, depth, &info->name))
2160                 return False;
2161
2162         return True;
2163 }
2164
2165 /*******************************************************************
2166 ********************************************************************/  
2167 BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2168 {
2169         prs_struct *ps=&(buffer->prs);
2170
2171         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2172         depth++;        
2173
2174         buffer->struct_start=prs_offset(ps);
2175
2176         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
2177                 return False;
2178
2179         return True;
2180 }
2181
2182 /*******************************************************************
2183 ********************************************************************/  
2184 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2185 {
2186         prs_struct *ps=&(buffer->prs);
2187
2188         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2189         depth++;        
2190
2191         buffer->struct_start=prs_offset(ps);
2192
2193         if (!new_smb_io_relstr("name", buffer, depth, &info->name))
2194                 return False;
2195         if (!new_smb_io_relstr("environment", buffer, depth, &info->environment))
2196                 return False;
2197         if (!new_smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2198                 return False;
2199
2200         return True;
2201 }
2202
2203 /*******************************************************************
2204 return the size required by a struct in the stream
2205 ********************************************************************/  
2206 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2207 {
2208         int size=0;
2209         
2210         size+=size_of_relative_string( &info->printername );
2211         size+=size_of_relative_string( &info->servername );
2212
2213         size+=size_of_uint32( &info->cjobs);
2214         size+=size_of_uint32( &info->total_jobs);
2215         size+=size_of_uint32( &info->total_bytes);
2216
2217         size+=size_of_uint16( &info->year);
2218         size+=size_of_uint16( &info->month);
2219         size+=size_of_uint16( &info->dayofweek);
2220         size+=size_of_uint16( &info->day);
2221         size+=size_of_uint16( &info->hour);
2222         size+=size_of_uint16( &info->minute);
2223         size+=size_of_uint16( &info->second);
2224         size+=size_of_uint16( &info->milliseconds);
2225
2226         size+=size_of_uint32( &info->global_counter);
2227         size+=size_of_uint32( &info->total_pages);
2228
2229         size+=size_of_uint16( &info->major_version);
2230         size+=size_of_uint16( &info->build_version);
2231
2232         size+=size_of_uint32( &info->unknown7);
2233         size+=size_of_uint32( &info->unknown8);
2234         size+=size_of_uint32( &info->unknown9);
2235         size+=size_of_uint32( &info->session_counter);
2236         size+=size_of_uint32( &info->unknown11);
2237         size+=size_of_uint32( &info->printer_errors);
2238         size+=size_of_uint32( &info->unknown13);
2239         size+=size_of_uint32( &info->unknown14);
2240         size+=size_of_uint32( &info->unknown15);
2241         size+=size_of_uint32( &info->unknown16);
2242         size+=size_of_uint32( &info->change_id);
2243         size+=size_of_uint32( &info->unknown18);
2244         size+=size_of_uint32( &info->status);
2245         size+=size_of_uint32( &info->unknown20);
2246         size+=size_of_uint32( &info->c_setprinter);
2247         
2248         size+=size_of_uint16( &info->unknown22);
2249         size+=size_of_uint16( &info->unknown23);
2250         size+=size_of_uint16( &info->unknown24);
2251         size+=size_of_uint16( &info->unknown25);
2252         size+=size_of_uint16( &info->unknown26);
2253         size+=size_of_uint16( &info->unknown27);
2254         size+=size_of_uint16( &info->unknown28);
2255         size+=size_of_uint16( &info->unknown29);
2256         
2257         return size;
2258 }
2259
2260 /*******************************************************************
2261 return the size required by a struct in the stream
2262 ********************************************************************/  
2263 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
2264 {
2265         int size=0;
2266                 
2267         size+=size_of_uint32( &(info->flags) ); 
2268         size+=size_of_relative_string( &(info->description) );
2269         size+=size_of_relative_string( &(info->name) );
2270         size+=size_of_relative_string( &(info->comment) );
2271
2272         return size;
2273 }
2274
2275 /*******************************************************************
2276 return the size required by a struct in the stream
2277 ********************************************************************/
2278 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
2279 {
2280         int size=0;
2281                 
2282         size+=4;      /* the security descriptor */
2283         
2284         size+=size_of_device_mode( info->devmode );
2285         
2286         size+=size_of_relative_string( &info->servername );
2287         size+=size_of_relative_string( &info->printername );
2288         size+=size_of_relative_string( &info->sharename );
2289         size+=size_of_relative_string( &info->portname );
2290         size+=size_of_relative_string( &info->drivername );
2291         size+=size_of_relative_string( &info->comment );
2292         size+=size_of_relative_string( &info->location );
2293         
2294         size+=size_of_relative_string( &info->sepfile );
2295         size+=size_of_relative_string( &info->printprocessor );
2296         size+=size_of_relative_string( &info->datatype );
2297         size+=size_of_relative_string( &info->parameters );
2298
2299         size+=size_of_uint32( &info->attributes );
2300         size+=size_of_uint32( &info->priority );
2301         size+=size_of_uint32( &info->defaultpriority );
2302         size+=size_of_uint32( &info->starttime );
2303         size+=size_of_uint32( &info->untiltime );
2304         size+=size_of_uint32( &info->status );
2305         size+=size_of_uint32( &info->cjobs );
2306         size+=size_of_uint32( &info->averageppm );      
2307         return size;
2308 }
2309
2310 /*******************************************************************
2311 return the size required by a struct in the stream
2312 ********************************************************************/
2313 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
2314 {
2315         int size=0;
2316         size+=size_of_relative_string( &info->name );
2317
2318         return size;
2319 }
2320
2321 /*******************************************************************
2322 return the size required by a struct in the stream
2323 ********************************************************************/
2324 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
2325 {
2326         int size=0;
2327         size+=size_of_uint32( &info->version ); 
2328         size+=size_of_relative_string( &info->name );
2329         size+=size_of_relative_string( &info->architecture );
2330         size+=size_of_relative_string( &info->driverpath );
2331         size+=size_of_relative_string( &info->datafile );
2332         size+=size_of_relative_string( &info->configfile );
2333
2334         return size;
2335 }
2336
2337 /*******************************************************************
2338 return the size required by a struct in the stream
2339 ********************************************************************/
2340 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
2341 {
2342         int size=0;
2343         uint16 *string;
2344         int i=0;
2345
2346         size+=size_of_uint32( &info->version ); 
2347         size+=size_of_relative_string( &info->name );
2348         size+=size_of_relative_string( &info->architecture );
2349         size+=size_of_relative_string( &info->driverpath );
2350         size+=size_of_relative_string( &info->datafile );
2351         size+=size_of_relative_string( &info->configfile );
2352         size+=size_of_relative_string( &info->helpfile );
2353         size+=size_of_relative_string( &info->monitorname );
2354         size+=size_of_relative_string( &info->defaultdatatype );
2355         
2356         string=info->dependentfiles;
2357         
2358         for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
2359
2360         i=i+2; /* to count all chars including the leading zero */
2361         i=2*i; /* because we need the value in bytes */
2362         i=i+4; /* the offset pointer size */
2363
2364         size+=i;
2365
2366         return size;
2367 }
2368
2369 /*******************************************************************
2370 return the size required by a struct in the stream
2371 ********************************************************************/  
2372 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
2373 {
2374         int size=0;
2375         size+=size_of_uint32( &info->jobid );
2376         size+=size_of_relative_string( &info->printername );
2377         size+=size_of_relative_string( &info->machinename );
2378         size+=size_of_relative_string( &info->username );
2379         size+=size_of_relative_string( &info->document );
2380         size+=size_of_relative_string( &info->datatype );
2381         size+=size_of_relative_string( &info->text_status );
2382         size+=size_of_uint32( &info->status );
2383         size+=size_of_uint32( &info->priority );
2384         size+=size_of_uint32( &info->position );
2385         size+=size_of_uint32( &info->totalpages );
2386         size+=size_of_uint32( &info->pagesprinted );
2387         size+=size_of_systemtime( &info->submitted );
2388
2389         return size;
2390 }
2391
2392 /*******************************************************************
2393 return the size required by a struct in the stream
2394 ********************************************************************/  
2395 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
2396 {
2397         int size=0;
2398
2399         size+=4; /* size of sec desc ptr */
2400
2401         size+=size_of_uint32( &info->jobid );
2402         size+=size_of_relative_string( &info->printername );
2403         size+=size_of_relative_string( &info->machinename );
2404         size+=size_of_relative_string( &info->username );
2405         size+=size_of_relative_string( &info->document );
2406         size+=size_of_relative_string( &info->notifyname );
2407         size+=size_of_relative_string( &info->datatype );
2408         size+=size_of_relative_string( &info->printprocessor );
2409         size+=size_of_relative_string( &info->parameters );
2410         size+=size_of_relative_string( &info->drivername );
2411         size+=size_of_device_mode( info->devmode );
2412         size+=size_of_relative_string( &info->text_status );
2413 /*      SEC_DESC sec_desc;*/
2414         size+=size_of_uint32( &info->status );
2415         size+=size_of_uint32( &info->priority );
2416         size+=size_of_uint32( &info->position );
2417         size+=size_of_uint32( &info->starttime );
2418         size+=size_of_uint32( &info->untiltime );
2419         size+=size_of_uint32( &info->totalpages );
2420         size+=size_of_uint32( &info->size );
2421         size+=size_of_systemtime( &info->submitted );
2422         size+=size_of_uint32( &info->timeelapsed );
2423         size+=size_of_uint32( &info->pagesprinted );
2424
2425         return size;
2426 }
2427
2428 /*******************************************************************
2429 return the size required by a struct in the stream
2430 ********************************************************************/
2431 uint32 spoolss_size_form_1(FORM_1 *info)
2432 {
2433         int size=0;
2434
2435         size+=size_of_uint32( &(info->flag) );
2436         size+=size_of_relative_string( &(info->name) );
2437         size+=size_of_uint32( &(info->width) );
2438         size+=size_of_uint32( &(info->length) );
2439         size+=size_of_uint32( &(info->left) );
2440         size+=size_of_uint32( &(info->top) );
2441         size+=size_of_uint32( &(info->right) );
2442         size+=size_of_uint32( &(info->bottom) );
2443
2444         return size;
2445 }
2446
2447 /*******************************************************************
2448 return the size required by a struct in the stream
2449 ********************************************************************/  
2450 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
2451 {
2452         int size=0;
2453
2454         size+=size_of_relative_string( &info->port_name );
2455
2456         return size;
2457 }
2458
2459 /*******************************************************************
2460 return the size required by a struct in the stream
2461 ********************************************************************/  
2462 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
2463 {
2464         int size=0;
2465
2466         size=str_len_uni(&info->name);  /* the string length       */
2467         size=size+1;                    /* add the leading zero    */
2468         size=size*2;                    /* convert in char         */
2469
2470         return size;
2471 }
2472
2473 /*******************************************************************
2474 return the size required by a struct in the stream
2475 ********************************************************************/  
2476 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
2477 {
2478         int size=0;
2479
2480         size+=size_of_relative_string( &info->port_name );
2481         size+=size_of_relative_string( &info->monitor_name );
2482         size+=size_of_relative_string( &info->description );
2483
2484         size+=size_of_uint32( &info->port_type );
2485         size+=size_of_uint32( &info->reserved );
2486
2487         return size;
2488 }
2489
2490 /*******************************************************************
2491 return the size required by a struct in the stream
2492 ********************************************************************/  
2493 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
2494 {
2495         int size=0;
2496         size+=size_of_relative_string( &info->name );
2497
2498         return size;
2499 }
2500
2501 /*******************************************************************
2502 return the size required by a struct in the stream
2503 ********************************************************************/  
2504 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
2505 {
2506         int size=0;
2507         size+=size_of_relative_string( &info->name );
2508
2509         return size;
2510 }
2511
2512 /*******************************************************************
2513 return the size required by a struct in the stream
2514 ********************************************************************/  
2515 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
2516 {
2517         int size=0;
2518         size+=size_of_relative_string( &info->name );
2519
2520         return size;
2521 }
2522
2523 /*******************************************************************
2524 return the size required by a struct in the stream
2525 ********************************************************************/  
2526 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
2527 {
2528         int size=0;
2529         size+=size_of_relative_string( &info->name);
2530         size+=size_of_relative_string( &info->environment);
2531         size+=size_of_relative_string( &info->dll_name);
2532
2533         return size;
2534 }
2535
2536 /*******************************************************************
2537  * init a structure.
2538  ********************************************************************/
2539 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
2540                                const POLICY_HND *hnd, fstring architecture,
2541                                uint32 level, uint32 clientmajor, uint32 clientminor,
2542                                NEW_BUFFER *buffer, uint32 offered)
2543 {      
2544         if (q_u == NULL)
2545         {
2546                 return False;
2547         }
2548
2549         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2550
2551         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
2552
2553         q_u->level=level;
2554         q_u->clientmajorversion=clientmajor;
2555         q_u->clientminorversion=clientminor;
2556
2557         q_u->buffer=buffer;
2558         q_u->offered=offered;
2559
2560         return True;
2561 }
2562
2563 /*******************************************************************
2564  * read a structure.
2565  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2566  ********************************************************************/
2567 BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
2568 {
2569         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
2570         depth++;
2571
2572         if(!prs_align(ps))
2573                 return False;
2574         
2575         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2576                 return False;
2577         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
2578                 return False;
2579         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
2580                 return False;
2581         
2582         if(!prs_align(ps))
2583                 return False;
2584                 if(!prs_uint32("level", ps, depth, &q_u->level))
2585                 return False;
2586                 
2587         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2588                 return False;
2589
2590         if(!prs_align(ps))
2591                 return False;
2592
2593         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2594                 return False;
2595                 
2596         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
2597                 return False;
2598         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
2599                 return False;
2600
2601         return True;
2602 }
2603
2604 /*******************************************************************
2605  * read a structure.
2606  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2607  ********************************************************************/
2608 BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
2609 {
2610         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
2611         depth++;
2612
2613         if (!prs_align(ps))
2614                 return False;
2615                 
2616         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2617                 return False;
2618
2619         if (!prs_align(ps))
2620                 return False;
2621         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2622                 return False;
2623         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
2624                 return False;
2625         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
2626                 return False;           
2627         if (!prs_uint32("status", ps, depth, &r_u->status))
2628                 return False;
2629
2630         return True;            
2631 }
2632
2633 /*******************************************************************
2634  * init a structure.
2635  ********************************************************************/
2636 BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, 
2637                                 fstring servername, uint32 level, 
2638                                 NEW_BUFFER *buffer, uint32 offered)
2639 {
2640         q_u->flags=flags;
2641         
2642         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
2643         init_unistr2(&(q_u->servername), servername, strlen(servername));
2644
2645         q_u->level=level;
2646         q_u->buffer=buffer;
2647         q_u->offered=offered;
2648
2649         return True;
2650 }
2651
2652 /*******************************************************************
2653  * read a structure.
2654  * called from spoolss_enumprinters (srv_spoolss.c)
2655  ********************************************************************/
2656 BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
2657 {
2658         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
2659         depth++;
2660
2661         if (!prs_align(ps))
2662                 return False;
2663
2664         if (!prs_uint32("flags", ps, depth, &q_u->flags))
2665                 return False;
2666         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
2667                 return False;
2668
2669         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
2670                 return False;
2671                 
2672         if (!prs_align(ps))
2673                 return False;
2674         if (!prs_uint32("level", ps, depth, &q_u->level))
2675                 return False;
2676
2677         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2678                 return False;
2679
2680         if (!prs_align(ps))
2681                 return False;
2682         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2683                 return False;
2684
2685         return True;
2686 }
2687
2688 /*******************************************************************
2689  Parse a SPOOL_R_ENUMPRINTERS structure.
2690  ********************************************************************/
2691 BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
2692 {
2693         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinters");
2694         depth++;
2695
2696         if (!prs_align(ps))
2697                 return False;
2698                 
2699         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2700                 return False;
2701
2702         if (!prs_align(ps))
2703                 return False;
2704                 
2705         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2706                 return False;
2707                 
2708         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2709                 return False;
2710                 
2711         if (!prs_uint32("status", ps, depth, &r_u->status))
2712                 return False;
2713
2714         return True;            
2715 }
2716
2717 /*******************************************************************
2718  * write a structure.
2719  * called from spoolss_r_enum_printers (srv_spoolss.c)
2720  *
2721  ********************************************************************/
2722 BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
2723 {       
2724         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
2725         depth++;
2726
2727         if (!prs_align(ps))
2728                 return False;
2729                 
2730         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2731                 return False;
2732
2733         if (!prs_align(ps))
2734                 return False;
2735                 
2736         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2737                 return False;
2738                 
2739         if (!prs_uint32("status", ps, depth, &r_u->status))
2740                 return False;
2741
2742         return True;            
2743 }
2744
2745 /*******************************************************************
2746  * read a structure.
2747  * called from spoolss_getprinter (srv_spoolss.c)
2748  ********************************************************************/
2749 BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
2750 {
2751         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
2752         depth++;
2753
2754         if (!prs_align(ps))
2755                 return False;
2756
2757         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2758                 return False;
2759         if (!prs_uint32("level", ps, depth, &q_u->level))
2760                 return False;
2761
2762         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2763                 return False;
2764
2765         if (!prs_align(ps))
2766                 return False;
2767         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2768                 return False;
2769
2770         return True;
2771 }
2772
2773 /*******************************************************************
2774  * init a structure.
2775  ********************************************************************/
2776 BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, 
2777                                 NEW_BUFFER *buffer, uint32 offered)
2778 {
2779         if (q_u == NULL)
2780         {
2781                 return False;
2782         }
2783         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2784
2785         q_u->level=level;
2786         q_u->buffer=buffer;
2787         q_u->offered=offered;
2788
2789         return True;
2790 }
2791
2792 /*******************************************************************
2793 ********************************************************************/  
2794 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
2795 {               
2796         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
2797         depth++;
2798
2799         if(!prs_align(ps))
2800                 return False;
2801         
2802         if(!prs_uint32("status", ps, depth, &(r_u->status)))
2803                 return False;
2804
2805         return True;
2806 }
2807
2808 /*******************************************************************
2809 ********************************************************************/  
2810 BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
2811 {
2812         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
2813         depth++;
2814
2815         if(!prs_align(ps))
2816                 return False;
2817
2818         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
2819                 return False;
2820         if(!prs_uint32("level", ps, depth, &q_u->level))
2821                 return False;
2822
2823         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
2824                 return False;
2825
2826         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
2827                 return False;
2828         
2829         if(!prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer))
2830                 return False;
2831         if(!prs_uint32("security.data", ps, depth, &q_u->security.data))
2832                 return False;
2833         
2834         if(!prs_uint32("command", ps, depth, &q_u->command))
2835                 return False;
2836
2837         return True;
2838 }
2839
2840 /*******************************************************************
2841 ********************************************************************/  
2842 BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
2843 {               
2844         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
2845         depth++;
2846
2847         if(!prs_align(ps))
2848                 return False;
2849         
2850         if(!prs_uint32("status", ps, depth, &(r_u->status)))
2851                 return False;
2852
2853         return True;
2854 }
2855
2856 /*******************************************************************
2857 ********************************************************************/  
2858 BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
2859 {
2860
2861         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
2862         depth++;
2863
2864         if(!prs_align(ps))
2865                 return False;
2866
2867         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
2868                 return False;
2869
2870         return True;
2871 }
2872
2873
2874 /*******************************************************************
2875 ********************************************************************/  
2876 BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
2877 {               
2878         prs_debug(ps, depth, desc, "");
2879         depth++;
2880
2881         if(!prs_align(ps))
2882                 return False;
2883         
2884         if(!prs_uint32("status", ps, depth, &r_u->status))
2885                 return False;
2886
2887         return True;
2888 }
2889
2890 /*******************************************************************
2891 ********************************************************************/  
2892 BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
2893 {
2894         prs_debug(ps, depth, desc, "");
2895         depth++;
2896
2897         if(!prs_align(ps))
2898                 return False;
2899
2900         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2901                 return False;
2902         if(!prs_uint32("level", ps, depth, &q_u->level))
2903                 return False;
2904         
2905         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2906                 return False;
2907
2908         if(!prs_align(ps))
2909                 return False;
2910         
2911         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2912                 return False;
2913
2914         return True;
2915 }
2916
2917 /*******************************************************************
2918 ********************************************************************/  
2919 BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
2920 {               
2921         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
2922         depth++;
2923
2924         if (!prs_align(ps))
2925                 return False;
2926                 
2927         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
2928                 return False;
2929
2930         if (!prs_align(ps))
2931                 return False;
2932                 
2933         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2934                 return False;
2935                 
2936         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2937                 return False;
2938                 
2939         if (!prs_uint32("status", ps, depth, &r_u->status))
2940                 return False;
2941
2942         return True;            
2943 }
2944
2945
2946 /*******************************************************************
2947 ********************************************************************/  
2948 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
2949                                 uint32 firstjob,
2950                                 uint32 numofjobs,
2951                                 uint32 level,
2952                                 NEW_BUFFER *buffer,
2953                                 uint32 offered)
2954 {
2955         if (q_u == NULL)
2956         {
2957                 return False;
2958         }
2959         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2960         q_u->firstjob = firstjob;
2961         q_u->numofjobs = numofjobs;
2962         q_u->level = level;
2963         q_u->buffer= buffer;
2964         q_u->offered = offered;
2965         return True;
2966 }
2967
2968 /*******************************************************************
2969 ********************************************************************/  
2970 BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
2971 {
2972         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
2973         depth++;
2974
2975         if (!prs_align(ps))
2976                 return False;
2977
2978         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
2979                 return False;
2980                 
2981         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
2982                 return False;
2983         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
2984                 return False;
2985         if (!prs_uint32("level", ps, depth, &q_u->level))
2986                 return False;
2987
2988         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
2989                 return False;   
2990
2991         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2992                 return False;
2993
2994         return True;
2995 }
2996
2997 /*******************************************************************
2998 ********************************************************************/  
2999 BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
3000 {               
3001         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
3002         depth++;
3003
3004         if(!prs_align(ps))
3005                 return False;
3006         
3007         if(!prs_uint32("status", ps, depth, &(r_u->status)))
3008                 return False;
3009
3010         return True;
3011 }
3012
3013 /*******************************************************************
3014 ********************************************************************/  
3015 BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
3016 {
3017         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
3018         depth++;
3019
3020         if(!prs_align(ps))
3021                 return False;
3022
3023         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
3024                 return False;
3025         if(!prs_uint32("jobid", ps, depth, &(q_u->jobid)))
3026                 return False;
3027
3028         return True;
3029 }
3030
3031 /*******************************************************************
3032 ********************************************************************/  
3033 BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
3034 {               
3035         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
3036         depth++;
3037
3038         if(!prs_align(ps))
3039                 return False;
3040         
3041         if(!prs_uint32("status", ps, depth, &(r_u->status)))
3042                 return False;
3043
3044         return True;
3045 }
3046
3047 /*******************************************************************
3048 ********************************************************************/  
3049 BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
3050 {
3051         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
3052         depth++;
3053
3054         if(!prs_align(ps))
3055                 return False;
3056
3057         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
3058                 return False;
3059         if(!prs_uint32("jobid", ps, depth, &(q_u->jobid)))
3060                 return False;
3061         /* 
3062          * level is usually 0. If (level!=0) then I'm in trouble !
3063          * I will try to generate setjob command with level!=0, one day.
3064          */
3065         if(!prs_uint32("level", ps, depth, &(q_u->level)))
3066                 return False;
3067         if(!prs_uint32("command", ps, depth, &(q_u->command)))
3068                 return False;
3069
3070         return True;
3071 }
3072
3073 /*******************************************************************
3074  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
3075 ********************************************************************/  
3076 BOOL new_spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
3077 {
3078         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinterdrivers");
3079         depth++;
3080
3081         if (!prs_align(ps))
3082                 return False;
3083                 
3084         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3085                 return False;
3086
3087         if (!prs_align(ps))
3088                 return False;
3089                 
3090         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3091                 return False;
3092                 
3093         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3094                 return False;
3095                 
3096         if (!prs_uint32("status", ps, depth, &r_u->status))
3097                 return False;
3098
3099         return True;            
3100 }
3101
3102
3103 /*******************************************************************
3104  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
3105 ********************************************************************/  
3106 BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
3107 {
3108
3109         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
3110         depth++;
3111
3112         if (!prs_align(ps))
3113                 return False;
3114                 
3115         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3116                 return False;
3117         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
3118                 return False;
3119                 
3120         if (!prs_align(ps))
3121                 return False;
3122         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
3123                 return False;
3124         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3125                 return False;
3126                 
3127         if (!prs_align(ps))
3128                 return False;
3129         if (!prs_uint32("level", ps, depth, &q_u->level))
3130                 return False;
3131                 
3132         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3133                 return False;
3134
3135         if (!prs_align(ps))
3136                 return False;
3137                 
3138         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3139                 return False;
3140
3141         return True;
3142 }
3143
3144 /*******************************************************************
3145 ********************************************************************/  
3146 BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
3147 {
3148
3149         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
3150         depth++;
3151
3152         if (!prs_align(ps))
3153                 return False;                   
3154         if (!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
3155                 return False;           
3156         if (!prs_uint32("level", ps, depth, &(q_u->level)))
3157                 return False;   
3158         
3159         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3160                 return False;
3161
3162         if (!prs_align(ps))
3163                 return False;
3164         if (!prs_uint32("offered", ps, depth, &(q_u->offered)))
3165                 return False;
3166
3167         return True;
3168 }
3169
3170 /*******************************************************************
3171 ********************************************************************/  
3172 BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
3173 {
3174         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumforms");
3175         depth++;
3176
3177         if (!prs_align(ps))
3178                 return False;
3179                 
3180         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3181                 return False;
3182
3183         if (!prs_align(ps))
3184                 return False;
3185                 
3186         if (!prs_uint32("size of buffer needed", ps, depth, &(r_u->needed)))
3187                 return False;
3188                 
3189         if (!prs_uint32("numofforms", ps, depth, &(r_u->numofforms)))
3190                 return False;
3191                 
3192         if (!prs_uint32("status", ps, depth, &(r_u->status)))
3193                 return False;
3194
3195         return True;
3196                 
3197 }
3198
3199 /*******************************************************************
3200  Parse a SPOOL_R_ENUMPORTS structure.
3201 ********************************************************************/  
3202 BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
3203 {
3204         prs_debug(ps, depth, desc, "new_spoolss_io_r_enumports");
3205         depth++;
3206
3207         if (!prs_align(ps))
3208                 return False;
3209                 
3210         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3211                 return False;
3212
3213         if (!prs_align(ps))
3214                 return False;
3215                 
3216         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3217                 return False;
3218                 
3219         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3220                 return False;
3221                 
3222         if (!prs_uint32("status", ps, depth, &r_u->status))
3223                 return False;
3224
3225         return True;            
3226 }
3227
3228 /*******************************************************************
3229 ********************************************************************/  
3230 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
3231 {
3232         prs_debug(ps, depth, desc, "");
3233         depth++;
3234
3235         if (!prs_align(ps))
3236                 return False;
3237
3238         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
3239                 return False;
3240         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
3241                 return False;
3242
3243         if (!prs_align(ps))
3244                 return False;
3245         if (!prs_uint32("level", ps, depth, &q_u->level))
3246                 return False;
3247                 
3248         if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3249                 return False;
3250
3251         if (!prs_align(ps))
3252                 return False;
3253         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3254                 return False;
3255
3256         return True;
3257 }
3258
3259 /*******************************************************************
3260  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
3261 ********************************************************************/  
3262 BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
3263 {       
3264         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
3265         depth++;
3266                 
3267         if(!prs_align(ps))
3268                 return False;
3269
3270         if(!prs_uint32("flags", ps, depth, &il->flags))
3271                 return False;
3272         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
3273                 return False;
3274         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
3275                 return False;
3276         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3277                 return False;
3278                 
3279         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
3280                 return False;
3281         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3282                 return False;
3283         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3284                 return False;
3285
3286         return True;
3287 }
3288
3289 /*******************************************************************
3290  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
3291 ********************************************************************/  
3292 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
3293 {       
3294         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
3295         depth++;
3296                 
3297         if(!prs_align(ps))
3298                 return False;
3299
3300         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
3301                 return False;
3302         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
3303                 return False;
3304         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
3305                 return False;
3306         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
3307                 return False;
3308         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
3309                 return False;
3310         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
3311                 return False;
3312         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
3313                 return False;
3314         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
3315                 return False;
3316         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
3317                 return False;
3318         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
3319                 return False;
3320         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
3321                 return False;
3322         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
3323                 return False;
3324         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
3325                 return False;
3326
3327         if(!prs_uint32("attributes", ps, depth, &il->attributes))
3328                 return False;
3329         if(!prs_uint32("priority", ps, depth, &il->priority))
3330                 return False;
3331         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
3332                 return False;
3333         if(!prs_uint32("starttime", ps, depth, &il->starttime))
3334                 return False;
3335         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
3336                 return False;
3337         if(!prs_uint32("status", ps, depth, &il->status))
3338                 return False;
3339         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
3340                 return False;
3341         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
3342                 return False;
3343
3344         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
3345                 return False;
3346         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
3347                 return False;
3348         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
3349                 return False;
3350         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
3351                 return False;
3352         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
3353                 return False;
3354         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
3355                 return False;
3356         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
3357                 return False;
3358         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
3359                 return False;
3360         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
3361                 return False;
3362         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
3363                 return False;
3364         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
3365                 return False;
3366
3367         return True;
3368 }
3369
3370 /*******************************************************************
3371 ********************************************************************/  
3372 BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
3373 {
3374         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
3375         depth++;
3376
3377         if(!prs_align(ps))
3378                 return False;
3379         if(!prs_uint32("level", ps, depth, &il->level))
3380                 return False;
3381         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
3382                 return False;
3383         
3384         /* if no struct inside just return */
3385         if (il->info_ptr==0) {
3386                 if (UNMARSHALLING(ps)) {
3387                         il->info_1=NULL;
3388                         il->info_2=NULL;
3389                 }
3390                 return True;
3391         }
3392                         
3393         switch (il->level) {
3394                 /*
3395                  * level 0 is used by setprinter when managing the queue
3396                  * (hold, stop, start a queue)
3397                  */
3398                 case 0:
3399                         break;
3400                 /* 
3401                  * level 2 is used by addprinter
3402                  * and by setprinter when updating printer's info
3403                  */     
3404                 case 1:
3405                         if (UNMARSHALLING(ps)) {
3406                                 il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_1));
3407                                 if(il->info_1 == NULL)
3408                                         return False;
3409                         }
3410                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
3411                                 return False;
3412                         break;          
3413                 case 2:
3414                         if (UNMARSHALLING(ps)) {
3415                                 il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
3416                                 if(il->info_2 == NULL)
3417                                         return False;
3418                         }
3419                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
3420                                 return False;
3421                         break;          
3422         }
3423
3424         return True;
3425 }
3426
3427 /*******************************************************************
3428 ********************************************************************/  
3429 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
3430 {
3431         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
3432         depth++;
3433
3434         /*
3435          * I think that's one of the few well written functions.
3436          * the sub-structures are correctly parsed and analysed
3437          * the info level are handled in a nice way.
3438          */
3439
3440         if(!prs_align(ps))
3441                 return False;
3442         if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
3443                 return False;
3444         if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
3445                 return False;
3446
3447         if(!prs_align(ps))
3448                 return False;
3449
3450         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3451                 return False;
3452         
3453         if(!spool_io_printer_info_level("", &(q_u->info), ps, depth))
3454                 return False;
3455         
3456         /* the 4 unknown are all 0 */
3457
3458         /* 
3459          * en fait ils sont pas inconnu
3460          * par recoupement avec rpcSetPrinter
3461          * c'est le devicemode 
3462          * et le security descriptor.
3463          */
3464         
3465         if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
3466                 return False;
3467         if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
3468                 return False;
3469         if(!prs_uint32("unk2", ps, depth, &q_u->unk2))
3470                 return False;
3471         if(!prs_uint32("unk3", ps, depth, &q_u->unk3))
3472                 return False;
3473
3474         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
3475                 return False;
3476         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
3477                 return False;
3478
3479         return True;
3480 }
3481
3482
3483 /*******************************************************************
3484 ********************************************************************/  
3485 BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth)
3486 {
3487         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
3488         depth++;
3489         
3490         if(!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
3491                 return False;
3492
3493         if(!prs_uint32("status", ps, depth, &(r_u->status)))
3494                 return False;
3495
3496         return True;
3497 }
3498
3499 /*******************************************************************
3500 ********************************************************************/  
3501 BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
3502                                           prs_struct *ps, int depth)
3503 {       
3504         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
3505         
3506         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
3507         depth++;
3508                 
3509         /* reading */
3510         if (UNMARSHALLING(ps)) {
3511                 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
3512                 if(il == NULL)
3513                         return False;
3514                 ZERO_STRUCTP(il);
3515                 *q_u=il;
3516         }
3517         else {
3518                 il=*q_u;
3519         }
3520         
3521         if(!prs_align(ps))
3522                 return False;
3523
3524         if(!prs_uint32("cversion", ps, depth, &il->cversion))
3525                 return False;
3526         if(!prs_uint32("name", ps, depth, &il->name_ptr))
3527                 return False;
3528         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
3529                 return False;
3530         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
3531                 return False;
3532         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
3533                 return False;
3534         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
3535                 return False;
3536         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
3537                 return False;
3538         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
3539                 return False;
3540         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3541                 return False;
3542         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
3543                 return False;
3544         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
3545                 return False;
3546
3547         if(!prs_align(ps))
3548                 return False;
3549         
3550         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3551                 return False;
3552         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3553                 return False;
3554         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3555                 return False;
3556         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3557                 return False;
3558         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3559                 return False;
3560         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3561                 return False;
3562         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3563                 return False;
3564         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3565                 return False;
3566
3567         if(!prs_align(ps))
3568                 return False;
3569                 
3570         if (il->dependentfiles_ptr)
3571                 smb_io_buffer5("", &(il->dependentfiles), ps, depth);
3572
3573         return True;
3574 }
3575
3576
3577 /*******************************************************************
3578  convert a buffer of UNICODE strings null terminated
3579  the buffer is terminated by a NULL
3580  
3581  convert to an ascii array (null terminated)
3582  
3583  dynamically allocate memory
3584  
3585 ********************************************************************/  
3586 BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar)
3587 {
3588         char **array;
3589         char *string;
3590         char *destend;
3591         char *dest;
3592         uint32 n;
3593         uint32 i;
3594
3595         uint16 *src;
3596
3597         if (buf5==NULL) return False;
3598
3599         array=NULL;
3600         n=0;
3601         i=0;
3602         src=buf5->buffer;
3603
3604         string=(char *)malloc(sizeof(char)*buf5->buf_len);
3605         if(string == NULL)
3606                 return False;
3607
3608         destend = string + buf5->buf_len;
3609         dest=string;
3610
3611         while (dest < destend)
3612         {
3613                 *(dest++) = (char)*(src++);
3614         }
3615                 
3616         /* that ugly for the first one but that's working */
3617         array=(char **)Realloc(array, sizeof(char *)*(i+1));
3618         if(array == NULL)
3619                 return False;
3620         array[i++]=string;
3621         
3622         while ( n < buf5->buf_len )
3623         {
3624                 if ( *(string++) == '\0' )
3625                 {
3626                         array=(char **)Realloc(array, sizeof(char *)*(i+1));
3627                         if(array == NULL)
3628                                 return False;
3629                         array[i++]=string;                      
3630                 }
3631                 n++;
3632         }               
3633         *ar=array;
3634         
3635         DEBUG(10,("Number of dependent files: [%d]\n", i-1));
3636
3637         return True;
3638 }
3639
3640 /*******************************************************************
3641  read a UNICODE array with null terminated strings 
3642  and null terminated array 
3643  and size of array at beginning
3644 ********************************************************************/  
3645 BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
3646 {
3647         if (buffer==NULL) return False;
3648
3649         buffer->undoc=0;
3650         buffer->uni_str_len=buffer->uni_max_len;
3651         
3652         if(!prs_uint32("buffer_size", ps, depth, &(buffer->uni_max_len)))
3653                 return False;
3654
3655         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
3656                 return False;
3657
3658         return True;
3659 }
3660
3661 /*******************************************************************
3662 ********************************************************************/  
3663 BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
3664 {
3665         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
3666         depth++;
3667
3668         if(!prs_align(ps))
3669                 return False;
3670         if(!prs_uint32("level", ps, depth, &il->level))
3671                 return False;
3672         if(!prs_uint32("ptr", ps, depth, &il->ptr))
3673                 return False;
3674
3675         if (il->ptr==0)
3676                 return True;
3677                 
3678         switch (il->level) {
3679                 case 3:
3680                         if(!spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth))
3681                                 return False;
3682                         break;          
3683         }
3684
3685         return True;
3686 }
3687
3688 /*******************************************************************
3689 ********************************************************************/  
3690 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
3691 {
3692         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
3693         depth++;
3694
3695         if(!prs_align(ps))
3696                 return False;
3697
3698         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
3699                 return False;
3700         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
3701                 return False;
3702                 
3703         if(!prs_align(ps))
3704                 return False;
3705         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3706                 return False;
3707
3708         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
3709                 return False;
3710
3711         return True;
3712 }
3713
3714 /*******************************************************************
3715 ********************************************************************/  
3716 BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
3717 {
3718         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
3719         depth++;
3720
3721         if(!prs_uint32("status", ps, depth, &q_u->status))
3722                 return False;
3723
3724         return True;
3725 }
3726
3727
3728 /*******************************************************************
3729 ********************************************************************/  
3730 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
3731                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
3732 {
3733         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
3734         
3735         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
3736         
3737         if (*asc==NULL)
3738         {
3739                 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
3740                 if(*asc == NULL)
3741                         return False;
3742                 ZERO_STRUCTP(*asc);
3743         }       
3744
3745         d=*asc;
3746
3747         d->cversion=uni->cversion;
3748
3749         unistr2_to_ascii(d->name,            &(uni->name),            sizeof(d->name)-1);
3750         unistr2_to_ascii(d->environment,     &(uni->environment),     sizeof(d->environment)-1);
3751         unistr2_to_ascii(d->driverpath,      &(uni->driverpath),      sizeof(d->driverpath)-1);
3752         unistr2_to_ascii(d->datafile,        &(uni->datafile),        sizeof(d->datafile)-1);
3753         unistr2_to_ascii(d->configfile,      &(uni->configfile),      sizeof(d->configfile)-1);
3754         unistr2_to_ascii(d->helpfile,        &(uni->helpfile),        sizeof(d->helpfile)-1);
3755         unistr2_to_ascii(d->monitorname,     &(uni->monitorname),     sizeof(d->monitorname)-1);
3756         unistr2_to_ascii(d->defaultdatatype, &(uni->defaultdatatype), sizeof(d->defaultdatatype)-1);
3757
3758         DEBUGADD(8,( "version:         %d\n", d->cversion));
3759         DEBUGADD(8,( "name:            %s\n", d->name));
3760         DEBUGADD(8,( "environment:     %s\n", d->environment));
3761         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
3762         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
3763         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
3764         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
3765         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
3766         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
3767
3768         uniarray_2_ascarray(&(uni->dependentfiles), &(d->dependentfiles) );
3769
3770         return True;
3771 }
3772
3773 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
3774                               NT_PRINTER_INFO_LEVEL_2  **asc)
3775 {
3776         NT_PRINTER_INFO_LEVEL_2 *d;
3777         NTTIME time_nt;
3778         time_t time_unix;
3779         
3780         DEBUG(7,("Converting from UNICODE to ASCII\n"));
3781         time_unix=time(NULL);
3782         
3783         if (*asc==NULL)
3784         {
3785                 DEBUGADD(8,("allocating memory\n"));
3786
3787                 *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
3788                 if(*asc == NULL)
3789                         return False;
3790                 ZERO_STRUCTP(*asc);
3791                 
3792                 /* we allocate memory iff called from 
3793                  * addprinter(ex) so we can do one time stuff here.
3794                  */
3795                 (*asc)->setuptime=time_unix;
3796
3797         }       
3798         DEBUGADD(8,("start converting\n"));
3799
3800         d=*asc;
3801                 
3802         d->attributes=uni->attributes;
3803         d->priority=uni->priority;
3804         d->default_priority=uni->default_priority;
3805         d->starttime=uni->starttime;
3806         d->untiltime=uni->untiltime;
3807         d->status=uni->status;
3808         d->cjobs=uni->cjobs;
3809
3810         unix_to_nt_time(&time_nt, time_unix);
3811         d->changeid=time_nt.low;
3812         
3813         d->c_setprinter++;
3814
3815         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
3816         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
3817         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
3818         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
3819         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
3820         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
3821         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
3822         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
3823         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
3824         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
3825
3826         return True;
3827 }
3828
3829 /*******************************************************************
3830  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
3831 ********************************************************************/  
3832 BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
3833 {
3834         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
3835         depth++;
3836
3837         if(!prs_align(ps))
3838                 return False;
3839         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3840                 return False;
3841         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
3842                 return False;
3843
3844         if(!prs_align(ps))
3845                 return False;
3846                 
3847         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
3848                 return False;
3849         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3850                 return False;
3851                 
3852         if(!prs_align(ps))
3853                 return False;
3854
3855         if(!prs_uint32("level", ps, depth, &q_u->level))
3856                 return False;
3857                 
3858         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3859                 return False;
3860                 
3861         if(!prs_align(ps))
3862                 return False;
3863                 
3864         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3865                 return False;
3866
3867         return True;
3868 }
3869
3870 /*******************************************************************
3871  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
3872 ********************************************************************/  
3873 BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
3874 {               
3875         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
3876         depth++;
3877
3878         if (!prs_align(ps))
3879                 return False;
3880                 
3881         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3882                 return False;
3883
3884         if (!prs_align(ps))
3885                 return False;
3886                 
3887         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3888                 return False;
3889                 
3890         if (!prs_uint32("status", ps, depth, &r_u->status))
3891                 return False;
3892
3893         return True;            
3894 }
3895
3896 /*******************************************************************
3897 ********************************************************************/  
3898 BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
3899 {               
3900         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
3901         depth++;
3902
3903         if (!prs_align(ps))
3904                 return False;
3905                 
3906         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3907                 return False;
3908
3909         if (!prs_align(ps))
3910                 return False;
3911                 
3912         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3913                 return False;
3914                 
3915         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3916                 return False;
3917                 
3918         if (!prs_uint32("status", ps, depth, &r_u->status))
3919                 return False;
3920
3921         return True;            
3922 }
3923
3924 /*******************************************************************
3925 ********************************************************************/  
3926 BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
3927 {
3928         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
3929         depth++;
3930
3931         if (!prs_align(ps))
3932                 return False;
3933                 
3934         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3935                 return False;
3936         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3937                 return False;
3938                 
3939         if (!prs_align(ps))
3940                 return False;
3941                 
3942         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
3943                 return False;
3944         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3945                 return False;
3946         
3947         if (!prs_align(ps))
3948                 return False;
3949                 
3950         if (!prs_uint32("level", ps, depth, &q_u->level))
3951                 return False;
3952                 
3953         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
3954                 return False;
3955
3956         if (!prs_align(ps))
3957                 return False;
3958
3959         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3960                 return False;
3961
3962         return True;
3963 }
3964
3965 /*******************************************************************
3966 ********************************************************************/  
3967 BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
3968 {               
3969         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
3970         depth++;
3971
3972         if (!prs_align(ps))
3973                 return False;
3974                 
3975         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
3976                 return False;
3977
3978         if (!prs_align(ps))
3979                 return False;
3980                 
3981         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3982                 return False;
3983                 
3984         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3985                 return False;
3986                 
3987         if (!prs_uint32("status", ps, depth, &r_u->status))
3988                 return False;
3989
3990         return True;            
3991 }
3992
3993 /*******************************************************************
3994 ********************************************************************/  
3995 BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
3996 {
3997         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
3998         depth++;
3999
4000         if (!prs_align(ps))
4001                 return False;
4002                 
4003         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4004                 return False;
4005         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4006                 return False;
4007                 
4008         if (!prs_align(ps))
4009                 return False;
4010                 
4011         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
4012                 return False;
4013         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
4014                 return False;
4015         
4016         if (!prs_align(ps))
4017                 return False;
4018                 
4019         if (!prs_uint32("level", ps, depth, &q_u->level))
4020                 return False;
4021                 
4022         if(!new_spoolss_io_buffer("buffer", ps, depth, q_u->buffer))
4023                 return False;
4024
4025         if (!prs_align(ps))
4026                 return False;
4027
4028         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4029                 return False;
4030
4031         return True;
4032 }
4033
4034 /*******************************************************************
4035  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
4036 ********************************************************************/  
4037 BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
4038 {
4039         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
4040         depth++;
4041
4042         if (!prs_align(ps))
4043                 return False;
4044                 
4045         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4046                 return False;
4047         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
4048                 return False;
4049                 
4050         if (!prs_align(ps))
4051                 return False;
4052                                 
4053         if (!prs_uint32("level", ps, depth, &q_u->level))
4054                 return False;
4055                 
4056         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
4057                 return False;
4058
4059         if (!prs_align(ps))
4060                 return False;
4061
4062         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4063                 return False;
4064
4065         return True;
4066 }
4067
4068 /*******************************************************************
4069 ********************************************************************/  
4070 BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
4071 {               
4072         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
4073         depth++;
4074
4075         if (!prs_align(ps))
4076                 return False;
4077                 
4078         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
4079                 return False;
4080
4081         if (!prs_align(ps))
4082                 return False;
4083                 
4084         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4085                 return False;
4086                 
4087         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4088                 return False;
4089                 
4090         if (!prs_uint32("status", ps, depth, &r_u->status))
4091                 return False;
4092
4093         return True;            
4094 }
4095
4096 /*******************************************************************
4097 ********************************************************************/  
4098 BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
4099 {       
4100         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
4101         depth++;
4102
4103         if(!prs_align(ps))
4104                 return False;
4105         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
4106                 return False;
4107         if(!prs_uint16s(False, "value", ps, depth, r_u->value, r_u->valuesize))
4108                 return False;
4109         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
4110                 return False;
4111
4112         if(!prs_uint32("type", ps, depth, &r_u->type))
4113                 return False;
4114
4115         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
4116                 return False;
4117         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
4118                 return False;
4119         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
4120                 return False;
4121         if(!prs_uint32("status", ps, depth, &r_u->status))
4122                 return False;
4123
4124         return True;
4125 }
4126
4127 /*******************************************************************
4128 ********************************************************************/  
4129 BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
4130 {
4131         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
4132         depth++;
4133
4134         if(!prs_align(ps))
4135                 return False;
4136         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4137                 return False;
4138         if(!prs_uint32("index", ps, depth, &q_u->index))
4139                 return False;
4140         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
4141                 return False;
4142         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
4143                 return False;
4144
4145         return True;
4146 }
4147
4148 /*******************************************************************
4149 ********************************************************************/  
4150 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, POLICY_HND *hnd, uint32 idx, uint32 valuelen, uint32 datalen)
4151 {
4152         memcpy(&(q_u->handle), hnd, sizeof(q_u->handle));
4153         q_u->index=idx;
4154         q_u->valuesize=valuelen;
4155         q_u->datasize=datalen;
4156
4157         return True;
4158 }
4159
4160 /*******************************************************************
4161 ********************************************************************/  
4162 BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
4163 {
4164         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
4165         depth++;
4166
4167         if(!prs_align(ps))
4168                 return False;
4169         if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth))
4170                 return False;
4171         if(!smb_io_unistr2("", &(q_u->value), True, ps, depth))
4172                 return False;
4173
4174         if(!prs_align(ps))
4175                 return False;
4176
4177         if(!prs_uint32("type", ps, depth, &(q_u->type)))
4178                 return False;
4179
4180         if(!prs_uint32("max_len", ps, depth, &(q_u->max_len)))
4181                 return False;
4182
4183         switch (q_u->type)
4184         {
4185                 case 0x1:
4186                 case 0x3:
4187                 case 0x4:
4188                 case 0x7:
4189                         q_u->data=(uint8 *)malloc(q_u->max_len * sizeof(uint8));
4190                         if(q_u->data == NULL)
4191                                 return False;
4192                         if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
4193                                 return False;
4194                         if(!prs_align(ps))
4195                                 return False;
4196                         break;
4197         }       
4198         
4199         if(!prs_uint32("real_len", ps, depth, &(q_u->real_len)))
4200                 return False;
4201
4202         return True;
4203 }
4204
4205 /*******************************************************************
4206 ********************************************************************/  
4207 BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
4208 {
4209         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
4210         depth++;
4211
4212         if(!prs_align(ps))
4213                 return False;
4214         if(!prs_uint32("status",     ps, depth, &(r_u->status)))
4215                 return False;
4216
4217         return True;
4218 }
4219
4220 /*******************************************************************
4221 ********************************************************************/  
4222 BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
4223                                 uint32 type, const uint8 *data, uint32 len)
4224 {
4225         DEBUG(5,("converting a specific param struct\n"));
4226
4227         if (*param == NULL)
4228         {
4229                 *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
4230                 if(*param == NULL)
4231                         return False;
4232                 ZERO_STRUCTP(*param);
4233                 DEBUGADD(6,("Allocated a new PARAM struct\n"));
4234         }
4235         unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
4236         (*param)->type = type;
4237         
4238         /* le champ data n'est pas NULL termine */
4239         /* on stocke donc la longueur */
4240         
4241         (*param)->data_len=len;
4242         
4243         (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
4244         if((*param)->data == NULL)
4245                 return False;
4246                         
4247         memcpy((*param)->data, data, len);
4248                 
4249         DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
4250
4251         return True;
4252 }
4253
4254 /*******************************************************************
4255 ********************************************************************/  
4256 static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
4257 {
4258         prs_debug(ps, depth, desc, "spoolss_io_addform");
4259         depth++;
4260         if(!prs_align(ps))
4261                 return False;
4262
4263         if (ptr!=0)
4264         {
4265                 if(!prs_uint32("flags",    ps, depth, &(f->flags)))
4266                         return False;
4267                 if(!prs_uint32("name_ptr", ps, depth, &(f->name_ptr)))
4268                         return False;
4269                 if(!prs_uint32("size_x",   ps, depth, &(f->size_x)))
4270                         return False;
4271                 if(!prs_uint32("size_y",   ps, depth, &(f->size_y)))
4272                         return False;
4273                 if(!prs_uint32("left",     ps, depth, &(f->left)))
4274                         return False;
4275                 if(!prs_uint32("top",      ps, depth, &(f->top)))
4276                         return False;
4277                 if(!prs_uint32("right",    ps, depth, &(f->right)))
4278                         return False;
4279                 if(!prs_uint32("bottom",   ps, depth, &(f->bottom)))
4280                         return False;
4281
4282                 if(!smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth))
4283                         return False;
4284         }
4285
4286         return True;
4287 }
4288
4289 /*******************************************************************
4290 ********************************************************************/  
4291 BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
4292 {
4293         uint32 useless_ptr=0;
4294         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
4295         depth++;
4296
4297         if(!prs_align(ps))
4298                 return False;
4299         if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth))
4300                 return False;
4301         if(!prs_uint32("level",  ps, depth, &(q_u->level)))
4302                 return False;
4303         if(!prs_uint32("level2", ps, depth, &(q_u->level2)))
4304                 return False;
4305
4306         if (q_u->level==1)
4307         {
4308                 if(!prs_uint32("useless_ptr", ps, depth, &(useless_ptr)))
4309                         return False;
4310                 if(!spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth))
4311                         return False;
4312         }
4313
4314         return True;
4315 }
4316
4317 /*******************************************************************
4318 ********************************************************************/  
4319 BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
4320 {
4321         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
4322         depth++;
4323
4324         if(!prs_align(ps))
4325                 return False;
4326         if(!prs_uint32("status",        ps, depth, &(r_u->status)))
4327                 return False;
4328
4329         return True;
4330 }
4331
4332 /*******************************************************************
4333 ********************************************************************/  
4334 BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
4335 {
4336         uint32 useless_ptr=0;
4337         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
4338         depth++;
4339
4340         if(!prs_align(ps))
4341                 return False;
4342         if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth))
4343                 return False;
4344         if(!smb_io_unistr2("", &(q_u->name), True, ps, depth))
4345                 return False;
4346               
4347         if(!prs_align(ps))
4348                 return False;
4349         
4350         if(!prs_uint32("level",  ps, depth, &(q_u->level)))
4351                 return False;
4352         if(!prs_uint32("level2", ps, depth, &(q_u->level2)))
4353                 return False;
4354
4355         if (q_u->level==1)
4356         {
4357                 if(!prs_uint32("useless_ptr", ps, depth, &(useless_ptr)))
4358                         return False;
4359                 if(!spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth))
4360                         return False;
4361         }
4362
4363         return True;
4364 }
4365
4366 /*******************************************************************
4367 ********************************************************************/  
4368 BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
4369 {
4370         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
4371         depth++;
4372
4373         if(!prs_align(ps))
4374                 return False;
4375         if(!prs_uint32("status",        ps, depth, &(r_u->status)))
4376                 return False;
4377
4378         return True;
4379 }
4380
4381 /*******************************************************************
4382  Parse a SPOOL_R_GETJOB structure.
4383 ********************************************************************/  
4384 BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
4385 {               
4386         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
4387         depth++;
4388
4389         if (!prs_align(ps))
4390                 return False;
4391                 
4392         if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
4393                 return False;
4394
4395         if (!prs_align(ps))
4396                 return False;
4397                 
4398         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4399                 return False;
4400                 
4401         if (!prs_uint32("status", ps, depth, &r_u->status))
4402                 return False;
4403
4404         return True;            
4405 }
4406
4407 /*******************************************************************
4408  Parse a SPOOL_Q_GETJOB structure.
4409 ********************************************************************/  
4410 BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
4411 {
4412         prs_debug(ps, depth, desc, "");
4413         depth++;
4414
4415         if(!prs_align(ps))
4416                 return False;
4417
4418         if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth))
4419                 return False;
4420         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4421                 return False;
4422         if(!prs_uint32("level", ps, depth, &q_u->level))
4423                 return False;
4424         
4425         if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
4426                 return False;
4427
4428         if(!prs_align(ps))
4429                 return False;
4430         
4431         if(!prs_uint32("offered", ps, depth, &q_u->offered))
4432                 return False;
4433
4434         return True;
4435 }
4436
4437 void free_devmode(DEVICEMODE *devmode)
4438 {
4439         if (devmode!=NULL)
4440         {
4441                 if (devmode->private!=NULL)
4442                         free(devmode->private);
4443                 free(devmode);
4444         }
4445 }
4446
4447 void free_printer_info_2(PRINTER_INFO_2 *printer)
4448 {
4449         if (printer!=NULL)
4450         {
4451                 free_devmode(printer->devmode);
4452                 free(printer);
4453         }
4454 }
4455
4456 static PRINTER_INFO_2 *prt2_dup(const PRINTER_INFO_2* from)
4457 {
4458         PRINTER_INFO_2 *copy = (PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2));
4459         if (copy != NULL)
4460         {
4461                 if (from != NULL)
4462                 {
4463                         memcpy(copy, from, sizeof(*copy));
4464                 }
4465                 else
4466                 {
4467                         ZERO_STRUCTP(copy);
4468                 }
4469         }
4470         return copy;
4471 }
4472
4473 void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries)
4474 {
4475         void(*fn)(void*) = (void(*)(void*))&free_printer_info_2;
4476         free_void_array(num_entries, (void**)entries, *fn);
4477 }
4478
4479 PRINTER_INFO_2 *add_print2_to_array(uint32 *len, PRINTER_INFO_2 ***array,
4480                                 const PRINTER_INFO_2 *prt)
4481 {
4482         void*(*fn)(const void*) = (void*(*)(const void*))&prt2_dup;
4483         return (PRINTER_INFO_2*)add_copy_to_array(len,
4484                    (void***)array, (const void*)prt, *fn, True);
4485 }
4486
4487 static PRINTER_INFO_1 *prt1_dup(const PRINTER_INFO_1* from)
4488 {
4489         PRINTER_INFO_1 *copy = (PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
4490         if (copy != NULL)
4491         {
4492                 if (from != NULL)
4493                 {
4494                         memcpy(copy, from, sizeof(*copy));
4495                 }
4496                 else
4497                 {
4498                         ZERO_STRUCTP(copy);
4499                 }
4500         }
4501         return copy;
4502 }
4503
4504 void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries)
4505 {
4506         void(*fn)(void*) = (void(*)(void*))&free;
4507         free_void_array(num_entries, (void**)entries, *fn);
4508 }
4509
4510 PRINTER_INFO_1 *add_print1_to_array(uint32 *len, PRINTER_INFO_1 ***array,
4511                                 const PRINTER_INFO_1 *prt)
4512 {
4513         void*(*fn)(const void*) = (void*(*)(const void*))&prt1_dup;
4514         return (PRINTER_INFO_1*)add_copy_to_array(len,
4515                            (void***)array, (const void*)prt, *fn, True);
4516 }
4517
4518 static JOB_INFO_1 *job1_dup(const JOB_INFO_1* from)
4519 {
4520         JOB_INFO_1 *copy = (JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
4521         if (copy != NULL)
4522         {
4523                 if (from != NULL)
4524                 {
4525                         memcpy(copy, from, sizeof(*copy));
4526                 }
4527                 else
4528                 {
4529                         ZERO_STRUCTP(copy);
4530                 }
4531         }
4532         return copy;
4533 }
4534
4535 void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries)
4536 {
4537         void(*fn)(void*) = (void(*)(void*))&free;
4538         free_void_array(num_entries, (void**)entries, *fn);
4539 }
4540
4541 JOB_INFO_1 *add_job1_to_array(uint32 *len, JOB_INFO_1 ***array,
4542                                 const JOB_INFO_1 *job)
4543 {
4544         void*(*fn)(const void*) = (void*(*)(const void*))&job1_dup;
4545         return (JOB_INFO_1*)add_copy_to_array(len,
4546                            (void***)array, (const void*)job, *fn, True);
4547 }
4548
4549 static JOB_INFO_2 *job2_dup(const JOB_INFO_2* from)
4550 {
4551         JOB_INFO_2 *copy = (JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
4552         if (copy != NULL)
4553         {
4554                 if (from != NULL)
4555                 {
4556                         memcpy(copy, from, sizeof(*copy));
4557                 }
4558                 else
4559                 {
4560                         ZERO_STRUCTP(copy);
4561                 }
4562         }
4563         return copy;
4564 }
4565
4566 void free_job_info_2(JOB_INFO_2 *job)
4567 {
4568         if (job!=NULL)
4569         {
4570                 free_devmode(job->devmode);
4571                 free(job);
4572         }
4573 }
4574
4575 void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries)
4576 {
4577         void(*fn)(void*) = (void(*)(void*))&free_job_info_2;
4578         free_void_array(num_entries, (void**)entries, *fn);
4579 }
4580
4581 JOB_INFO_2 *add_job2_to_array(uint32 *len, JOB_INFO_2 ***array,
4582                                 const JOB_INFO_2 *job)
4583 {
4584         void*(*fn)(const void*) = (void*(*)(const void*))&job2_dup;
4585         return (JOB_INFO_2*)add_copy_to_array(len,
4586                            (void***)array, (const void*)job, *fn, True);
4587 }
4588