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