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