This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[kai/samba.git] / source3 / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000,
7  *  Copyright (C) Gerald Carter                2000-2002
8  *  Copyright (C) Tim Potter                   2001.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25 #include "includes.h"
26
27 /*******************************************************************
28 return the length of a UNISTR string.
29 ********************************************************************/  
30
31 static uint32 str_len_uni(UNISTR *source)
32 {
33         uint32 i=0;
34
35         if (!source->buffer)
36                 return 0;
37
38         while (source->buffer[i])
39                 i++;
40
41         return i;
42 }
43
44 /*******************************************************************
45 This should be moved in a more generic lib.
46 ********************************************************************/  
47
48 static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
49 {
50         if(!prs_uint16("year", ps, depth, &systime->year))
51                 return False;
52         if(!prs_uint16("month", ps, depth, &systime->month))
53                 return False;
54         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
55                 return False;
56         if(!prs_uint16("day", ps, depth, &systime->day))
57                 return False;
58         if(!prs_uint16("hour", ps, depth, &systime->hour))
59                 return False;
60         if(!prs_uint16("minute", ps, depth, &systime->minute))
61                 return False;
62         if(!prs_uint16("second", ps, depth, &systime->second))
63                 return False;
64         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
65                 return False;
66
67         return True;
68 }
69
70 /*******************************************************************
71 ********************************************************************/  
72
73 BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
74 {
75         systime->year=unixtime->tm_year+1900;
76         systime->month=unixtime->tm_mon+1;
77         systime->dayofweek=unixtime->tm_wday;
78         systime->day=unixtime->tm_mday;
79         systime->hour=unixtime->tm_hour;
80         systime->minute=unixtime->tm_min;
81         systime->second=unixtime->tm_sec;
82         systime->milliseconds=0;
83
84         return True;
85 }
86
87 /*******************************************************************
88 reads or writes an DOC_INFO structure.
89 ********************************************************************/  
90
91 static BOOL smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
92 {
93         if (info_1 == NULL) return False;
94
95         prs_debug(ps, depth, desc, "smb_io_doc_info_1");
96         depth++;
97  
98         if(!prs_align(ps))
99                 return False;
100         
101         if(!prs_uint32("p_docname",    ps, depth, &info_1->p_docname))
102                 return False;
103         if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
104                 return False;
105         if(!prs_uint32("p_datatype",   ps, depth, &info_1->p_datatype))
106                 return False;
107
108         if(!smb_io_unistr2("", &info_1->docname,    info_1->p_docname,    ps, depth))
109                 return False;
110         if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
111                 return False;
112         if(!smb_io_unistr2("", &info_1->datatype,   info_1->p_datatype,   ps, depth))
113                 return False;
114
115         return True;
116 }
117
118 /*******************************************************************
119 reads or writes an DOC_INFO structure.
120 ********************************************************************/  
121
122 static BOOL smb_io_doc_info(char *desc, DOC_INFO *info, prs_struct *ps, int depth)
123 {
124         uint32 useless_ptr=0;
125         
126         if (info == NULL) return False;
127
128         prs_debug(ps, depth, desc, "smb_io_doc_info");
129         depth++;
130  
131         if(!prs_align(ps))
132                 return False;
133         
134         if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
135                 return False;
136         
137         if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
138                 return False;
139
140         switch (info->switch_value)
141         {
142                 case 1: 
143                         if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
144                                 return False;
145                         break;
146                 case 2:
147                         /*
148                           this is just a placeholder
149                           
150                           MSDN July 1998 says doc_info_2 is only on
151                           Windows 95, and as Win95 doesn't do RPC to print
152                           this case is nearly impossible
153                           
154                           Maybe one day with Windows for dishwasher 2037 ...
155                           
156                         */
157                         /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
158                         break;
159                 default:
160                         DEBUG(0,("Something is obviously wrong somewhere !\n"));
161                         break;
162         }
163
164         return True;
165 }
166
167 /*******************************************************************
168 reads or writes an DOC_INFO_CONTAINER structure.
169 ********************************************************************/  
170
171 static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
172 {
173         if (cont == NULL) return False;
174
175         prs_debug(ps, depth, desc, "smb_io_doc_info_container");
176         depth++;
177  
178         if(!prs_align(ps))
179                 return False;
180         
181         if(!prs_uint32("level", ps, depth, &cont->level))
182                 return False;
183         
184         if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
185                 return False;
186
187         return True;
188 }
189
190 /*******************************************************************
191 reads or writes an NOTIFY OPTION TYPE structure.
192 ********************************************************************/  
193
194 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
195    structure.  The _TYPE structure is really the deferred referrants (i.e
196    the notify fields array) of the _TYPE structure. -tpot */
197
198 static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
199 {
200         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
201         depth++;
202  
203         if (!prs_align(ps))
204                 return False;
205
206         if(!prs_uint16("type", ps, depth, &type->type))
207                 return False;
208         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
209                 return False;
210         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
211                 return False;
212         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
213                 return False;
214         if(!prs_uint32("count", ps, depth, &type->count))
215                 return False;
216         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
217                 return False;
218
219         return True;
220 }
221
222 /*******************************************************************
223 reads or writes an NOTIFY OPTION TYPE DATA.
224 ********************************************************************/  
225
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
257 static BOOL smb_io_notify_option_type_ctr(char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
258 {               
259         int i;
260         
261         prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
262         depth++;
263  
264         if(!prs_uint32("count", ps, depth, &ctr->count))
265                 return False;
266
267         /* reading */
268         if (UNMARSHALLING(ps))
269                 if((ctr->type=(SPOOL_NOTIFY_OPTION_TYPE *)prs_alloc_mem(ps,ctr->count*sizeof(SPOOL_NOTIFY_OPTION_TYPE))) == NULL)
270                         return False;
271                 
272         /* the option type struct */
273         for(i=0;i<ctr->count;i++)
274                 if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
275                         return False;
276
277         /* the type associated with the option type struct */
278         for(i=0;i<ctr->count;i++)
279                 if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
280                         return False;
281         
282         return True;
283 }
284
285 /*******************************************************************
286 reads or writes an NOTIFY OPTION structure.
287 ********************************************************************/  
288
289 static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
290 {
291         prs_debug(ps, depth, desc, "smb_io_notify_option");
292         depth++;
293         
294         if(!prs_uint32("version", ps, depth, &option->version))
295                 return False;
296         if(!prs_uint32("flags", ps, depth, &option->flags))
297                 return False;
298         if(!prs_uint32("count", ps, depth, &option->count))
299                 return False;
300         if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
301                 return False;
302         
303         /* marshalling or unmarshalling, that would work */     
304         if (option->option_type_ptr!=0) {
305                 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
306                         return False;
307         }
308         else {
309                 option->ctr.type=NULL;
310                 option->ctr.count=0;
311         }
312         
313         return True;
314 }
315
316 /*******************************************************************
317 reads or writes an NOTIFY INFO DATA structure.
318 ********************************************************************/  
319
320 static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
321 {
322         uint32 useless_ptr=0xADDE0FF0;
323
324         uint32 how_many_words;
325         BOOL isvalue;
326         uint32 x;
327         
328         prs_debug(ps, depth, desc, "smb_io_notify_info_data");
329         depth++;
330
331         how_many_words=data->size;
332         if (how_many_words==POINTER) {
333                 how_many_words=TWO_VALUE;
334         }
335         
336         isvalue=data->enc_type;
337
338         if(!prs_align(ps))
339                 return False;
340         if(!prs_uint16("type",           ps, depth, &data->type))
341                 return False;
342         if(!prs_uint16("field",          ps, depth, &data->field))
343                 return False;
344         /*prs_align(ps);*/
345
346         if(!prs_uint32("how many words", ps, depth, &how_many_words))
347                 return False;
348         if(!prs_uint32("id",             ps, depth, &data->id))
349                 return False;
350         if(!prs_uint32("how many words", ps, depth, &how_many_words))
351                 return False;
352
353
354         /*prs_align(ps);*/
355
356         if (isvalue==True) {
357                 if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
358                         return False;
359                 if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
360                         return False;
361                 /*prs_align(ps);*/
362         } else {
363                 /* it's a string */
364                 /* length in ascii including \0 */
365                 x=2*(data->notify_data.data.length+1);
366                 if(!prs_uint32("string length", ps, depth, &x ))
367                         return False;
368                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
369                         return False;
370                 /*prs_align(ps);*/
371         }
372
373         return True;
374 }
375
376 /*******************************************************************
377 reads or writes an NOTIFY INFO DATA structure.
378 ********************************************************************/  
379
380 BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
381                                      prs_struct *ps, int depth)
382 {
383         uint32 x;
384         BOOL isvalue;
385         
386         prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
387         depth++;
388         
389         if(!prs_align(ps))
390                 return False;
391
392         isvalue=data->enc_type;
393
394         if (isvalue==False) {
395                 /* length of string in unicode include \0 */
396                 x=data->notify_data.data.length+1;
397                 if(!prs_uint32("string length", ps, depth, &x ))
398                         return False;
399                 if (MARSHALLING(ps)) {
400                         /* These are already in little endian format. Don't byte swap. */
401                         if (x == 1) {
402
403                                 /* No memory allocated for this string
404                                    therefore following the data.string
405                                    pointer is a bad idea.  Use a pointer to
406                                    the uint32 length union member to
407                                    provide a source for a unicode NULL */
408
409                                 if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) 
410                                         return False;
411                         } else {
412                                 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
413                                         return False;
414                         }
415                 } else {
416
417                         /* Tallocate memory for string */
418
419                         data->notify_data.data.string = (uint16 *)prs_alloc_mem(ps, x * 2);
420                         if (!data->notify_data.data.string) 
421                                 return False;
422
423                         if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
424                                 return False;
425                 }
426         }
427 #if 0   /* JERRY */
428
429         /* Win2k does not seem to put this parse align here */
430
431         if(!prs_align(ps))
432                 return False;
433 #endif
434
435         return True;
436 }
437
438 /*******************************************************************
439 reads or writes an NOTIFY INFO structure.
440 ********************************************************************/  
441
442 static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
443 {
444         int i;
445
446         prs_debug(ps, depth, desc, "smb_io_notify_info");
447         depth++;
448  
449         if(!prs_align(ps))
450                 return False;
451
452         if(!prs_uint32("count", ps, depth, &info->count))
453                 return False;
454         if(!prs_uint32("version", ps, depth, &info->version))
455                 return False;
456         if(!prs_uint32("flags", ps, depth, &info->flags))
457                 return False;
458         if(!prs_uint32("count", ps, depth, &info->count))
459                 return False;
460
461         for (i=0;i<info->count;i++) {
462                 if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
463                         return False;
464         }
465
466         /* now do the strings at the end of the stream */       
467         for (i=0;i<info->count;i++) {
468                 if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
469                         return False;
470         }
471
472         return True;
473 }
474
475 /*******************************************************************
476 ********************************************************************/  
477
478 static BOOL spool_io_user_level_1(char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
479 {
480         prs_debug(ps, depth, desc, "");
481         depth++;
482
483         /* reading */
484         if (UNMARSHALLING(ps))
485                 ZERO_STRUCTP(q_u);
486
487         if (!prs_align(ps))
488                 return False;
489         if (!prs_uint32("size", ps, depth, &q_u->size))
490                 return False;
491         if (!prs_uint32("client_name_ptr", ps, depth, &q_u->client_name_ptr))
492                 return False;
493         if (!prs_uint32("user_name_ptr", ps, depth, &q_u->user_name_ptr))
494                 return False;
495         if (!prs_uint32("build", ps, depth, &q_u->build))
496                 return False;
497         if (!prs_uint32("major", ps, depth, &q_u->major))
498                 return False;
499         if (!prs_uint32("minor", ps, depth, &q_u->minor))
500                 return False;
501         if (!prs_uint32("processor", ps, depth, &q_u->processor))
502                 return False;
503
504         if (!smb_io_unistr2("", &q_u->client_name, q_u->client_name_ptr, ps, depth))
505                 return False;
506         if (!prs_align(ps))
507                 return False;
508         if (!smb_io_unistr2("", &q_u->user_name,   q_u->user_name_ptr,   ps, depth))
509                 return False;
510
511         return True;
512 }
513
514 /*******************************************************************
515 ********************************************************************/  
516
517 static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
518 {
519         if (q_u==NULL)
520                 return False;
521
522         prs_debug(ps, depth, desc, "spool_io_user_level");
523         depth++;
524
525         if (!prs_align(ps))
526                 return False;
527         if (!prs_uint32("level", ps, depth, &q_u->level))
528                 return False;
529         if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
530                 return False;
531         
532         switch (q_u->level) {   
533         case 1:
534                 if (!spool_io_user_level_1("", &q_u->user1, ps, depth))
535                         return False;
536                 break;
537         default:
538                 return False;   
539         }       
540
541         return True;
542 }
543
544 /*******************************************************************
545  * read or write a DEVICEMODE struct.
546  * on reading allocate memory for the private member
547  ********************************************************************/
548
549 BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
550 {
551         prs_debug(ps, depth, desc, "spoolss_io_devmode");
552         depth++;
553
554         if (UNMARSHALLING(ps)) {
555                 devmode->devicename.buffer = (uint16 *)prs_alloc_mem(ps, 32 * sizeof(uint16) );
556                 if (devmode->devicename.buffer == NULL)
557                         return False;
558         }
559
560         if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, 32))
561                 return False;
562         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
563                 return False;
564         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
565                 return False;
566         if (!prs_uint16("size",             ps, depth, &devmode->size))
567                 return False;
568         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
569                 return False;
570         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
571                 return False;
572         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
573                 return False;
574         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
575                 return False;
576         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
577                 return False;
578         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
579                 return False;
580         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
581                 return False;
582         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
583                 return False;
584         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
585                 return False;
586         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
587                 return False;
588         if (!prs_uint16("color",            ps, depth, &devmode->color))
589                 return False;
590         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
591                 return False;
592         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
593                 return False;
594         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
595                 return False;
596         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
597                 return False;
598
599         if (UNMARSHALLING(ps)) {
600                 devmode->formname.buffer = (uint16 *)prs_alloc_mem(ps, 32 * sizeof(uint16) );
601                 if (devmode->formname.buffer == NULL)
602                         return False;
603         }
604
605         if (!prs_uint16uni(True, "formname",  ps, depth, devmode->formname.buffer, 32))
606                 return False;
607         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
608                 return False;
609         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
610                 return False;
611         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
612                 return False;
613         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
614                 return False;
615         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
616                 return False;
617         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
618                 return False;
619
620         /* 
621          * Conditional parsing.  Assume that the DeviceMode has been 
622          * zero'd by the caller. 
623          */
624         switch(devmode->specversion) {
625         
626                 /* Used by spooler when issuing OpenPrinter() calls.  NT 3.5x? */
627                 case 0x0320:
628                         break;
629                 
630                 /* See the comments on the DEVMODE in the msdn GDI documentation */
631                 /* (WINVER >= 0x0400) */
632                 case 0x0400:
633                 case 0x0401:
634         if (!prs_uint32("icmmethod",        ps, depth, &devmode->icmmethod))
635                 return False;
636         if (!prs_uint32("icmintent",        ps, depth, &devmode->icmintent))
637                 return False;
638         if (!prs_uint32("mediatype",        ps, depth, &devmode->mediatype))
639                 return False;
640         if (!prs_uint32("dithertype",       ps, depth, &devmode->dithertype))
641                 return False;
642         if (!prs_uint32("reserved1",        ps, depth, &devmode->reserved1))
643                 return False;
644         if (!prs_uint32("reserved2",        ps, depth, &devmode->reserved2))
645                 return False;
646
647                         /* (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400) */
648                         if (devmode->specversion == 0x401) {
649         if (!prs_uint32("panningwidth",     ps, depth, &devmode->panningwidth))
650                 return False;
651         if (!prs_uint32("panningheight",    ps, depth, &devmode->panningheight))
652                 return False;
653                         }
654                         break;
655
656                 /* log an error if we see something else */
657                 default:
658                         DEBUG(0,("spoolss_io_devmode: Unknown specversion [0x%x]!\n", devmode->specversion));
659                         DEBUG(0,("spoolss_io_devmode: Please report to samba-technical@samba.org\n"));
660                         break;
661         }
662
663         if (devmode->driverextra!=0) {
664                 if (UNMARSHALLING(ps)) {
665                         devmode->private=(uint8 *)prs_alloc_mem(ps, devmode->driverextra*sizeof(uint8));
666                         if(devmode->private == NULL)
667                                 return False;
668                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra)); 
669                 }
670                         
671                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
672                 if (!prs_uint8s(False, "private",  ps, depth,
673                                 devmode->private, devmode->driverextra))
674                         return False;
675         }
676
677         return True;
678 }
679
680 /*******************************************************************
681  Read or write a DEVICEMODE container
682 ********************************************************************/  
683
684 static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
685 {
686         if (dm_c==NULL)
687                 return False;
688
689         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
690         depth++;
691
692         if(!prs_align(ps))
693                 return False;
694         
695         if (!prs_uint32("size", ps, depth, &dm_c->size))
696                 return False;
697
698         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
699                 return False;
700
701         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
702                 if (UNMARSHALLING(ps))
703                         /* if while reading there is no DEVMODE ... */
704                         dm_c->devmode=NULL;
705                 return True;
706         }
707         
708         /* so we have a DEVICEMODE to follow */         
709         if (UNMARSHALLING(ps)) {
710                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
711                 dm_c->devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE));
712                 if(dm_c->devmode == NULL)
713                         return False;
714         }
715         
716         /* this is bad code, shouldn't be there */
717         if (!prs_uint32("size", ps, depth, &dm_c->size))
718                 return False;
719                 
720         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
721                 return False;
722
723         return True;
724 }
725
726 /*******************************************************************
727 ********************************************************************/  
728
729 static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
730 {
731         if (pd==NULL)
732                 return False;
733
734         prs_debug(ps, depth, desc, "spoolss_io_printer_default");
735         depth++;
736
737         if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
738                 return False;
739
740         if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
741                 return False;
742         
743         if (!prs_align(ps))
744                 return False;
745
746         if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
747                 return False;
748
749         if (!prs_align(ps))
750                 return False;
751
752         if (!prs_uint32("access_required", ps, depth, &pd->access_required))
753                 return False;
754
755         return True;
756 }
757
758 /*******************************************************************
759  * init a structure.
760  ********************************************************************/
761
762 BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
763                 const fstring printername, 
764                 const fstring datatype, 
765                 uint32 access_required,
766                 const fstring clientname,
767                 const fstring user_name)
768 {
769         DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
770         q_u->printername_ptr = (printername!=NULL)?1:0;
771         init_unistr2(&q_u->printername, printername, strlen(printername)+1);
772
773         q_u->printer_default.datatype_ptr = 0;
774 /*
775         q_u->printer_default.datatype_ptr = (datatype!=NULL)?1:0;
776         init_unistr2(&q_u->printer_default.datatype, datatype, strlen(datatype));
777 */
778         q_u->printer_default.devmode_cont.size=0;
779         q_u->printer_default.devmode_cont.devmode_ptr=0;
780         q_u->printer_default.devmode_cont.devmode=NULL;
781         q_u->printer_default.access_required=access_required;
782         q_u->user_switch=1;
783         q_u->user_ctr.level=1;
784         q_u->user_ctr.ptr=1;
785         q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+10;
786         q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
787         q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
788         q_u->user_ctr.user1.build=1381;
789         q_u->user_ctr.user1.major=2;
790         q_u->user_ctr.user1.minor=0;
791         q_u->user_ctr.user1.processor=0;
792         init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname)+1);
793         init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name)+1);
794         
795         return True;
796 }
797
798 /*******************************************************************
799  * init a structure.
800  ********************************************************************/
801
802 BOOL make_spoolss_q_addprinterex(
803         TALLOC_CTX *mem_ctx,
804         SPOOL_Q_ADDPRINTEREX *q_u, 
805         const char *srv_name,
806         const char* clientname, 
807         const char* user_name,
808         uint32 level, 
809         PRINTER_INFO_CTR *ctr)
810 {
811         DEBUG(5,("make_spoolss_q_addprinterex\n"));
812         
813         if (!ctr) return False;
814
815         ZERO_STRUCTP(q_u);
816
817         q_u->server_name_ptr = (srv_name!=NULL)?1:0;
818         init_unistr2(&q_u->server_name, srv_name, strlen(srv_name));
819
820         q_u->level = level;
821         
822         q_u->info.level = level;
823         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
824         switch (level) {
825                 case 2:
826                         /* init q_u->info.info2 from *info */
827                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
828                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
829                                 return False;
830                         }
831                         break;
832                 default :
833                         break;
834         }
835
836         q_u->user_switch=1;
837
838         q_u->user_ctr.level=1;
839         q_u->user_ctr.ptr=1;
840         q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
841         q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
842         q_u->user_ctr.user1.build=1381;
843         q_u->user_ctr.user1.major=2;
844         q_u->user_ctr.user1.minor=0;
845         q_u->user_ctr.user1.processor=0;
846         init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname)+1);
847         init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name)+1);
848         q_u->user_ctr.user1.size=q_u->user_ctr.user1.user_name.uni_str_len +
849                                  q_u->user_ctr.user1.client_name.uni_str_len + 2;
850         
851         return True;
852 }
853         
854 /*******************************************************************
855 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
856 *******************************************************************/
857
858 BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
859                                 PRINTER_INFO_2 *info)
860 {
861
862         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
863
864         /* allocate the necessary memory */
865         if (!(inf=(SPOOL_PRINTER_INFO_LEVEL_2*)talloc(mem_ctx, sizeof(SPOOL_PRINTER_INFO_LEVEL_2)))) {
866                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
867                 return False;
868         }
869         
870         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
871         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
872         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
873         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
874         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
875         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
876         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
877         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
878         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
879         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
880         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
881         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
882         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
883         inf->attributes         = info->attributes;
884         inf->priority           = info->priority;
885         inf->default_priority   = info->defaultpriority;
886         inf->starttime          = info->starttime;
887         inf->untiltime          = info->untiltime;
888         inf->cjobs              = info->cjobs;
889         inf->averageppm = info->averageppm;
890         init_unistr2_from_unistr(&inf->servername,      &info->servername);
891         init_unistr2_from_unistr(&inf->printername,     &info->printername);
892         init_unistr2_from_unistr(&inf->sharename,       &info->sharename);
893         init_unistr2_from_unistr(&inf->portname,        &info->portname);
894         init_unistr2_from_unistr(&inf->drivername,      &info->drivername);
895         init_unistr2_from_unistr(&inf->comment,         &info->comment);
896         init_unistr2_from_unistr(&inf->location,        &info->location);
897         init_unistr2_from_unistr(&inf->sepfile,         &info->sepfile);
898         init_unistr2_from_unistr(&inf->printprocessor,  &info->printprocessor);
899         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
900         init_unistr2_from_unistr(&inf->parameters,      &info->parameters);
901         init_unistr2_from_unistr(&inf->datatype,        &info->datatype);
902
903         *spool_info2 = inf;
904
905         return True;
906 }
907
908 /*******************************************************************
909  * read a structure.
910  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
911  ********************************************************************/
912
913 BOOL spoolss_io_q_open_printer(char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
914 {
915         if (q_u == NULL)
916                 return False;
917
918         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
919         depth++;
920
921         if (!prs_align(ps))
922                 return False;
923
924         if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
925                 return False;
926         if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
927                 return False;
928         
929         if (!prs_align(ps))
930                 return False;
931
932         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
933                 return False;
934                 
935         return True;
936 }
937
938 /*******************************************************************
939  * write a structure.
940  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
941  * called from spoolss_open_printer_ex (cli_spoolss.c)
942  ********************************************************************/
943
944 BOOL spoolss_io_r_open_printer(char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
945 {
946         if (r_u == NULL) return False;
947
948         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
949         depth++;
950         
951         if (!prs_align(ps))
952                 return False;
953
954         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
955                 return False;   
956
957         if (!prs_werror("status code", ps, depth, &(r_u->status)))
958                 return False;
959                 
960         return True;
961 }
962
963
964 /*******************************************************************
965  * read a structure.
966  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
967  ********************************************************************/
968
969 BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
970 {
971         if (q_u == NULL)
972                 return False;
973
974         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
975         depth++;
976
977         if (!prs_align(ps))
978                 return False;
979
980         if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
981                 return False;
982         if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
983                 return False;
984         
985         if (!prs_align(ps))
986                 return False;
987
988         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
989                 return False;
990
991         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
992                 return False;   
993         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
994                 return False;
995         
996         return True;
997 }
998
999 /*******************************************************************
1000  * write a structure.
1001  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1002  * called from spoolss_open_printer_ex (cli_spoolss.c)
1003  ********************************************************************/
1004
1005 BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1006 {
1007         if (r_u == NULL) return False;
1008
1009         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1010         depth++;
1011         
1012         if (!prs_align(ps))
1013                 return False;
1014
1015         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1016                 return False;
1017
1018         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1019                 return False;
1020
1021         return True;
1022 }
1023
1024 /*******************************************************************
1025  * init a structure.
1026  ********************************************************************/
1027 BOOL make_spoolss_q_deleteprinterdriver(
1028         TALLOC_CTX *mem_ctx,
1029         SPOOL_Q_DELETEPRINTERDRIVER *q_u, 
1030         const char *server,
1031         const char* arch, 
1032         const char* driver 
1033 )
1034 {
1035         DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1036         
1037         q_u->server_ptr = (server!=NULL)?1:0;
1038
1039         /* these must be NULL terminated or else NT4 will
1040            complain about invalid parameters --jerry */
1041         init_unistr2(&q_u->server, server, strlen(server)+1);
1042         init_unistr2(&q_u->arch, arch, strlen(arch)+1);
1043         init_unistr2(&q_u->driver, driver, strlen(driver)+1);
1044
1045         
1046         return True;
1047 }
1048
1049
1050 /*******************************************************************
1051  * make a structure.
1052  ********************************************************************/
1053
1054 BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1055                                 const POLICY_HND *handle,
1056                                 UNISTR2 *valuename, uint32 size)
1057 {
1058         if (q_u == NULL) return False;
1059
1060         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1061
1062         q_u->handle = *handle;
1063         copy_unistr2(&q_u->valuename, valuename);
1064         q_u->size = size;
1065
1066         return True;
1067 }
1068
1069 /*******************************************************************
1070  * read a structure.
1071  * called from spoolss_q_getprinterdata (srv_spoolss.c)
1072  ********************************************************************/
1073
1074 BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1075 {
1076         if (q_u == NULL)
1077                 return False;
1078
1079         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1080         depth++;
1081
1082         if (!prs_align(ps))
1083                 return False;
1084         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1085                 return False;
1086         if (!prs_align(ps))
1087                 return False;
1088         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1089                 return False;
1090         if (!prs_align(ps))
1091                 return False;
1092         if (!prs_uint32("size", ps, depth, &q_u->size))
1093                 return False;
1094
1095         return True;
1096 }
1097
1098 /*******************************************************************
1099  * read a structure.
1100  * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1101  ********************************************************************/
1102
1103 BOOL spoolss_io_q_deleteprinterdata(char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1104 {
1105         if (q_u == NULL)
1106                 return False;
1107
1108         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1109         depth++;
1110
1111         if (!prs_align(ps))
1112                 return False;
1113         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1114                 return False;
1115         if (!prs_align(ps))
1116                 return False;
1117         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1118                 return False;
1119
1120         return True;
1121 }
1122
1123 /*******************************************************************
1124  * write a structure.
1125  * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1126  ********************************************************************/
1127
1128 BOOL spoolss_io_r_deleteprinterdata(char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1129 {
1130         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1131         depth++;
1132         if(!prs_werror("status", ps, depth, &r_u->status))
1133                 return False;
1134
1135         return True;
1136 }
1137
1138 /*******************************************************************
1139  * write a structure.
1140  * called from spoolss_r_getprinterdata (srv_spoolss.c)
1141  ********************************************************************/
1142
1143 BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1144 {
1145         if (r_u == NULL)
1146                 return False;
1147
1148         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1149         depth++;
1150
1151         if (!prs_align(ps))
1152                 return False;
1153         if (!prs_uint32("type", ps, depth, &r_u->type))
1154                 return False;
1155         if (!prs_uint32("size", ps, depth, &r_u->size))
1156                 return False;
1157         
1158         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
1159                 return False;
1160                 
1161         if (!prs_align(ps))
1162                 return False;
1163         
1164         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1165                 return False;
1166         if (!prs_werror("status", ps, depth, &r_u->status))
1167                 return False;
1168                 
1169         return True;
1170 }
1171
1172 /*******************************************************************
1173  * make a structure.
1174  ********************************************************************/
1175
1176 BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1177 {
1178         if (q_u == NULL) return False;
1179
1180         DEBUG(5,("make_spoolss_q_closeprinter\n"));
1181
1182         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1183
1184         return True;
1185 }
1186
1187 /*******************************************************************
1188  * read a structure.
1189  * called from static spoolss_q_abortprinter (srv_spoolss.c)
1190  * called from spoolss_abortprinter (cli_spoolss.c)
1191  ********************************************************************/
1192
1193 BOOL spoolss_io_q_abortprinter(char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1194 {
1195         if (q_u == NULL) return False;
1196
1197         prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1198         depth++;
1199
1200         if (!prs_align(ps))
1201                 return False;
1202
1203         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1204                 return False;
1205
1206         return True;
1207 }
1208
1209 /*******************************************************************
1210  * write a structure.
1211  * called from spoolss_r_abortprinter (srv_spoolss.c)
1212  ********************************************************************/
1213
1214 BOOL spoolss_io_r_abortprinter(char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1215 {
1216         prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1217         depth++;
1218         if(!prs_werror("status", ps, depth, &r_u->status))
1219                 return False;
1220
1221         return True;
1222 }
1223
1224 /*******************************************************************
1225  * read a structure.
1226  * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1227  * called from spoolss_deleteprinter (cli_spoolss.c)
1228  ********************************************************************/
1229
1230 BOOL spoolss_io_q_deleteprinter(char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1231 {
1232         if (q_u == NULL) return False;
1233
1234         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1235         depth++;
1236
1237         if (!prs_align(ps))
1238                 return False;
1239
1240         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1241                 return False;
1242
1243         return True;
1244 }
1245
1246 /*******************************************************************
1247  * write a structure.
1248  * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1249  * called from spoolss_deleteprinter (cli_spoolss.c)
1250  ********************************************************************/
1251
1252 BOOL spoolss_io_r_deleteprinter(char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1253 {
1254         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1255         depth++;
1256         
1257         if (!prs_align(ps))
1258                 return False;
1259
1260         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1261                 return False;
1262         if (!prs_werror("status", ps, depth, &r_u->status))
1263                 return False;
1264         
1265         return True;
1266 }
1267
1268
1269 /*******************************************************************
1270  * read a structure.
1271  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1272  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1273  ********************************************************************/
1274
1275 BOOL spoolss_io_q_deleteprinterdriver(char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1276 {
1277         if (q_u == NULL) return False;
1278
1279         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1280         depth++;
1281
1282         if (!prs_align(ps))
1283                 return False;
1284
1285         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1286                 return False;           
1287         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1288                 return False;
1289         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1290                 return False;
1291         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1292                 return False;
1293
1294
1295         return True;
1296 }
1297
1298
1299 /*******************************************************************
1300  * write a structure.
1301  ********************************************************************/
1302 BOOL spoolss_io_r_deleteprinterdriver(char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1303 {
1304         if (r_u == NULL) return False;
1305
1306         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1307         depth++;
1308
1309         if (!prs_align(ps))
1310                 return False;
1311
1312         if (!prs_werror("status", ps, depth, &r_u->status))
1313                 return False;
1314
1315         return True;
1316 }
1317
1318
1319
1320 /*******************************************************************
1321  * read a structure.
1322  * called from static spoolss_q_closeprinter (srv_spoolss.c)
1323  * called from spoolss_closeprinter (cli_spoolss.c)
1324  ********************************************************************/
1325
1326 BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1327 {
1328         if (q_u == NULL) return False;
1329
1330         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1331         depth++;
1332
1333         if (!prs_align(ps))
1334                 return False;
1335
1336         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1337                 return False;
1338
1339         return True;
1340 }
1341
1342 /*******************************************************************
1343  * write a structure.
1344  * called from static spoolss_r_closeprinter (srv_spoolss.c)
1345  * called from spoolss_closeprinter (cli_spoolss.c)
1346  ********************************************************************/
1347
1348 BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1349 {
1350         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1351         depth++;
1352         
1353         if (!prs_align(ps))
1354                 return False;
1355
1356         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1357                 return False;
1358         if (!prs_werror("status", ps, depth, &r_u->status))
1359                 return False;
1360         
1361         return True;
1362 }
1363
1364 /*******************************************************************
1365  * read a structure.
1366  * called from spoolss_q_startdocprinter (srv_spoolss.c)
1367  ********************************************************************/
1368
1369 BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1370 {
1371         if (q_u == NULL) return False;
1372
1373         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1374         depth++;
1375
1376         if(!prs_align(ps))
1377                 return False;
1378
1379         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1380                 return False;
1381         
1382         if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1383                 return False;
1384
1385         return True;
1386 }
1387
1388 /*******************************************************************
1389  * write a structure.
1390  * called from spoolss_r_startdocprinter (srv_spoolss.c)
1391  ********************************************************************/
1392
1393 BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1394 {
1395         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1396         depth++;
1397         if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1398                 return False;
1399         if(!prs_werror("status", ps, depth, &r_u->status))
1400                 return False;
1401
1402         return True;
1403 }
1404
1405 /*******************************************************************
1406  * read a structure.
1407  * called from spoolss_q_enddocprinter (srv_spoolss.c)
1408  ********************************************************************/
1409
1410 BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1411 {
1412         if (q_u == NULL) return False;
1413
1414         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1415         depth++;
1416
1417         if(!prs_align(ps))
1418                 return False;
1419
1420         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1421                 return False;
1422
1423         return True;
1424 }
1425
1426 /*******************************************************************
1427  * write a structure.
1428  * called from spoolss_r_enddocprinter (srv_spoolss.c)
1429  ********************************************************************/
1430
1431 BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1432 {
1433         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1434         depth++;
1435         if(!prs_werror("status", ps, depth, &r_u->status))
1436                 return False;
1437
1438         return True;
1439 }
1440
1441 /*******************************************************************
1442  * read a structure.
1443  * called from spoolss_q_startpageprinter (srv_spoolss.c)
1444  ********************************************************************/
1445
1446 BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1447 {
1448         if (q_u == NULL) return False;
1449
1450         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1451         depth++;
1452
1453         if(!prs_align(ps))
1454                 return False;
1455
1456         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1457                 return False;
1458
1459         return True;
1460 }
1461
1462 /*******************************************************************
1463  * write a structure.
1464  * called from spoolss_r_startpageprinter (srv_spoolss.c)
1465  ********************************************************************/
1466
1467 BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1468 {
1469         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1470         depth++;
1471         if(!prs_werror("status", ps, depth, &r_u->status))
1472                 return False;
1473
1474         return True;
1475 }
1476
1477 /*******************************************************************
1478  * read a structure.
1479  * called from spoolss_q_endpageprinter (srv_spoolss.c)
1480  ********************************************************************/
1481
1482 BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1483 {
1484         if (q_u == NULL) return False;
1485
1486         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1487         depth++;
1488
1489         if(!prs_align(ps))
1490                 return False;
1491
1492         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1493                 return False;
1494
1495         return True;
1496 }
1497
1498 /*******************************************************************
1499  * write a structure.
1500  * called from spoolss_r_endpageprinter (srv_spoolss.c)
1501  ********************************************************************/
1502
1503 BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1504 {
1505         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1506         depth++;
1507         if(!prs_werror("status", ps, depth, &r_u->status))
1508                 return False;
1509
1510         return True;
1511 }
1512
1513 /*******************************************************************
1514  * read a structure.
1515  * called from spoolss_q_writeprinter (srv_spoolss.c)
1516  ********************************************************************/
1517
1518 BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1519 {
1520         if (q_u == NULL) return False;
1521
1522         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1523         depth++;
1524
1525         if(!prs_align(ps))
1526                 return False;
1527
1528         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1529                 return False;
1530         if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1531                 return False;
1532         
1533         if (q_u->buffer_size!=0)
1534         {
1535                 if (UNMARSHALLING(ps))
1536                         q_u->buffer=(uint8 *)prs_alloc_mem(ps,q_u->buffer_size*sizeof(uint8));
1537                 if(q_u->buffer == NULL)
1538                         return False;   
1539                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1540                         return False;
1541         }
1542         if(!prs_align(ps))
1543                 return False;
1544         if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1545                 return False;
1546
1547         return True;
1548 }
1549
1550 /*******************************************************************
1551  * write a structure.
1552  * called from spoolss_r_writeprinter (srv_spoolss.c)
1553  ********************************************************************/
1554
1555 BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1556 {
1557         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1558         depth++;
1559         if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1560                 return False;
1561         if(!prs_werror("status", ps, depth, &r_u->status))
1562                 return False;
1563
1564         return True;
1565 }
1566
1567 /*******************************************************************
1568  * read a structure.
1569  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1570  ********************************************************************/
1571
1572 BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1573 {
1574         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1575         depth++;
1576
1577         if(!prs_align(ps))
1578                 return False;
1579
1580         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1581                 return False;
1582         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1583                 return False;
1584         if(!prs_uint32("options", ps, depth, &q_u->options))
1585                 return False;
1586         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1587                 return False;
1588         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1589                 return False;
1590
1591         if(!prs_align(ps))
1592                 return False;
1593                 
1594         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1595                 return False;
1596
1597         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1598                 return False;
1599         
1600         if (q_u->option_ptr!=0) {
1601         
1602                 if (UNMARSHALLING(ps))
1603                         if((q_u->option=(SPOOL_NOTIFY_OPTION *)prs_alloc_mem(ps,sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1604                                 return False;
1605         
1606                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1607                         return False;
1608         }
1609         
1610         return True;
1611 }
1612
1613 /*******************************************************************
1614  * write a structure.
1615  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1616  ********************************************************************/
1617
1618 BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1619 {
1620         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1621         depth++;
1622
1623         if(!prs_werror("status", ps, depth, &r_u->status))
1624                 return False;
1625
1626         return True;
1627 }
1628
1629 /*******************************************************************
1630  * read a structure.
1631  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1632  ********************************************************************/
1633
1634 BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
1635 {
1636         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
1637         depth++;
1638
1639         if(!prs_align(ps))
1640                 return False;
1641
1642         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1643                 return False;
1644
1645         if(!prs_uint32("change", ps, depth, &q_u->change))
1646                 return False;
1647         
1648         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1649                 return False;
1650         
1651         if (q_u->option_ptr!=0) {
1652         
1653                 if (UNMARSHALLING(ps))
1654                         if((q_u->option=(SPOOL_NOTIFY_OPTION *)prs_alloc_mem(ps,sizeof(SPOOL_NOTIFY_OPTION))) == NULL)
1655                                 return False;
1656         
1657                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1658                         return False;
1659         }
1660
1661         return True;
1662 }
1663
1664 /*******************************************************************
1665  * write a structure.
1666  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
1667  ********************************************************************/
1668
1669 BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
1670 {
1671         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
1672         depth++;
1673
1674         if(!prs_align(ps))
1675                 return False;
1676                 
1677         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
1678                 return False;
1679
1680         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
1681                 return False;
1682         
1683         if(!prs_align(ps))
1684                 return False;
1685         if(!prs_werror("status", ps, depth, &r_u->status))
1686                 return False;
1687
1688         return True;
1689 }
1690
1691 /*******************************************************************
1692  * return the length of a uint16 (obvious, but the code is clean)
1693  ********************************************************************/
1694
1695 static uint32 size_of_uint16(uint16 *value)
1696 {
1697         return (sizeof(*value));
1698 }
1699
1700 /*******************************************************************
1701  * return the length of a uint32 (obvious, but the code is clean)
1702  ********************************************************************/
1703
1704 static uint32 size_of_uint32(uint32 *value)
1705 {
1706         return (sizeof(*value));
1707 }
1708
1709 /*******************************************************************
1710  * return the length of a NTTIME (obvious, but the code is clean)
1711  ********************************************************************/
1712
1713 static uint32 size_of_nttime(NTTIME *value)
1714 {
1715         return (sizeof(*value));
1716 }
1717
1718 /*******************************************************************
1719  * return the length of a UNICODE string in number of char, includes:
1720  * - the leading zero
1721  * - the relative pointer size
1722  ********************************************************************/
1723
1724 static uint32 size_of_relative_string(UNISTR *string)
1725 {
1726         uint32 size=0;
1727         
1728         size=str_len_uni(string);       /* the string length       */
1729         size=size+1;                    /* add the leading zero    */
1730         size=size*2;                    /* convert in char         */
1731         /* Ensure size is 4 byte multiple (prs_align is being called...). */
1732         size += ((4 - (size & 3)) & 3);
1733         size=size+4;                    /* add the size of the ptr */   
1734
1735         return size;
1736 }
1737
1738 /*******************************************************************
1739  * return the length of a uint32 (obvious, but the code is clean)
1740  ********************************************************************/
1741
1742 static uint32 size_of_device_mode(DEVICEMODE *devmode)
1743 {
1744         if (devmode==NULL)
1745                 return (4);
1746         else 
1747                 return (4+devmode->size+devmode->driverextra);
1748 }
1749
1750 /*******************************************************************
1751  * return the length of a uint32 (obvious, but the code is clean)
1752  ********************************************************************/
1753
1754 static uint32 size_of_systemtime(SYSTEMTIME *systime)
1755 {
1756         if (systime==NULL)
1757                 return (4);
1758         else 
1759                 return (sizeof(SYSTEMTIME) +4);
1760 }
1761
1762 /*******************************************************************
1763  * write a UNICODE string.
1764  * used by all the RPC structs passing a buffer
1765  ********************************************************************/
1766
1767 static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
1768 {
1769         if (uni == NULL)
1770                 return False;
1771
1772         prs_debug(ps, depth, desc, "spoolss_smb_io_unistr");
1773         depth++;
1774         
1775         /* there should be no align here as it can mess up
1776            parsing a NEW_BUFFER->prs */
1777 #if 0   /* JERRY */
1778         if (!prs_align(ps))
1779                 return False;
1780 #endif
1781                 
1782         if (!prs_unistr("unistr", ps, depth, uni))
1783                 return False;
1784
1785         return True;
1786 }
1787
1788 /*******************************************************************
1789  * write a UNICODE string and its relative pointer.
1790  * used by all the RPC structs passing a buffer
1791  *
1792  * As I'm a nice guy, I'm forcing myself to explain this code.
1793  * MS did a good job in the overall spoolss code except in some
1794  * functions where they are passing the API buffer directly in the
1795  * RPC request/reply. That's to maintain compatiility at the API level.
1796  * They could have done it the good way the first time.
1797  *
1798  * So what happen is: the strings are written at the buffer's end, 
1799  * in the reverse order of the original structure. Some pointers to
1800  * the strings are also in the buffer. Those are relative to the
1801  * buffer's start.
1802  *
1803  * If you don't understand or want to change that function,
1804  * first get in touch with me: jfm@samba.org
1805  *
1806  ********************************************************************/
1807
1808 static BOOL smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
1809 {
1810         prs_struct *ps=&buffer->prs;
1811         
1812         if (MARSHALLING(ps)) {
1813                 uint32 struct_offset = prs_offset(ps);
1814                 uint32 relative_offset;
1815                 
1816                 buffer->string_at_end -= (size_of_relative_string(string) - 4);
1817                 if(!prs_set_offset(ps, buffer->string_at_end))
1818                         return False;
1819                 if (!prs_align(ps))
1820                         return False;
1821                 buffer->string_at_end = prs_offset(ps);
1822                 
1823                 /* write the string */
1824                 if (!smb_io_unistr(desc, string, ps, depth))
1825                         return False;
1826
1827                 if(!prs_set_offset(ps, struct_offset))
1828                         return False;
1829                 
1830                 relative_offset=buffer->string_at_end - buffer->struct_start;
1831                 /* write its offset */
1832                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1833                         return False;
1834         }
1835         else {
1836                 uint32 old_offset;
1837                 
1838                 /* read the offset */
1839                 if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
1840                         return False;
1841
1842                 old_offset = prs_offset(ps);
1843                 if(!prs_set_offset(ps, buffer->string_at_end+buffer->struct_start))
1844                         return False;
1845
1846                 /* read the string */
1847                 if (!spoolss_smb_io_unistr(desc, string, ps, depth))
1848                         return False;
1849
1850                 if(!prs_set_offset(ps, old_offset))
1851                         return False;
1852         }
1853         return True;
1854 }
1855
1856 /*******************************************************************
1857  * write a array of UNICODE strings and its relative pointer.
1858  * used by 2 RPC structs
1859  ********************************************************************/
1860
1861 static BOOL smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string)
1862 {
1863         UNISTR chaine;
1864         
1865         prs_struct *ps=&buffer->prs;
1866         
1867         if (MARSHALLING(ps)) {
1868                 uint32 struct_offset = prs_offset(ps);
1869                 uint32 relative_offset;
1870                 uint16 *p;
1871                 uint16 *q;
1872                 uint16 zero=0;
1873                 p=*string;
1874                 q=*string;
1875
1876                 /* first write the last 0 */
1877                 buffer->string_at_end -= 2;
1878                 if(!prs_set_offset(ps, buffer->string_at_end))
1879                         return False;
1880
1881                 if(!prs_uint16("leading zero", ps, depth, &zero))
1882                         return False;
1883
1884                 while (p && (*p!=0)) {  
1885                         while (*q!=0)
1886                                 q++;
1887
1888                         /* Yes this should be malloc not talloc. Don't change. */
1889
1890                         chaine.buffer = malloc((q-p+1)*sizeof(uint16));
1891                         if (chaine.buffer == NULL)
1892                                 return False;
1893
1894                         memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16));
1895
1896                         buffer->string_at_end -= (q-p+1)*sizeof(uint16);
1897
1898                         if(!prs_set_offset(ps, buffer->string_at_end)) {
1899                                 SAFE_FREE(chaine.buffer);
1900                                 return False;
1901                         }
1902
1903                         /* write the string */
1904                         if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth)) {
1905                                 SAFE_FREE(chaine.buffer);
1906                                 return False;
1907                         }
1908                         q++;
1909                         p=q;
1910
1911                         SAFE_FREE(chaine.buffer);
1912                 }
1913                 
1914                 if(!prs_set_offset(ps, struct_offset))
1915                         return False;
1916                 
1917                 relative_offset=buffer->string_at_end - buffer->struct_start;
1918                 /* write its offset */
1919                 if (!prs_uint32("offset", ps, depth, &relative_offset))
1920                         return False;
1921
1922         } else {
1923
1924                 /* UNMARSHALLING */
1925
1926                 uint32 old_offset;
1927                 uint16 *chaine2=NULL;
1928                 int l_chaine=0;
1929                 int l_chaine2=0;
1930                 size_t realloc_size = 0;
1931
1932                 *string=NULL;
1933                                 
1934                 /* read the offset */
1935                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
1936                         return False;
1937
1938                 old_offset = prs_offset(ps);
1939                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
1940                         return False;
1941         
1942                 do {
1943                         if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth))
1944                                 return False;
1945                         
1946                         l_chaine=str_len_uni(&chaine);
1947                         
1948                         /* we're going to add two more bytes here in case this
1949                            is the last string in the array and we need to add 
1950                            an extra NULL for termination */
1951                         if (l_chaine > 0)
1952                         {
1953                                 uint16 *tc2;
1954                         
1955                                 realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16);
1956
1957                                 /* Yes this should be realloc - it's freed below. JRA */
1958
1959                                 if((tc2=(uint16 *)Realloc(chaine2, realloc_size)) == NULL) {
1960                                         SAFE_FREE(chaine2);
1961                                         return False;
1962                                 }
1963                                 else chaine2 = tc2;
1964                                 memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16));
1965                                 l_chaine2+=l_chaine+1;
1966                         }
1967                 
1968                 } while(l_chaine!=0);
1969                 
1970                 /* the end should be bould NULL terminated so add 
1971                    the second one here */
1972                 if (chaine2)
1973                 {
1974                         chaine2[l_chaine2] = '\0';
1975                         *string=(uint16 *)talloc_memdup(prs_get_mem_context(ps),chaine2,realloc_size);
1976                         SAFE_FREE(chaine2);
1977                 }
1978
1979                 if(!prs_set_offset(ps, old_offset))
1980                         return False;
1981         }
1982         return True;
1983 }
1984
1985 /*******************************************************************
1986  Parse a DEVMODE structure and its relative pointer.
1987 ********************************************************************/
1988
1989 static BOOL smb_io_relsecdesc(char *desc, NEW_BUFFER *buffer, int depth, SEC_DESC **secdesc)
1990 {
1991         prs_struct *ps= &buffer->prs;
1992
1993         prs_debug(ps, depth, desc, "smb_io_relsecdesc");
1994         depth++;
1995
1996         if (MARSHALLING(ps)) {
1997                 uint32 struct_offset = prs_offset(ps);
1998                 uint32 relative_offset;
1999
2000                 if (! *secdesc) {
2001                         relative_offset = 0;
2002                         if (!prs_uint32("offset", ps, depth, &relative_offset))
2003                                 return False;
2004                         return True;
2005                 }
2006                 
2007                 if (*secdesc != NULL) {
2008                         buffer->string_at_end -= sec_desc_size(*secdesc);
2009
2010                         if(!prs_set_offset(ps, buffer->string_at_end))
2011                                 return False;
2012                         /* write the secdesc */
2013                         if (!sec_io_desc(desc, secdesc, ps, depth))
2014                                 return False;
2015
2016                         if(!prs_set_offset(ps, struct_offset))
2017                                 return False;
2018                 }
2019
2020                 relative_offset=buffer->string_at_end - buffer->struct_start;
2021                 /* write its offset */
2022
2023                 if (!prs_uint32("offset", ps, depth, &relative_offset))
2024                         return False;
2025         } else {
2026                 uint32 old_offset;
2027                 
2028                 /* read the offset */
2029                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2030                         return False;
2031
2032                 old_offset = prs_offset(ps);
2033                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2034                         return False;
2035
2036                 /* read the sd */
2037                 if (!sec_io_desc(desc, secdesc, ps, depth))
2038                         return False;
2039
2040                 if(!prs_set_offset(ps, old_offset))
2041                         return False;
2042         }
2043         return True;
2044 }
2045
2046 /*******************************************************************
2047  Parse a DEVMODE structure and its relative pointer.
2048 ********************************************************************/
2049
2050 static BOOL smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2051 {
2052         prs_struct *ps=&buffer->prs;
2053
2054         prs_debug(ps, depth, desc, "smb_io_reldevmode");
2055         depth++;
2056
2057         if (MARSHALLING(ps)) {
2058                 uint32 struct_offset = prs_offset(ps);
2059                 uint32 relative_offset;
2060                 
2061                 if (*devmode == NULL) {
2062                         relative_offset=0;
2063                         if (!prs_uint32("offset", ps, depth, &relative_offset))
2064                                 return False;
2065                         DEBUG(8, ("boing, the devmode was NULL\n"));
2066                         
2067                         return True;
2068                 }
2069                 
2070                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2071                 
2072                 if(!prs_set_offset(ps, buffer->string_at_end))
2073                         return False;
2074                 
2075                 /* write the DEVMODE */
2076                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2077                         return False;
2078
2079                 if(!prs_set_offset(ps, struct_offset))
2080                         return False;
2081                 
2082                 relative_offset=buffer->string_at_end - buffer->struct_start;
2083                 /* write its offset */
2084                 if (!prs_uint32("offset", ps, depth, &relative_offset))
2085                         return False;
2086         }
2087         else {
2088                 uint32 old_offset;
2089                 
2090                 /* read the offset */
2091                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2092                         return False;
2093
2094                 old_offset = prs_offset(ps);
2095                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2096                         return False;
2097
2098                 /* read the string */
2099                 if((*devmode=(DEVICEMODE *)prs_alloc_mem(ps,sizeof(DEVICEMODE))) == NULL)
2100                         return False;
2101                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2102                         return False;
2103
2104                 if(!prs_set_offset(ps, old_offset))
2105                         return False;
2106         }
2107         return True;
2108 }
2109
2110 /*******************************************************************
2111  Parse a PRINTER_INFO_0 structure.
2112 ********************************************************************/  
2113
2114 BOOL smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2115 {
2116         prs_struct *ps=&buffer->prs;
2117
2118         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2119         depth++;        
2120         
2121         buffer->struct_start=prs_offset(ps);
2122
2123         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2124                 return False;
2125         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2126                 return False;
2127         
2128         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2129                 return False;
2130         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2131                 return False;
2132         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2133                 return False;
2134
2135         if(!prs_uint16("year", ps, depth, &info->year))
2136                 return False;
2137         if(!prs_uint16("month", ps, depth, &info->month))
2138                 return False;
2139         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2140                 return False;
2141         if(!prs_uint16("day", ps, depth, &info->day))
2142                 return False;
2143         if(!prs_uint16("hour", ps, depth, &info->hour))
2144                 return False;
2145         if(!prs_uint16("minute", ps, depth, &info->minute))
2146                 return False;
2147         if(!prs_uint16("second", ps, depth, &info->second))
2148                 return False;
2149         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2150                 return False;
2151
2152         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2153                 return False;
2154         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2155                 return False;
2156
2157         if(!prs_uint16("major_version", ps, depth, &info->major_version))
2158                 return False;
2159         if(!prs_uint16("build_version", ps, depth, &info->build_version))
2160                 return False;
2161         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2162                 return False;
2163         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2164                 return False;
2165         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2166                 return False;
2167         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2168                 return False;
2169         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2170                 return False;
2171         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2172                 return False;
2173         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2174                 return False;
2175         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2176                 return False;
2177         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2178                 return False;
2179         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2180                 return False;
2181         if(!prs_uint32("change_id", ps, depth, &info->change_id))
2182                 return False;
2183         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2184                 return False;
2185         if(!prs_uint32("status"   , ps, depth, &info->status))
2186                 return False;
2187         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2188                 return False;
2189         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2190                 return False;
2191         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2192                 return False;
2193         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2194                 return False;
2195         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2196                 return False;
2197         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2198                 return False;
2199         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2200                 return False;
2201         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2202                 return False;
2203         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2204                 return False;
2205         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2206                 return False;
2207
2208         return True;
2209 }
2210
2211 /*******************************************************************
2212  Parse a PRINTER_INFO_1 structure.
2213 ********************************************************************/  
2214
2215 BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2216 {
2217         prs_struct *ps=&buffer->prs;
2218
2219         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2220         depth++;        
2221         
2222         buffer->struct_start=prs_offset(ps);
2223
2224         if (!prs_uint32("flags", ps, depth, &info->flags))
2225                 return False;
2226         if (!smb_io_relstr("description", buffer, depth, &info->description))
2227                 return False;
2228         if (!smb_io_relstr("name", buffer, depth, &info->name))
2229                 return False;
2230         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2231                 return False;   
2232
2233         return True;
2234 }
2235
2236 /*******************************************************************
2237  Parse a PRINTER_INFO_2 structure.
2238 ********************************************************************/  
2239
2240 BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2241 {
2242         prs_struct *ps=&buffer->prs;
2243
2244         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2245         depth++;        
2246         
2247         buffer->struct_start=prs_offset(ps);
2248         
2249         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2250                 return False;
2251         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2252                 return False;
2253         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2254                 return False;
2255         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2256                 return False;
2257         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2258                 return False;
2259         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2260                 return False;
2261         if (!smb_io_relstr("location", buffer, depth, &info->location))
2262                 return False;
2263
2264         /* NT parses the DEVMODE at the end of the struct */
2265         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2266                 return False;
2267         
2268         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2269                 return False;
2270         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2271                 return False;
2272         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2273                 return False;
2274         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2275                 return False;
2276
2277         if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2278                 return False;
2279
2280         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2281                 return False;
2282         if (!prs_uint32("priority", ps, depth, &info->priority))
2283                 return False;
2284         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2285                 return False;
2286         if (!prs_uint32("starttime", ps, depth, &info->starttime))
2287                 return False;
2288         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2289                 return False;
2290         if (!prs_uint32("status", ps, depth, &info->status))
2291                 return False;
2292         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2293                 return False;
2294         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2295                 return False;
2296
2297 #if 0 /* JFMTEST */
2298         if (!prs_uint32_post("secdesc_ptr", ps, depth, NULL, sec_offset, info->secdesc ? prs_offset(ps)-buffer->struct_start : 0 ))
2299                 return False;
2300
2301         if (!sec_io_desc("secdesc", &info->secdesc, ps, depth)) 
2302                 return False;
2303 #endif
2304         return True;
2305 }
2306
2307 /*******************************************************************
2308  Parse a PRINTER_INFO_3 structure.
2309 ********************************************************************/  
2310
2311 BOOL smb_io_printer_info_3(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2312 {
2313         prs_struct *ps=&buffer->prs;
2314
2315         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2316         depth++;        
2317         
2318         buffer->struct_start=prs_offset(ps);
2319         
2320         if (!prs_uint32("flags", ps, depth, &info->flags))
2321                 return False;
2322         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2323                 return False;
2324
2325         return True;
2326 }
2327
2328 /*******************************************************************
2329  Parse a PRINTER_INFO_4 structure.
2330 ********************************************************************/  
2331
2332 BOOL smb_io_printer_info_4(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2333 {
2334         prs_struct *ps=&buffer->prs;
2335
2336         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2337         depth++;        
2338         
2339         buffer->struct_start=prs_offset(ps);
2340         
2341         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2342                 return False;
2343         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2344                 return False;
2345         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2346                 return False;
2347         return True;
2348 }
2349
2350 /*******************************************************************
2351  Parse a PRINTER_INFO_5 structure.
2352 ********************************************************************/  
2353
2354 BOOL smb_io_printer_info_5(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2355 {
2356         prs_struct *ps=&buffer->prs;
2357
2358         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2359         depth++;        
2360         
2361         buffer->struct_start=prs_offset(ps);
2362         
2363         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2364                 return False;
2365         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2366                 return False;
2367         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2368                 return False;
2369         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2370                 return False;
2371         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2372                 return False;
2373         return True;
2374 }
2375
2376 /*******************************************************************
2377  Parse a PORT_INFO_1 structure.
2378 ********************************************************************/  
2379
2380 BOOL smb_io_port_info_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2381 {
2382         prs_struct *ps=&buffer->prs;
2383
2384         prs_debug(ps, depth, desc, "smb_io_port_info_1");
2385         depth++;        
2386         
2387         buffer->struct_start=prs_offset(ps);
2388         
2389         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2390                 return False;
2391
2392         return True;
2393 }
2394
2395 /*******************************************************************
2396  Parse a PORT_INFO_2 structure.
2397 ********************************************************************/  
2398
2399 BOOL smb_io_port_info_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2400 {
2401         prs_struct *ps=&buffer->prs;
2402
2403         prs_debug(ps, depth, desc, "smb_io_port_info_2");
2404         depth++;        
2405         
2406         buffer->struct_start=prs_offset(ps);
2407         
2408         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2409                 return False;
2410         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2411                 return False;
2412         if (!smb_io_relstr("description", buffer, depth, &info->description))
2413                 return False;
2414         if (!prs_uint32("port_type", ps, depth, &info->port_type))
2415                 return False;
2416         if (!prs_uint32("reserved", ps, depth, &info->reserved))
2417                 return False;
2418
2419         return True;
2420 }
2421
2422 /*******************************************************************
2423  Parse a DRIVER_INFO_1 structure.
2424 ********************************************************************/
2425
2426 BOOL smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
2427 {
2428         prs_struct *ps=&buffer->prs;
2429
2430         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2431         depth++;        
2432         
2433         buffer->struct_start=prs_offset(ps);
2434
2435         if (!smb_io_relstr("name", buffer, depth, &info->name))
2436                 return False;
2437
2438         return True;
2439 }
2440
2441 /*******************************************************************
2442  Parse a DRIVER_INFO_2 structure.
2443 ********************************************************************/
2444
2445 BOOL smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
2446 {
2447         prs_struct *ps=&buffer->prs;
2448
2449         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2450         depth++;        
2451         
2452         buffer->struct_start=prs_offset(ps);
2453
2454         if (!prs_uint32("version", ps, depth, &info->version))
2455                 return False;
2456         if (!smb_io_relstr("name", buffer, depth, &info->name))
2457                 return False;
2458         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2459                 return False;
2460         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2461                 return False;
2462         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2463                 return False;
2464         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2465                 return False;
2466
2467         return True;
2468 }
2469
2470 /*******************************************************************
2471  Parse a DRIVER_INFO_3 structure.
2472 ********************************************************************/
2473
2474 BOOL smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2475 {
2476         prs_struct *ps=&buffer->prs;
2477
2478         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2479         depth++;        
2480         
2481         buffer->struct_start=prs_offset(ps);
2482
2483         if (!prs_uint32("version", ps, depth, &info->version))
2484                 return False;
2485         if (!smb_io_relstr("name", buffer, depth, &info->name))
2486                 return False;
2487         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2488                 return False;
2489         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2490                 return False;
2491         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2492                 return False;
2493         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2494                 return False;
2495         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2496                 return False;
2497
2498         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2499                 return False;
2500
2501         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2502                 return False;
2503         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2504                 return False;
2505
2506         return True;
2507 }
2508
2509 /*******************************************************************
2510  Parse a DRIVER_INFO_6 structure.
2511 ********************************************************************/
2512
2513 BOOL smb_io_printer_driver_info_6(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2514 {
2515         prs_struct *ps=&buffer->prs;
2516
2517         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2518         depth++;        
2519         
2520         buffer->struct_start=prs_offset(ps);
2521
2522         if (!prs_uint32("version", ps, depth, &info->version))
2523                 return False;
2524         if (!smb_io_relstr("name", buffer, depth, &info->name))
2525                 return False;
2526         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2527                 return False;
2528         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2529                 return False;
2530         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2531                 return False;
2532         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2533                 return False;
2534         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2535                 return False;
2536
2537         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2538                 return False;
2539
2540         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2541                 return False;
2542         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2543                 return False;
2544
2545         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2546                 return False;
2547
2548         if (!prs_uint32("date.low", ps, depth, &info->driver_date.low))
2549                 return False;
2550         if (!prs_uint32("date.high", ps, depth, &info->driver_date.high))
2551                 return False;
2552
2553         if (!prs_uint32("padding", ps, depth, &info->padding))
2554                 return False;
2555
2556         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2557                 return False;
2558
2559         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2560                 return False;
2561
2562         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2563                 return False;
2564         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2565                 return False;
2566         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2567                 return False;
2568         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2569                 return False;
2570         
2571         return True;
2572 }
2573
2574 /*******************************************************************
2575  Parse a JOB_INFO_1 structure.
2576 ********************************************************************/  
2577
2578 BOOL smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2579 {
2580         prs_struct *ps=&buffer->prs;
2581
2582         prs_debug(ps, depth, desc, "smb_io_job_info_1");
2583         depth++;        
2584         
2585         buffer->struct_start=prs_offset(ps);
2586
2587         if (!prs_uint32("jobid", ps, depth, &info->jobid))
2588                 return False;
2589         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2590                 return False;
2591         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2592                 return False;
2593         if (!smb_io_relstr("username", buffer, depth, &info->username))
2594                 return False;
2595         if (!smb_io_relstr("document", buffer, depth, &info->document))
2596                 return False;
2597         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2598                 return False;
2599         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2600                 return False;
2601         if (!prs_uint32("status", ps, depth, &info->status))
2602                 return False;
2603         if (!prs_uint32("priority", ps, depth, &info->priority))
2604                 return False;
2605         if (!prs_uint32("position", ps, depth, &info->position))
2606                 return False;
2607         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2608                 return False;
2609         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2610                 return False;
2611         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2612                 return False;
2613
2614         return True;
2615 }
2616
2617 /*******************************************************************
2618  Parse a JOB_INFO_2 structure.
2619 ********************************************************************/  
2620
2621 BOOL smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2622 {       
2623         uint32 pipo=0;
2624         prs_struct *ps=&buffer->prs;
2625         
2626         prs_debug(ps, depth, desc, "smb_io_job_info_2");
2627         depth++;        
2628
2629         buffer->struct_start=prs_offset(ps);
2630         
2631         if (!prs_uint32("jobid",ps, depth, &info->jobid))
2632                 return False;
2633         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2634                 return False;
2635         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2636                 return False;
2637         if (!smb_io_relstr("username", buffer, depth, &info->username))
2638                 return False;
2639         if (!smb_io_relstr("document", buffer, depth, &info->document))
2640                 return False;
2641         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2642                 return False;
2643         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2644                 return False;
2645
2646         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2647                 return False;
2648         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2649                 return False;
2650         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2651                 return False;
2652         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2653                 return False;
2654         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2655                 return False;
2656
2657 /*      SEC_DESC sec_desc;*/
2658         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2659                 return False;
2660
2661         if (!prs_uint32("status",ps, depth, &info->status))
2662                 return False;
2663         if (!prs_uint32("priority",ps, depth, &info->priority))
2664                 return False;
2665         if (!prs_uint32("position",ps, depth, &info->position)) 
2666                 return False;
2667         if (!prs_uint32("starttime",ps, depth, &info->starttime))
2668                 return False;
2669         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2670                 return False;
2671         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2672                 return False;
2673         if (!prs_uint32("size",ps, depth, &info->size))
2674                 return False;
2675         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2676                 return False;
2677         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2678                 return False;
2679         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2680                 return False;
2681
2682         return True;
2683 }
2684
2685 /*******************************************************************
2686 ********************************************************************/  
2687
2688 BOOL smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
2689 {
2690         prs_struct *ps=&buffer->prs;
2691         
2692         prs_debug(ps, depth, desc, "smb_io_form_1");
2693         depth++;
2694                 
2695         buffer->struct_start=prs_offset(ps);
2696         
2697         if (!prs_uint32("flag", ps, depth, &info->flag))
2698                 return False;
2699                 
2700         if (!smb_io_relstr("name", buffer, depth, &info->name))
2701                 return False;
2702
2703         if (!prs_uint32("width", ps, depth, &info->width))
2704                 return False;
2705         if (!prs_uint32("length", ps, depth, &info->length))
2706                 return False;
2707         if (!prs_uint32("left", ps, depth, &info->left))
2708                 return False;
2709         if (!prs_uint32("top", ps, depth, &info->top))
2710                 return False;
2711         if (!prs_uint32("right", ps, depth, &info->right))
2712                 return False;
2713         if (!prs_uint32("bottom", ps, depth, &info->bottom))
2714                 return False;
2715
2716         return True;
2717 }
2718
2719 /*******************************************************************
2720  Read/write a BUFFER struct.
2721 ********************************************************************/  
2722
2723 static BOOL spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER **pp_buffer)
2724 {
2725         NEW_BUFFER *buffer = *pp_buffer;
2726
2727         prs_debug(ps, depth, desc, "spoolss_io_buffer");
2728         depth++;
2729         
2730         if (UNMARSHALLING(ps))
2731                 buffer = *pp_buffer = (NEW_BUFFER *)prs_alloc_mem(ps, sizeof(NEW_BUFFER));
2732
2733         if (buffer == NULL)
2734                 return False;
2735
2736         if (!prs_uint32("ptr", ps, depth, &buffer->ptr))
2737                 return False;
2738         
2739         /* reading */
2740         if (UNMARSHALLING(ps)) {
2741                 buffer->size=0;
2742                 buffer->string_at_end=0;
2743                 
2744                 if (buffer->ptr==0) {
2745                         /*
2746                          * JRA. I'm not sure if the data in here is in big-endian format if
2747                          * the client is big-endian. Leave as default (little endian) for now.
2748                          */
2749
2750                         if (!prs_init(&buffer->prs, 0, prs_get_mem_context(ps), UNMARSHALL))
2751                                 return False;
2752                         return True;
2753                 }
2754                 
2755                 if (!prs_uint32("size", ps, depth, &buffer->size))
2756                         return False;
2757                                         
2758                 /*
2759                  * JRA. I'm not sure if the data in here is in big-endian format if
2760                  * the client is big-endian. Leave as default (little endian) for now.
2761                  */
2762
2763                 if (!prs_init(&buffer->prs, buffer->size, prs_get_mem_context(ps), UNMARSHALL))
2764                         return False;
2765
2766                 if (!prs_append_some_prs_data(&buffer->prs, ps, prs_offset(ps), buffer->size))
2767                         return False;
2768
2769                 if (!prs_set_offset(&buffer->prs, 0))
2770                         return False;
2771
2772                 if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
2773                         return False;
2774
2775                 buffer->string_at_end=buffer->size;
2776                 
2777                 return True;
2778         }
2779         else {
2780                 BOOL ret = False;
2781
2782                 /* writing */
2783                 if (buffer->ptr==0) {
2784                         /* We have finished with the data in buffer->prs - free it. */
2785                         prs_mem_free(&buffer->prs);
2786                         return True;
2787                 }
2788         
2789                 if (!prs_uint32("size", ps, depth, &buffer->size))
2790                         goto out;
2791
2792                 if (!prs_append_some_prs_data(ps, &buffer->prs, 0, buffer->size))
2793                         goto out;
2794
2795                 ret = True;
2796         out:
2797
2798                 /* We have finished with the data in buffer->prs - free it. */
2799                 prs_mem_free(&buffer->prs);
2800
2801                 return ret;
2802         }
2803 }
2804
2805 /*******************************************************************
2806  move a BUFFER from the query to the reply.
2807  As the data pointers in NEW_BUFFER are malloc'ed, not talloc'ed,
2808  this is ok. This is an OPTIMIZATION and is not strictly neccessary.
2809  Clears the memory to zero also.
2810 ********************************************************************/  
2811
2812 void spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
2813 {
2814         prs_switch_type(&src->prs, MARSHALL);
2815         if(!prs_set_offset(&src->prs, 0))
2816                 return;
2817         prs_force_dynamic(&src->prs);
2818         prs_mem_clear(&src->prs);
2819         *dest=src;
2820 }
2821
2822 /*******************************************************************
2823  Get the size of a BUFFER struct.
2824 ********************************************************************/  
2825
2826 uint32 new_get_buffer_size(NEW_BUFFER *buffer)
2827 {
2828         return (buffer->size);
2829 }
2830
2831 /*******************************************************************
2832  Parse a DRIVER_DIRECTORY_1 structure.
2833 ********************************************************************/  
2834
2835 BOOL smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2836 {
2837         prs_struct *ps=&buffer->prs;
2838
2839         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2840         depth++;
2841
2842         buffer->struct_start=prs_offset(ps);
2843
2844         if (!smb_io_unistr(desc, &info->name, ps, depth))
2845                 return False;
2846
2847         return True;
2848 }
2849
2850 /*******************************************************************
2851  Parse a PORT_INFO_1 structure.
2852 ********************************************************************/  
2853
2854 BOOL smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2855 {
2856         prs_struct *ps=&buffer->prs;
2857
2858         prs_debug(ps, depth, desc, "smb_io_port_1");
2859         depth++;
2860
2861         buffer->struct_start=prs_offset(ps);
2862
2863         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2864                 return False;
2865
2866         return True;
2867 }
2868
2869 /*******************************************************************
2870  Parse a PORT_INFO_2 structure.
2871 ********************************************************************/  
2872
2873 BOOL smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2874 {
2875         prs_struct *ps=&buffer->prs;
2876
2877         prs_debug(ps, depth, desc, "smb_io_port_2");
2878         depth++;
2879
2880         buffer->struct_start=prs_offset(ps);
2881
2882         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2883                 return False;
2884         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2885                 return False;
2886         if(!smb_io_relstr("description", buffer, depth, &info->description))
2887                 return False;
2888         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2889                 return False;
2890         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2891                 return False;
2892
2893         return True;
2894 }
2895
2896 /*******************************************************************
2897 ********************************************************************/  
2898
2899 BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2900 {
2901         prs_struct *ps=&buffer->prs;
2902
2903         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2904         depth++;        
2905
2906         buffer->struct_start=prs_offset(ps);
2907         
2908         if (smb_io_relstr("name", buffer, depth, &info->name))
2909                 return False;
2910
2911         return True;
2912 }
2913
2914 /*******************************************************************
2915 ********************************************************************/  
2916
2917 BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2918 {
2919         prs_struct *ps=&buffer->prs;
2920
2921         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2922         depth++;        
2923
2924         buffer->struct_start=prs_offset(ps);
2925         
2926         if (smb_io_relstr("name", buffer, depth, &info->name))
2927                 return False;
2928
2929         return True;
2930 }
2931
2932 /*******************************************************************
2933 ********************************************************************/  
2934
2935 BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2936 {
2937         prs_struct *ps=&buffer->prs;
2938
2939         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2940         depth++;        
2941
2942         buffer->struct_start=prs_offset(ps);
2943
2944         if (!smb_io_relstr("name", buffer, depth, &info->name))
2945                 return False;
2946
2947         return True;
2948 }
2949
2950 /*******************************************************************
2951 ********************************************************************/  
2952
2953 BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
2954 {
2955         prs_struct *ps=&buffer->prs;
2956
2957         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
2958         depth++;        
2959
2960         buffer->struct_start=prs_offset(ps);
2961
2962         if (!smb_io_relstr("name", buffer, depth, &info->name))
2963                 return False;
2964         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
2965                 return False;
2966         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
2967                 return False;
2968
2969         return True;
2970 }
2971
2972 /*******************************************************************
2973 return the size required by a struct in the stream
2974 ********************************************************************/  
2975
2976 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
2977 {
2978         int size=0;
2979         
2980         size+=size_of_relative_string( &info->printername );
2981         size+=size_of_relative_string( &info->servername );
2982
2983         size+=size_of_uint32( &info->cjobs);
2984         size+=size_of_uint32( &info->total_jobs);
2985         size+=size_of_uint32( &info->total_bytes);
2986
2987         size+=size_of_uint16( &info->year);
2988         size+=size_of_uint16( &info->month);
2989         size+=size_of_uint16( &info->dayofweek);
2990         size+=size_of_uint16( &info->day);
2991         size+=size_of_uint16( &info->hour);
2992         size+=size_of_uint16( &info->minute);
2993         size+=size_of_uint16( &info->second);
2994         size+=size_of_uint16( &info->milliseconds);
2995
2996         size+=size_of_uint32( &info->global_counter);
2997         size+=size_of_uint32( &info->total_pages);
2998
2999         size+=size_of_uint16( &info->major_version);
3000         size+=size_of_uint16( &info->build_version);
3001
3002         size+=size_of_uint32( &info->unknown7);
3003         size+=size_of_uint32( &info->unknown8);
3004         size+=size_of_uint32( &info->unknown9);
3005         size+=size_of_uint32( &info->session_counter);
3006         size+=size_of_uint32( &info->unknown11);
3007         size+=size_of_uint32( &info->printer_errors);
3008         size+=size_of_uint32( &info->unknown13);
3009         size+=size_of_uint32( &info->unknown14);
3010         size+=size_of_uint32( &info->unknown15);
3011         size+=size_of_uint32( &info->unknown16);
3012         size+=size_of_uint32( &info->change_id);
3013         size+=size_of_uint32( &info->unknown18);
3014         size+=size_of_uint32( &info->status);
3015         size+=size_of_uint32( &info->unknown20);
3016         size+=size_of_uint32( &info->c_setprinter);
3017         
3018         size+=size_of_uint16( &info->unknown22);
3019         size+=size_of_uint16( &info->unknown23);
3020         size+=size_of_uint16( &info->unknown24);
3021         size+=size_of_uint16( &info->unknown25);
3022         size+=size_of_uint16( &info->unknown26);
3023         size+=size_of_uint16( &info->unknown27);
3024         size+=size_of_uint16( &info->unknown28);
3025         size+=size_of_uint16( &info->unknown29);
3026         
3027         return size;
3028 }
3029
3030 /*******************************************************************
3031 return the size required by a struct in the stream
3032 ********************************************************************/  
3033
3034 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3035 {
3036         int size=0;
3037                 
3038         size+=size_of_uint32( &info->flags );   
3039         size+=size_of_relative_string( &info->description );
3040         size+=size_of_relative_string( &info->name );
3041         size+=size_of_relative_string( &info->comment );
3042
3043         return size;
3044 }
3045
3046 /*******************************************************************
3047 return the size required by a struct in the stream
3048 ********************************************************************/
3049
3050 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3051 {
3052         uint32 size=0;
3053                 
3054         size += 4;
3055         /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
3056         size += sec_desc_size( info->secdesc );
3057
3058         size+=size_of_device_mode( info->devmode );
3059         
3060         size+=size_of_relative_string( &info->servername );
3061         size+=size_of_relative_string( &info->printername );
3062         size+=size_of_relative_string( &info->sharename );
3063         size+=size_of_relative_string( &info->portname );
3064         size+=size_of_relative_string( &info->drivername );
3065         size+=size_of_relative_string( &info->comment );
3066         size+=size_of_relative_string( &info->location );
3067         
3068         size+=size_of_relative_string( &info->sepfile );
3069         size+=size_of_relative_string( &info->printprocessor );
3070         size+=size_of_relative_string( &info->datatype );
3071         size+=size_of_relative_string( &info->parameters );
3072
3073         size+=size_of_uint32( &info->attributes );
3074         size+=size_of_uint32( &info->priority );
3075         size+=size_of_uint32( &info->defaultpriority );
3076         size+=size_of_uint32( &info->starttime );
3077         size+=size_of_uint32( &info->untiltime );
3078         size+=size_of_uint32( &info->status );
3079         size+=size_of_uint32( &info->cjobs );
3080         size+=size_of_uint32( &info->averageppm );      
3081         return size;
3082 }
3083
3084 /*******************************************************************
3085 return the size required by a struct in the stream
3086 ********************************************************************/
3087
3088 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3089 {
3090         uint32 size=0;
3091                 
3092         size+=size_of_relative_string( &info->printername );
3093         size+=size_of_relative_string( &info->servername );
3094
3095         size+=size_of_uint32( &info->attributes );
3096         return size;
3097 }
3098
3099 /*******************************************************************
3100 return the size required by a struct in the stream
3101 ********************************************************************/
3102
3103 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3104 {
3105         uint32 size=0;
3106                 
3107         size+=size_of_relative_string( &info->printername );
3108         size+=size_of_relative_string( &info->portname );
3109
3110         size+=size_of_uint32( &info->attributes );
3111         size+=size_of_uint32( &info->device_not_selected_timeout );
3112         size+=size_of_uint32( &info->transmission_retry_timeout );
3113         return size;
3114 }
3115
3116
3117 /*******************************************************************
3118 return the size required by a struct in the stream
3119 ********************************************************************/
3120
3121 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3122 {
3123         /* The 4 is for the self relative pointer.. */
3124         /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
3125         return 4 + (uint32)sec_desc_size( info->secdesc );
3126 }
3127
3128 /*******************************************************************
3129 return the size required by a struct in the stream
3130 ********************************************************************/
3131
3132 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3133 {
3134         int size=0;
3135         size+=size_of_relative_string( &info->name );
3136
3137         return size;
3138 }
3139
3140 /*******************************************************************
3141 return the size required by a struct in the stream
3142 ********************************************************************/
3143
3144 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3145 {
3146         int size=0;
3147         size+=size_of_uint32( &info->version ); 
3148         size+=size_of_relative_string( &info->name );
3149         size+=size_of_relative_string( &info->architecture );
3150         size+=size_of_relative_string( &info->driverpath );
3151         size+=size_of_relative_string( &info->datafile );
3152         size+=size_of_relative_string( &info->configfile );
3153
3154         return size;
3155 }
3156
3157 /*******************************************************************
3158 return the size required by a string array.
3159 ********************************************************************/
3160
3161 uint32 spoolss_size_string_array(uint16 *string)
3162 {
3163         uint32 i = 0;
3164
3165         if (string) {
3166                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3167         }
3168         i=i+2; /* to count all chars including the leading zero */
3169         i=2*i; /* because we need the value in bytes */
3170         i=i+4; /* the offset pointer size */
3171
3172         return i;
3173 }
3174
3175 /*******************************************************************
3176 return the size required by a struct in the stream
3177 ********************************************************************/
3178
3179 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3180 {
3181         int size=0;
3182
3183         size+=size_of_uint32( &info->version ); 
3184         size+=size_of_relative_string( &info->name );
3185         size+=size_of_relative_string( &info->architecture );
3186         size+=size_of_relative_string( &info->driverpath );
3187         size+=size_of_relative_string( &info->datafile );
3188         size+=size_of_relative_string( &info->configfile );
3189         size+=size_of_relative_string( &info->helpfile );
3190         size+=size_of_relative_string( &info->monitorname );
3191         size+=size_of_relative_string( &info->defaultdatatype );
3192         
3193         size+=spoolss_size_string_array(info->dependentfiles);
3194
3195         return size;
3196 }
3197
3198 /*******************************************************************
3199 return the size required by a struct in the stream
3200 ********************************************************************/
3201
3202 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3203 {
3204         uint32 size=0;
3205
3206         size+=size_of_uint32( &info->version ); 
3207         size+=size_of_relative_string( &info->name );
3208         size+=size_of_relative_string( &info->architecture );
3209         size+=size_of_relative_string( &info->driverpath );
3210         size+=size_of_relative_string( &info->datafile );
3211         size+=size_of_relative_string( &info->configfile );
3212         size+=size_of_relative_string( &info->helpfile );
3213
3214         size+=spoolss_size_string_array(info->dependentfiles);
3215
3216         size+=size_of_relative_string( &info->monitorname );
3217         size+=size_of_relative_string( &info->defaultdatatype );
3218         
3219         size+=spoolss_size_string_array(info->previousdrivernames);
3220
3221         size+=size_of_nttime(&info->driver_date);
3222         size+=size_of_uint32( &info->padding ); 
3223         size+=size_of_uint32( &info->driver_version_low );      
3224         size+=size_of_uint32( &info->driver_version_high );     
3225         size+=size_of_relative_string( &info->mfgname );
3226         size+=size_of_relative_string( &info->oem_url );
3227         size+=size_of_relative_string( &info->hardware_id );
3228         size+=size_of_relative_string( &info->provider );
3229
3230         return size;
3231 }
3232
3233 /*******************************************************************
3234 return the size required by a struct in the stream
3235 ********************************************************************/  
3236
3237 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3238 {
3239         int size=0;
3240         size+=size_of_uint32( &info->jobid );
3241         size+=size_of_relative_string( &info->printername );
3242         size+=size_of_relative_string( &info->machinename );
3243         size+=size_of_relative_string( &info->username );
3244         size+=size_of_relative_string( &info->document );
3245         size+=size_of_relative_string( &info->datatype );
3246         size+=size_of_relative_string( &info->text_status );
3247         size+=size_of_uint32( &info->status );
3248         size+=size_of_uint32( &info->priority );
3249         size+=size_of_uint32( &info->position );
3250         size+=size_of_uint32( &info->totalpages );
3251         size+=size_of_uint32( &info->pagesprinted );
3252         size+=size_of_systemtime( &info->submitted );
3253
3254         return size;
3255 }
3256
3257 /*******************************************************************
3258 return the size required by a struct in the stream
3259 ********************************************************************/  
3260
3261 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3262 {
3263         int size=0;
3264
3265         size+=4; /* size of sec desc ptr */
3266
3267         size+=size_of_uint32( &info->jobid );
3268         size+=size_of_relative_string( &info->printername );
3269         size+=size_of_relative_string( &info->machinename );
3270         size+=size_of_relative_string( &info->username );
3271         size+=size_of_relative_string( &info->document );
3272         size+=size_of_relative_string( &info->notifyname );
3273         size+=size_of_relative_string( &info->datatype );
3274         size+=size_of_relative_string( &info->printprocessor );
3275         size+=size_of_relative_string( &info->parameters );
3276         size+=size_of_relative_string( &info->drivername );
3277         size+=size_of_device_mode( info->devmode );
3278         size+=size_of_relative_string( &info->text_status );
3279 /*      SEC_DESC sec_desc;*/
3280         size+=size_of_uint32( &info->status );
3281         size+=size_of_uint32( &info->priority );
3282         size+=size_of_uint32( &info->position );
3283         size+=size_of_uint32( &info->starttime );
3284         size+=size_of_uint32( &info->untiltime );
3285         size+=size_of_uint32( &info->totalpages );
3286         size+=size_of_uint32( &info->size );
3287         size+=size_of_systemtime( &info->submitted );
3288         size+=size_of_uint32( &info->timeelapsed );
3289         size+=size_of_uint32( &info->pagesprinted );
3290
3291         return size;
3292 }
3293
3294 /*******************************************************************
3295 return the size required by a struct in the stream
3296 ********************************************************************/
3297
3298 uint32 spoolss_size_form_1(FORM_1 *info)
3299 {
3300         int size=0;
3301
3302         size+=size_of_uint32( &info->flag );
3303         size+=size_of_relative_string( &info->name );
3304         size+=size_of_uint32( &info->width );
3305         size+=size_of_uint32( &info->length );
3306         size+=size_of_uint32( &info->left );
3307         size+=size_of_uint32( &info->top );
3308         size+=size_of_uint32( &info->right );
3309         size+=size_of_uint32( &info->bottom );
3310
3311         return size;
3312 }
3313
3314 /*******************************************************************
3315 return the size required by a struct in the stream
3316 ********************************************************************/  
3317
3318 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3319 {
3320         int size=0;
3321
3322         size+=size_of_relative_string( &info->port_name );
3323
3324         return size;
3325 }
3326
3327 /*******************************************************************
3328 return the size required by a struct in the stream
3329 ********************************************************************/  
3330
3331 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3332 {
3333         int size=0;
3334
3335         size=str_len_uni(&info->name);  /* the string length       */
3336         size=size+1;                    /* add the leading zero    */
3337         size=size*2;                    /* convert in char         */
3338
3339         return size;
3340 }
3341
3342 /*******************************************************************
3343 return the size required by a struct in the stream
3344 ********************************************************************/  
3345
3346 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3347 {
3348         int size=0;
3349
3350         size=str_len_uni(&info->name);  /* the string length       */
3351         size=size+1;                    /* add the leading zero    */
3352         size=size*2;                    /* convert in char         */
3353
3354         return size;
3355 }
3356
3357 /*******************************************************************
3358 return the size required by a struct in the stream
3359 ********************************************************************/  
3360
3361 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3362 {
3363         int size=0;
3364
3365         size+=size_of_relative_string( &info->port_name );
3366         size+=size_of_relative_string( &info->monitor_name );
3367         size+=size_of_relative_string( &info->description );
3368
3369         size+=size_of_uint32( &info->port_type );
3370         size+=size_of_uint32( &info->reserved );
3371
3372         return size;
3373 }
3374
3375 /*******************************************************************
3376 return the size required by a struct in the stream
3377 ********************************************************************/  
3378
3379 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
3380 {
3381         int size=0;
3382         size+=size_of_relative_string( &info->name );
3383
3384         return size;
3385 }
3386
3387 /*******************************************************************
3388 return the size required by a struct in the stream
3389 ********************************************************************/  
3390
3391 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
3392 {
3393         int size=0;
3394         size+=size_of_relative_string( &info->name );
3395
3396         return size;
3397 }
3398
3399 /*******************************************************************
3400 return the size required by a struct in the stream
3401 ********************************************************************/  
3402 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
3403 {
3404         uint32  size = 0; 
3405         
3406         if (!p)
3407                 return 0;
3408         
3409         /* uint32(offset) + uint32(length) + length) */
3410         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
3411         size += (size_of_uint32(&p->data_len)*2) + p->data_len;
3412         
3413         size += size_of_uint32(&p->type);
3414                        
3415         return size;
3416 }
3417
3418 /*******************************************************************
3419 return the size required by a struct in the stream
3420 ********************************************************************/  
3421
3422 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
3423 {
3424         int size=0;
3425         size+=size_of_relative_string( &info->name );
3426
3427         return size;
3428 }
3429
3430 /*******************************************************************
3431 return the size required by a struct in the stream
3432 ********************************************************************/  
3433
3434 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
3435 {
3436         int size=0;
3437         size+=size_of_relative_string( &info->name);
3438         size+=size_of_relative_string( &info->environment);
3439         size+=size_of_relative_string( &info->dll_name);
3440
3441         return size;
3442 }
3443
3444 /*******************************************************************
3445  * init a structure.
3446  ********************************************************************/
3447
3448 BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, 
3449                                const POLICY_HND *hnd,
3450                                const fstring architecture,
3451                                uint32 level, uint32 clientmajor, uint32 clientminor,
3452                                NEW_BUFFER *buffer, uint32 offered)
3453 {      
3454         if (q_u == NULL)
3455                 return False;
3456
3457         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3458
3459         init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture);
3460
3461         q_u->level=level;
3462         q_u->clientmajorversion=clientmajor;
3463         q_u->clientminorversion=clientminor;
3464
3465         q_u->buffer=buffer;
3466         q_u->offered=offered;
3467
3468         return True;
3469 }
3470
3471 /*******************************************************************
3472  * read a structure.
3473  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3474  ********************************************************************/
3475
3476 BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
3477 {
3478         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
3479         depth++;
3480
3481         if(!prs_align(ps))
3482                 return False;
3483         
3484         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3485                 return False;
3486         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
3487                 return False;
3488         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
3489                 return False;
3490         
3491         if(!prs_align(ps))
3492                 return False;
3493         if(!prs_uint32("level", ps, depth, &q_u->level))
3494                 return False;
3495                 
3496         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3497                 return False;
3498
3499         if(!prs_align(ps))
3500                 return False;
3501
3502         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3503                 return False;
3504                 
3505         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
3506                 return False;
3507         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
3508                 return False;
3509
3510         return True;
3511 }
3512
3513 /*******************************************************************
3514  * read a structure.
3515  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
3516  ********************************************************************/
3517
3518 BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
3519 {
3520         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
3521         depth++;
3522
3523         if (!prs_align(ps))
3524                 return False;
3525                 
3526         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3527                 return False;
3528
3529         if (!prs_align(ps))
3530                 return False;
3531         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3532                 return False;
3533         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
3534                 return False;
3535         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
3536                 return False;           
3537         if (!prs_werror("status", ps, depth, &r_u->status))
3538                 return False;
3539
3540         return True;            
3541 }
3542
3543 /*******************************************************************
3544  * init a structure.
3545  ********************************************************************/
3546
3547 BOOL make_spoolss_q_enumprinters(
3548         SPOOL_Q_ENUMPRINTERS *q_u, 
3549         uint32 flags, 
3550         fstring servername, 
3551         uint32 level, 
3552         NEW_BUFFER *buffer, 
3553         uint32 offered
3554 )
3555 {
3556         q_u->flags=flags;
3557         
3558         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
3559         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
3560
3561         q_u->level=level;
3562         q_u->buffer=buffer;
3563         q_u->offered=offered;
3564
3565         return True;
3566 }
3567
3568 /*******************************************************************
3569  * init a structure.
3570  ********************************************************************/
3571
3572 BOOL make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
3573                                 fstring servername, uint32 level, 
3574                                 NEW_BUFFER *buffer, uint32 offered)
3575 {
3576         q_u->name_ptr = (servername != NULL) ? 1 : 0;
3577         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
3578
3579         q_u->level=level;
3580         q_u->buffer=buffer;
3581         q_u->offered=offered;
3582
3583         return True;
3584 }
3585
3586 /*******************************************************************
3587  * read a structure.
3588  * called from spoolss_enumprinters (srv_spoolss.c)
3589  ********************************************************************/
3590
3591 BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
3592 {
3593         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
3594         depth++;
3595
3596         if (!prs_align(ps))
3597                 return False;
3598
3599         if (!prs_uint32("flags", ps, depth, &q_u->flags))
3600                 return False;
3601         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
3602                 return False;
3603
3604         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
3605                 return False;
3606                 
3607         if (!prs_align(ps))
3608                 return False;
3609         if (!prs_uint32("level", ps, depth, &q_u->level))
3610                 return False;
3611
3612         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3613                 return False;
3614
3615         if (!prs_align(ps))
3616                 return False;
3617         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3618                 return False;
3619
3620         return True;
3621 }
3622
3623 /*******************************************************************
3624  Parse a SPOOL_R_ENUMPRINTERS structure.
3625  ********************************************************************/
3626
3627 BOOL spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
3628 {
3629         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
3630         depth++;
3631
3632         if (!prs_align(ps))
3633                 return False;
3634                 
3635         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3636                 return False;
3637
3638         if (!prs_align(ps))
3639                 return False;
3640                 
3641         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3642                 return False;
3643                 
3644         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3645                 return False;
3646                 
3647         if (!prs_werror("status", ps, depth, &r_u->status))
3648                 return False;
3649
3650         return True;            
3651 }
3652
3653 /*******************************************************************
3654  * write a structure.
3655  * called from spoolss_r_enum_printers (srv_spoolss.c)
3656  *
3657  ********************************************************************/
3658
3659 BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
3660 {       
3661         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
3662         depth++;
3663
3664         if (!prs_align(ps))
3665                 return False;
3666                 
3667         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3668                 return False;
3669
3670         if (!prs_align(ps))
3671                 return False;
3672
3673         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3674                 return False;
3675                 
3676         if (!prs_werror("status", ps, depth, &r_u->status))
3677                 return False;
3678
3679         return True;            
3680 }
3681
3682 /*******************************************************************
3683  * read a structure.
3684  * called from spoolss_getprinter (srv_spoolss.c)
3685  ********************************************************************/
3686
3687 BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
3688 {
3689         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
3690         depth++;
3691
3692         if (!prs_align(ps))
3693                 return False;
3694
3695         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3696                 return False;
3697         if (!prs_uint32("level", ps, depth, &q_u->level))
3698                 return False;
3699
3700         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3701                 return False;
3702
3703         if (!prs_align(ps))
3704                 return False;
3705         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3706                 return False;
3707
3708         return True;
3709 }
3710
3711 /*******************************************************************
3712  * init a structure.
3713  ********************************************************************/
3714
3715 BOOL make_spoolss_q_getprinter(
3716         TALLOC_CTX *mem_ctx,
3717         SPOOL_Q_GETPRINTER *q_u, 
3718         const POLICY_HND *hnd, 
3719         uint32 level, 
3720         NEW_BUFFER *buffer, 
3721         uint32 offered
3722 )
3723 {
3724         if (q_u == NULL)
3725         {
3726                 return False;
3727         }
3728         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3729
3730         q_u->level=level;
3731         q_u->buffer=buffer;
3732         q_u->offered=offered;
3733
3734         return True;
3735 }
3736
3737 /*******************************************************************
3738  * init a structure.
3739  ********************************************************************/
3740 BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
3741                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
3742                                 uint32 command)
3743 {
3744         SEC_DESC *secdesc;
3745         DEVICEMODE *devmode;
3746
3747         if (q_u == NULL)
3748                 return False;
3749         
3750         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3751
3752         q_u->level = level;
3753         q_u->info.level = level;
3754         q_u->info.info_ptr = (info != NULL) ? 1 : 0;
3755         switch (level) {
3756
3757           /* There's no such thing as a setprinter level 1 */
3758
3759         case 2:
3760                 secdesc = info->printers_2->secdesc;
3761                 devmode = info->printers_2->devmode;
3762                 
3763                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
3764 #if 1   /* JERRY TEST */
3765                 q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF));
3766                 if (!q_u->secdesc_ctr)
3767                         return False;
3768                 q_u->secdesc_ctr->ptr = (secdesc != NULL) ? 1: 0;
3769                 q_u->secdesc_ctr->max_len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3770                 q_u->secdesc_ctr->len = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
3771                 q_u->secdesc_ctr->sec = secdesc;
3772
3773                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
3774                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
3775                 q_u->devmode_ctr.devmode = devmode;
3776 #else
3777                 q_u->secdesc_ctr = NULL;
3778         
3779                 q_u->devmode_ctr.devmode_ptr = 0;
3780                 q_u->devmode_ctr.size = 0;
3781                 q_u->devmode_ctr.devmode = NULL;
3782 #endif
3783                 break;
3784         default: 
3785                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
3786                         break;
3787         }
3788
3789         
3790         q_u->command = command;
3791
3792         return True;
3793 }
3794
3795
3796 /*******************************************************************
3797 ********************************************************************/  
3798
3799 BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
3800 {               
3801         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
3802         depth++;
3803
3804         if(!prs_align(ps))
3805                 return False;
3806         
3807         if(!prs_werror("status", ps, depth, &r_u->status))
3808                 return False;
3809
3810         return True;
3811 }
3812
3813 /*******************************************************************
3814  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
3815 ********************************************************************/  
3816
3817 BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
3818 {
3819         uint32 ptr_sec_desc = 0;
3820
3821         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
3822         depth++;
3823
3824         if(!prs_align(ps))
3825                 return False;
3826
3827         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
3828                 return False;
3829         if(!prs_uint32("level", ps, depth, &q_u->level))
3830                 return False;
3831
3832         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3833                 return False;
3834
3835         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3836                 return False;
3837         
3838         if(!prs_align(ps))
3839                 return False;
3840
3841         switch (q_u->level)
3842         {
3843                 case 2:
3844                 {
3845                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3846                         break;
3847                 }
3848                 case 3:
3849                 {
3850                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3851                         break;
3852                 }
3853         }
3854         if (ptr_sec_desc)
3855         {
3856                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3857                         return False;
3858         } else {
3859                 uint32 dummy = 0;
3860
3861                 /* Parse a NULL security descriptor.  This should really
3862                    happen inside the sec_io_desc_buf() function. */
3863
3864                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3865                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3866                         return False;
3867                 if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return
3868                                                                        False;
3869         }
3870         
3871         if(!prs_uint32("command", ps, depth, &q_u->command))
3872                 return False;
3873
3874         return True;
3875 }
3876
3877 /*******************************************************************
3878 ********************************************************************/  
3879
3880 BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth)
3881 {               
3882         prs_debug(ps, depth, desc, "spoolss_io_r_fcpn");
3883         depth++;
3884
3885         if(!prs_align(ps))
3886                 return False;
3887         
3888         if(!prs_werror("status", ps, depth, &r_u->status))
3889                 return False;
3890
3891         return True;
3892 }
3893
3894 /*******************************************************************
3895 ********************************************************************/  
3896
3897 BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth)
3898 {
3899
3900         prs_debug(ps, depth, desc, "spoolss_io_q_fcpn");
3901         depth++;
3902
3903         if(!prs_align(ps))
3904                 return False;
3905
3906         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3907                 return False;
3908
3909         return True;
3910 }
3911
3912
3913 /*******************************************************************
3914 ********************************************************************/  
3915
3916 BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth)
3917 {               
3918         prs_debug(ps, depth, desc, "");
3919         depth++;
3920
3921         if(!prs_align(ps))
3922                 return False;
3923         
3924         if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3925                 return False;
3926
3927         if(!prs_align(ps))
3928                 return False;
3929         
3930         if(!prs_uint32("needed", ps, depth, &r_u->needed))
3931                 return False;
3932
3933         if(!prs_werror("status", ps, depth, &r_u->status))
3934                 return False;
3935
3936         return True;
3937 }
3938
3939 /*******************************************************************
3940 ********************************************************************/  
3941
3942 BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
3943 {
3944         prs_debug(ps, depth, desc, "");
3945         depth++;
3946
3947         if(!prs_align(ps))
3948                 return False;
3949
3950         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3951                 return False;
3952         if(!prs_uint32("level", ps, depth, &q_u->level))
3953                 return False;
3954         
3955         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
3956                 return False;
3957
3958         if(!prs_align(ps))
3959                 return False;
3960         
3961         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3962                 return False;
3963
3964         return True;
3965 }
3966
3967 /*******************************************************************
3968 ********************************************************************/  
3969
3970 BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
3971 {               
3972         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
3973         depth++;
3974
3975         if (!prs_align(ps))
3976                 return False;
3977                 
3978         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
3979                 return False;
3980
3981         if (!prs_align(ps))
3982                 return False;
3983                 
3984         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3985                 return False;
3986                 
3987         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3988                 return False;
3989                 
3990         if (!prs_werror("status", ps, depth, &r_u->status))
3991                 return False;
3992
3993         return True;            
3994 }
3995
3996 /*******************************************************************
3997 ********************************************************************/  
3998
3999 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
4000                                 uint32 firstjob,
4001                                 uint32 numofjobs,
4002                                 uint32 level,
4003                                 NEW_BUFFER *buffer,
4004                                 uint32 offered)
4005 {
4006         if (q_u == NULL)
4007         {
4008                 return False;
4009         }
4010         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
4011         q_u->firstjob = firstjob;
4012         q_u->numofjobs = numofjobs;
4013         q_u->level = level;
4014         q_u->buffer= buffer;
4015         q_u->offered = offered;
4016         return True;
4017 }
4018
4019 /*******************************************************************
4020 ********************************************************************/  
4021
4022 BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
4023 {
4024         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
4025         depth++;
4026
4027         if (!prs_align(ps))
4028                 return False;
4029
4030         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
4031                 return False;
4032                 
4033         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
4034                 return False;
4035         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
4036                 return False;
4037         if (!prs_uint32("level", ps, depth, &q_u->level))
4038                 return False;
4039
4040         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4041                 return False;   
4042
4043         if(!prs_align(ps))
4044                 return False;
4045
4046         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4047                 return False;
4048
4049         return True;
4050 }
4051
4052 /*******************************************************************
4053 ********************************************************************/  
4054
4055 BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
4056 {               
4057         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
4058         depth++;
4059
4060         if(!prs_align(ps))
4061                 return False;
4062         
4063         if(!prs_werror("status", ps, depth, &r_u->status))
4064                 return False;
4065
4066         return True;
4067 }
4068
4069 /*******************************************************************
4070 ********************************************************************/  
4071
4072 BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
4073 {
4074         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
4075         depth++;
4076
4077         if(!prs_align(ps))
4078                 return False;
4079
4080         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4081                 return False;
4082         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4083                 return False;
4084
4085         return True;
4086 }
4087
4088 /*******************************************************************
4089 ********************************************************************/  
4090
4091 BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
4092 {               
4093         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
4094         depth++;
4095
4096         if(!prs_align(ps))
4097                 return False;
4098         
4099         if(!prs_werror("status", ps, depth, &r_u->status))
4100                 return False;
4101
4102         return True;
4103 }
4104
4105 /*******************************************************************
4106 ********************************************************************/  
4107
4108 BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
4109 {
4110         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
4111         depth++;
4112
4113         if(!prs_align(ps))
4114                 return False;
4115
4116         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4117                 return False;
4118         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
4119                 return False;
4120         /* 
4121          * level is usually 0. If (level!=0) then I'm in trouble !
4122          * I will try to generate setjob command with level!=0, one day.
4123          */
4124         if(!prs_uint32("level", ps, depth, &q_u->level))
4125                 return False;
4126         if(!prs_uint32("command", ps, depth, &q_u->command))
4127                 return False;
4128
4129         return True;
4130 }
4131
4132 /*******************************************************************
4133  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
4134 ********************************************************************/  
4135
4136 BOOL spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
4137 {
4138         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
4139         depth++;
4140
4141         if (!prs_align(ps))
4142                 return False;
4143                 
4144         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4145                 return False;
4146
4147         if (!prs_align(ps))
4148                 return False;
4149                 
4150         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4151                 return False;
4152                 
4153         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4154                 return False;
4155                 
4156         if (!prs_werror("status", ps, depth, &r_u->status))
4157                 return False;
4158
4159         return True;            
4160 }
4161
4162 /*******************************************************************
4163  * init a structure.
4164  ********************************************************************/
4165
4166 BOOL make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
4167                                 const char *name,
4168                                 const char *environment,
4169                                 uint32 level,
4170                                 NEW_BUFFER *buffer, uint32 offered)
4171 {
4172         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
4173         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
4174
4175         q_u->level=level;
4176         q_u->buffer=buffer;
4177         q_u->offered=offered;
4178
4179         return True;
4180 }
4181
4182 /*******************************************************************
4183  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
4184 ********************************************************************/  
4185
4186 BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
4187 {
4188
4189         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
4190         depth++;
4191
4192         if (!prs_align(ps))
4193                 return False;
4194                 
4195         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
4196                 return False;
4197         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
4198                 return False;
4199                 
4200         if (!prs_align(ps))
4201                 return False;
4202         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
4203                 return False;
4204         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
4205                 return False;
4206                 
4207         if (!prs_align(ps))
4208                 return False;
4209         if (!prs_uint32("level", ps, depth, &q_u->level))
4210                 return False;
4211                 
4212         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4213                 return False;
4214
4215         if (!prs_align(ps))
4216                 return False;
4217                 
4218         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4219                 return False;
4220
4221         return True;
4222 }
4223
4224 /*******************************************************************
4225 ********************************************************************/  
4226
4227 BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
4228 {
4229
4230         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
4231         depth++;
4232
4233         if (!prs_align(ps))
4234                 return False;                   
4235         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4236                 return False;           
4237         if (!prs_uint32("level", ps, depth, &q_u->level))
4238                 return False;   
4239         
4240         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4241                 return False;
4242
4243         if (!prs_align(ps))
4244                 return False;
4245         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4246                 return False;
4247
4248         return True;
4249 }
4250
4251 /*******************************************************************
4252 ********************************************************************/  
4253
4254 BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
4255 {
4256         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
4257         depth++;
4258
4259         if (!prs_align(ps))
4260                 return False;
4261                 
4262         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4263                 return False;
4264
4265         if (!prs_align(ps))
4266                 return False;
4267                 
4268         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4269                 return False;
4270                 
4271         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
4272                 return False;
4273                 
4274         if (!prs_werror("status", ps, depth, &r_u->status))
4275                 return False;
4276
4277         return True;
4278 }
4279
4280 /*******************************************************************
4281 ********************************************************************/  
4282
4283 BOOL spoolss_io_q_getform(char *desc, SPOOL_Q_GETFORM *q_u, prs_struct *ps, int depth)
4284 {
4285
4286         prs_debug(ps, depth, desc, "spoolss_io_q_getform");
4287         depth++;
4288
4289         if (!prs_align(ps))
4290                 return False;                   
4291         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
4292                 return False;           
4293         if (!smb_io_unistr2("", &q_u->formname,True,ps,depth))
4294                 return False;
4295
4296         if (!prs_align(ps))
4297                 return False;
4298
4299         if (!prs_uint32("level", ps, depth, &q_u->level))
4300                 return False;   
4301         
4302         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4303                 return False;
4304
4305         if (!prs_align(ps))
4306                 return False;
4307         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4308                 return False;
4309
4310         return True;
4311 }
4312
4313 /*******************************************************************
4314 ********************************************************************/  
4315
4316 BOOL spoolss_io_r_getform(char *desc, SPOOL_R_GETFORM *r_u, prs_struct *ps, int depth)
4317 {
4318         prs_debug(ps, depth, desc, "spoolss_io_r_getform");
4319         depth++;
4320
4321         if (!prs_align(ps))
4322                 return False;
4323                 
4324         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4325                 return False;
4326
4327         if (!prs_align(ps))
4328                 return False;
4329                 
4330         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
4331                 return False;
4332                 
4333         if (!prs_werror("status", ps, depth, &r_u->status))
4334                 return False;
4335
4336         return True;
4337 }
4338
4339 /*******************************************************************
4340  Parse a SPOOL_R_ENUMPORTS structure.
4341 ********************************************************************/  
4342
4343 BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
4344 {
4345         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
4346         depth++;
4347
4348         if (!prs_align(ps))
4349                 return False;
4350                 
4351         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
4352                 return False;
4353
4354         if (!prs_align(ps))
4355                 return False;
4356                 
4357         if (!prs_uint32("needed", ps, depth, &r_u->needed))
4358                 return False;
4359                 
4360         if (!prs_uint32("returned", ps, depth, &r_u->returned))
4361                 return False;
4362                 
4363         if (!prs_werror("status", ps, depth, &r_u->status))
4364                 return False;
4365
4366         return True;            
4367 }
4368
4369 /*******************************************************************
4370 ********************************************************************/  
4371
4372 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
4373 {
4374         prs_debug(ps, depth, desc, "");
4375         depth++;
4376
4377         if (!prs_align(ps))
4378                 return False;
4379
4380         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
4381                 return False;
4382         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
4383                 return False;
4384
4385         if (!prs_align(ps))
4386                 return False;
4387         if (!prs_uint32("level", ps, depth, &q_u->level))
4388                 return False;
4389                 
4390         if (!spoolss_io_buffer("", ps, depth, &q_u->buffer))
4391                 return False;
4392
4393         if (!prs_align(ps))
4394                 return False;
4395         if (!prs_uint32("offered", ps, depth, &q_u->offered))
4396                 return False;
4397
4398         return True;
4399 }
4400
4401 /*******************************************************************
4402  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
4403 ********************************************************************/  
4404
4405 BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
4406 {       
4407         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
4408         depth++;
4409                 
4410         if(!prs_align(ps))
4411                 return False;
4412
4413         if(!prs_uint32("flags", ps, depth, &il->flags))
4414                 return False;
4415         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
4416                 return False;
4417         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4418                 return False;
4419         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4420                 return False;
4421                 
4422         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
4423                 return False;
4424         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4425                 return False;
4426         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4427                 return False;
4428
4429         return True;
4430 }
4431
4432 /*******************************************************************
4433  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
4434 ********************************************************************/  
4435
4436 BOOL spool_io_printer_info_level_3(char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
4437 {       
4438         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
4439         depth++;
4440                 
4441         if(!prs_align(ps))
4442                 return False;
4443
4444         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4445                 return False;
4446
4447         return True;
4448 }
4449
4450 /*******************************************************************
4451  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
4452 ********************************************************************/  
4453
4454 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
4455 {       
4456         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
4457         depth++;
4458                 
4459         if(!prs_align(ps))
4460                 return False;
4461
4462         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
4463                 return False;
4464         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
4465                 return False;
4466         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
4467                 return False;
4468         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
4469                 return False;
4470
4471         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
4472                 return False;
4473         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
4474                 return False;
4475         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
4476                 return False;
4477         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
4478                 return False;
4479         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
4480                 return False;
4481         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
4482                 return False;
4483         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
4484                 return False;
4485         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
4486                 return False;
4487         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
4488                 return False;
4489
4490         if(!prs_uint32("attributes", ps, depth, &il->attributes))
4491                 return False;
4492         if(!prs_uint32("priority", ps, depth, &il->priority))
4493                 return False;
4494         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
4495                 return False;
4496         if(!prs_uint32("starttime", ps, depth, &il->starttime))
4497                 return False;
4498         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
4499                 return False;
4500         if(!prs_uint32("status", ps, depth, &il->status))
4501                 return False;
4502         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
4503                 return False;
4504         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
4505                 return False;
4506
4507         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
4508                 return False;
4509         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
4510                 return False;
4511         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
4512                 return False;
4513         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
4514                 return False;
4515         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
4516                 return False;
4517         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
4518                 return False;
4519         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
4520                 return False;
4521         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
4522                 return False;
4523         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
4524                 return False;
4525         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
4526                 return False;
4527         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
4528                 return False;
4529
4530         return True;
4531 }
4532
4533 /*******************************************************************
4534 ********************************************************************/  
4535
4536 BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
4537 {
4538         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
4539         depth++;
4540
4541         if(!prs_align(ps))
4542                 return False;
4543         if(!prs_uint32("level", ps, depth, &il->level))
4544                 return False;
4545         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
4546                 return False;
4547         
4548         /* if no struct inside just return */
4549         if (il->info_ptr==0) {
4550                 if (UNMARSHALLING(ps)) {
4551                         il->info_1=NULL;
4552                         il->info_2=NULL;
4553                 }
4554                 return True;
4555         }
4556                         
4557         switch (il->level) {
4558                 /*
4559                  * level 0 is used by setprinter when managing the queue
4560                  * (hold, stop, start a queue)
4561                  */
4562                 case 0:
4563                         break;
4564                 /* DOCUMENT ME!!! What is level 1 used for? */
4565                 case 1:
4566                 {
4567                         if (UNMARSHALLING(ps)) {
4568                                 if ((il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_1))) == NULL)
4569                                         return False;
4570                         }
4571                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
4572                                 return False;
4573                         break;          
4574                 }
4575                 /* 
4576                  * level 2 is used by addprinter
4577                  * and by setprinter when updating printer's info
4578                  */     
4579                 case 2:
4580                         if (UNMARSHALLING(ps)) {
4581                                 if ((il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_2))) == NULL)
4582                                         return False;
4583                         }
4584                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
4585                                 return False;
4586                         break;          
4587                 /* DOCUMENT ME!!! What is level 3 used for? */
4588                 case 3:
4589                 {
4590                         if (UNMARSHALLING(ps)) {
4591                                 if ((il->info_3=(SPOOL_PRINTER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_INFO_LEVEL_3))) == NULL)
4592                                         return False;
4593                         }
4594                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
4595                                 return False;
4596                         break;          
4597                 }
4598         }
4599
4600         return True;
4601 }
4602
4603 /*******************************************************************
4604 ********************************************************************/  
4605
4606 BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
4607 {
4608         uint32 ptr_sec_desc = 0;
4609
4610         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
4611         depth++;
4612
4613         if(!prs_align(ps))
4614                 return False;
4615         if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
4616                 return False;
4617         if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
4618                 return False;
4619
4620         if(!prs_align(ps))
4621                 return False;
4622
4623         if(!prs_uint32("info_level", ps, depth, &q_u->level))
4624                 return False;
4625         
4626         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
4627                 return False;
4628         
4629         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
4630                 return False;
4631
4632         if(!prs_align(ps))
4633                 return False;
4634
4635         switch (q_u->level) {
4636                 case 2:
4637                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
4638                         break;
4639                 case 3:
4640                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
4641                         break;
4642         }
4643         if (ptr_sec_desc) {
4644                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
4645                         return False;
4646         } else {
4647                 uint32 dummy;
4648
4649                 /* Parse a NULL security descriptor.  This should really
4650                         happen inside the sec_io_desc_buf() function. */
4651
4652                 prs_debug(ps, depth, "", "sec_io_desc_buf");
4653                 if (!prs_uint32("size", ps, depth + 1, &dummy))
4654                         return False;
4655                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
4656                         return False;
4657         }
4658
4659         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
4660                 return False;
4661         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
4662                 return False;
4663
4664         return True;
4665 }
4666
4667 /*******************************************************************
4668 ********************************************************************/  
4669
4670 BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
4671                                prs_struct *ps, int depth)
4672 {
4673         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
4674         depth++;
4675         
4676         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
4677                 return False;
4678
4679         if(!prs_werror("status", ps, depth, &r_u->status))
4680                 return False;
4681
4682         return True;
4683 }
4684
4685 /*******************************************************************
4686 ********************************************************************/  
4687
4688 BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
4689                                           prs_struct *ps, int depth)
4690 {       
4691         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
4692         
4693         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
4694         depth++;
4695                 
4696         /* reading */
4697         if (UNMARSHALLING(ps)) {
4698                 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
4699                 if(il == NULL)
4700                         return False;
4701                 *q_u=il;
4702         }
4703         else {
4704                 il=*q_u;
4705         }
4706         
4707         if(!prs_align(ps))
4708                 return False;
4709
4710         if(!prs_uint32("cversion", ps, depth, &il->cversion))
4711                 return False;
4712         if(!prs_uint32("name", ps, depth, &il->name_ptr))
4713                 return False;
4714         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
4715                 return False;
4716         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
4717                 return False;
4718         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
4719                 return False;
4720         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
4721                 return False;
4722         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
4723                 return False;
4724         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
4725                 return False;
4726         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
4727                 return False;
4728         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
4729                 return False;
4730         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
4731                 return False;
4732
4733         if(!prs_align(ps))
4734                 return False;
4735         
4736         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4737                 return False;
4738         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4739                 return False;
4740         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4741                 return False;
4742         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4743                 return False;
4744         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4745                 return False;
4746         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4747                 return False;
4748         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4749                 return False;
4750         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4751                 return False;
4752
4753         if(!prs_align(ps))
4754                 return False;
4755                 
4756         if (il->dependentfiles_ptr)
4757                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
4758
4759         return True;
4760 }
4761
4762 /*******************************************************************
4763 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
4764 ********************************************************************/  
4765
4766 BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
4767                                           prs_struct *ps, int depth)
4768 {       
4769         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
4770         
4771         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
4772         depth++;
4773                 
4774         /* reading */
4775         if (UNMARSHALLING(ps)) {
4776                 il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *)prs_alloc_mem(ps,sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6));
4777                 if(il == NULL)
4778                         return False;
4779                 *q_u=il;
4780         }
4781         else {
4782                 il=*q_u;
4783         }
4784         
4785         if(!prs_align(ps))
4786                 return False;
4787
4788
4789         /* parse the main elements the packet */
4790
4791         if(!prs_uint32("version", ps, depth, &il->version))
4792                 return False;
4793
4794         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4795                 return False;   
4796         /*
4797          * If name_ptr is NULL then the next 4 bytes are the name_ptr. A driver 
4798          * with a NULL name just isn't a driver For example: "HP LaserJet 4si"
4799          * from W2K CDROM (which uses unidriver). JohnR 010205
4800          */
4801         if (!il->name_ptr) {
4802                 DEBUG(5,("spool_io_printer_driver_info_level_6: name_ptr is NULL! Get next value\n"));
4803                 if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
4804                         return False;   
4805         }
4806         
4807         if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr))
4808                 return False;
4809         if(!prs_uint32("driverpath_ptr", ps, depth, &il->driverpath_ptr))
4810                 return False;
4811         if(!prs_uint32("datafile_ptr", ps, depth, &il->datafile_ptr))
4812                 return False;
4813         if(!prs_uint32("configfile_ptr", ps, depth, &il->configfile_ptr))
4814                 return False;
4815         if(!prs_uint32("helpfile_ptr", ps, depth, &il->helpfile_ptr))
4816                 return False;
4817         if(!prs_uint32("monitorname_ptr", ps, depth, &il->monitorname_ptr))
4818                 return False;
4819         if(!prs_uint32("defaultdatatype_ptr", ps, depth, &il->defaultdatatype_ptr))
4820                 return False;
4821         if(!prs_uint32("dependentfiles_len", ps, depth, &il->dependentfiles_len))
4822                 return False;
4823         if(!prs_uint32("dependentfiles_ptr", ps, depth, &il->dependentfiles_ptr))
4824                 return False;
4825         if(!prs_uint32("previousnames_len", ps, depth, &il->previousnames_len))
4826                 return False;
4827         if(!prs_uint32("previousnames_ptr", ps, depth, &il->previousnames_ptr))
4828                 return False;
4829         if(!smb_io_time("driverdate", &il->driverdate, ps, depth))
4830                 return False;
4831         if(!prs_uint32("dummy4", ps, depth, &il->dummy4))
4832                 return False;
4833         if(!prs_uint64("driverversion", ps, depth, &il->driverversion))
4834                 return False;
4835         if(!prs_uint32("mfgname_ptr", ps, depth, &il->mfgname_ptr))
4836                 return False;
4837         if(!prs_uint32("oemurl_ptr", ps, depth, &il->oemurl_ptr))
4838                 return False;
4839         if(!prs_uint32("hardwareid_ptr", ps, depth, &il->hardwareid_ptr))
4840                 return False;
4841         if(!prs_uint32("provider_ptr", ps, depth, &il->provider_ptr))
4842                 return False;
4843
4844         /* parse the structures in the packet */
4845
4846         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
4847                 return False;
4848         if(!prs_align(ps))
4849                 return False;
4850
4851         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
4852                 return False;
4853         if(!prs_align(ps))
4854                 return False;
4855
4856         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
4857                 return False;
4858         if(!prs_align(ps))
4859                 return False;
4860
4861         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
4862                 return False;
4863         if(!prs_align(ps))
4864                 return False;
4865
4866         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
4867                 return False;
4868         if(!prs_align(ps))
4869                 return False;
4870
4871         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
4872                 return False;
4873         if(!prs_align(ps))
4874                 return False;
4875
4876         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
4877                 return False;
4878         if(!prs_align(ps))
4879                 return False;
4880
4881         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
4882                 return False;
4883         if(!prs_align(ps))
4884                 return False;
4885         if (il->dependentfiles_ptr) {
4886                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
4887                         return False;
4888                 if(!prs_align(ps))
4889                         return False;
4890         }
4891         if (il->previousnames_ptr) {
4892                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
4893                         return False;
4894                 if(!prs_align(ps))
4895                         return False;
4896         }
4897         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
4898                 return False;
4899         if(!prs_align(ps))
4900                 return False;
4901         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
4902                 return False;
4903         if(!prs_align(ps))
4904                 return False;
4905         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
4906                 return False;
4907         if(!prs_align(ps))
4908                 return False;
4909         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
4910                 return False;
4911
4912         return True;
4913 }
4914
4915 /*******************************************************************
4916  convert a buffer of UNICODE strings null terminated
4917  the buffer is terminated by a NULL
4918  
4919  convert to an dos codepage array (null terminated)
4920  
4921  dynamically allocate memory
4922  
4923 ********************************************************************/  
4924 static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
4925 {
4926         fstring f, *tar;
4927         int n = 0;
4928         char *src;
4929
4930         if (buf5==NULL)
4931                 return False;
4932
4933         src = (char *)buf5->buffer;
4934         *ar = NULL;
4935
4936         while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
4937                 rpcstr_pull(f, src, sizeof(f)-1, -1, 0);
4938                 src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
4939                 tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
4940                 if (!tar)
4941                         return False;
4942                 else
4943                         *ar = tar;
4944                 fstrcpy((*ar)[n], f);
4945                 n++;
4946         }
4947         fstrcpy((*ar)[n], "");
4948  
4949         return True;
4950 }
4951
4952
4953
4954
4955 /*******************************************************************
4956  read a UNICODE array with null terminated strings 
4957  and null terminated array 
4958  and size of array at beginning
4959 ********************************************************************/  
4960
4961 BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
4962 {
4963         if (buffer==NULL) return False;
4964
4965         buffer->undoc=0;
4966         buffer->uni_str_len=buffer->uni_max_len;
4967         
4968         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
4969                 return False;
4970
4971         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
4972                 return False;
4973
4974         return True;
4975 }
4976
4977 /*******************************************************************
4978 ********************************************************************/  
4979
4980 BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
4981 {
4982         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
4983         depth++;
4984
4985         if(!prs_align(ps))
4986                 return False;
4987         if(!prs_uint32("level", ps, depth, &il->level))
4988                 return False;
4989         if(!prs_uint32("ptr", ps, depth, &il->ptr))
4990                 return False;
4991
4992         if (il->ptr==0)
4993                 return True;
4994                 
4995         switch (il->level) {
4996                 case 3:
4997                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
4998                                 return False;
4999                         break;          
5000                 case 6:
5001                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
5002                                 return False;
5003                         break;          
5004         default:
5005                 return False;
5006         }
5007
5008         return True;
5009 }
5010
5011 /*******************************************************************
5012  init a SPOOL_Q_ADDPRINTERDRIVER struct
5013  ******************************************************************/
5014
5015 BOOL make_spoolss_q_addprinterdriver(TALLOC_CTX *mem_ctx,
5016                                 SPOOL_Q_ADDPRINTERDRIVER *q_u, const char* srv_name, 
5017                                 uint32 level, PRINTER_DRIVER_CTR *info)
5018 {
5019         DEBUG(5,("make_spoolss_q_addprinterdriver\n"));
5020         
5021         q_u->server_name_ptr = (srv_name!=NULL)?1:0;
5022         init_unistr2(&q_u->server_name, srv_name, strlen(srv_name)+1);
5023         
5024         q_u->level = level;
5025         
5026         q_u->info.level = level;
5027         q_u->info.ptr = (info!=NULL)?1:0;
5028         switch (level)
5029         {
5030         /* info level 3 is supported by Windows 95/98, WinNT and Win2k */
5031         case 3 :
5032                 make_spoolss_driver_info_3(mem_ctx, &q_u->info.info_3, info->info3);
5033                 break;
5034                 
5035         /* info level 6 is supported by WinME and Win2k */
5036         case 6:
5037                 /* WRITEME!!  will add later  --jerry */
5038                 break;
5039                 
5040         default:
5041                 DEBUG(0,("make_spoolss_q_addprinterdriver: Unknown info level [%d]\n", level));
5042                 break;
5043         }
5044         
5045         return True;
5046 }
5047
5048 BOOL make_spoolss_driver_info_3(TALLOC_CTX *mem_ctx, 
5049         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **spool_drv_info,
5050                                 DRIVER_INFO_3 *info3)
5051 {
5052         uint32          len = 0;
5053         uint16          *ptr = info3->dependentfiles;
5054         BOOL            done = False;
5055         BOOL            null_char = False;
5056         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *inf;
5057
5058         if (!(inf=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3*)talloc_zero(mem_ctx, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3))))
5059                 return False;
5060         
5061         inf->cversion   = info3->version;
5062         inf->name_ptr   = (info3->name.buffer!=NULL)?1:0;
5063         inf->environment_ptr    = (info3->architecture.buffer!=NULL)?1:0;
5064         inf->driverpath_ptr     = (info3->driverpath.buffer!=NULL)?1:0;
5065         inf->datafile_ptr       = (info3->datafile.buffer!=NULL)?1:0;
5066         inf->configfile_ptr     = (info3->configfile.buffer!=NULL)?1:0;
5067         inf->helpfile_ptr       = (info3->helpfile.buffer!=NULL)?1:0;
5068         inf->monitorname_ptr    = (info3->monitorname.buffer!=NULL)?1:0;
5069         inf->defaultdatatype_ptr        = (info3->defaultdatatype.buffer!=NULL)?1:0;
5070
5071         init_unistr2_from_unistr(&inf->name, &info3->name);
5072         init_unistr2_from_unistr(&inf->environment, &info3->architecture);
5073         init_unistr2_from_unistr(&inf->driverpath, &info3->driverpath);
5074         init_unistr2_from_unistr(&inf->datafile, &info3->datafile);
5075         init_unistr2_from_unistr(&inf->configfile, &info3->configfile);
5076         init_unistr2_from_unistr(&inf->helpfile, &info3->helpfile);
5077         init_unistr2_from_unistr(&inf->monitorname, &info3->monitorname);
5078         init_unistr2_from_unistr(&inf->defaultdatatype, &info3->defaultdatatype);
5079
5080         while (!done)
5081         {
5082                 switch (*ptr)
5083                 {
5084                         case 0:
5085                                 /* the null_char BOOL is used to help locate
5086                                    two '\0's back to back */
5087                                 if (null_char)
5088                                         done = True;
5089                                 else
5090                                         null_char = True;
5091                                 break;
5092                                         
5093                         default:
5094                                 null_char = False;
5095                                 ;;
5096                                 break;                          
5097                 }
5098                 len++;
5099                 ptr++;
5100         }
5101         inf->dependentfiles_ptr = (info3->dependentfiles != NULL) ? 1 : 0;
5102         inf->dependentfilessize = len;
5103         if(!make_spoolss_buffer5(mem_ctx, &inf->dependentfiles, len, info3->dependentfiles))
5104         {
5105                 SAFE_FREE(inf);
5106                 return False;
5107         }
5108         
5109         *spool_drv_info = inf;
5110         
5111         return True;
5112 }
5113
5114 /*******************************************************************
5115  make a BUFFER5 struct from a uint16*
5116  ******************************************************************/
5117 BOOL make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
5118 {
5119
5120         buf5->buf_len = len;
5121         if((buf5->buffer=(uint16*)talloc_memdup(mem_ctx, src, sizeof(uint16)*len)) == NULL)
5122         {
5123                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
5124                 return False;
5125         }
5126         
5127         return True;
5128 }
5129
5130 /*******************************************************************
5131  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
5132  ********************************************************************/  
5133
5134 BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5135 {
5136         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
5137         depth++;
5138
5139         if(!prs_align(ps))
5140                 return False;
5141
5142         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
5143                 return False;
5144         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
5145                 return False;
5146                 
5147         if(!prs_align(ps))
5148                 return False;
5149         if(!prs_uint32("info_level", ps, depth, &q_u->level))
5150                 return False;
5151
5152         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
5153                 return False;
5154
5155         return True;
5156 }
5157
5158 /*******************************************************************
5159 ********************************************************************/  
5160
5161 BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
5162 {
5163         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
5164         depth++;
5165
5166         if(!prs_werror("status", ps, depth, &q_u->status))
5167                 return False;
5168
5169         return True;
5170 }
5171
5172 /*******************************************************************
5173 ********************************************************************/  
5174
5175 BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
5176                                 NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc)
5177 {
5178         NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
5179         
5180         DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n"));
5181         
5182         if (*asc==NULL)
5183         {
5184                 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3));
5185                 if(*asc == NULL)
5186                         return False;
5187                 ZERO_STRUCTP(*asc);
5188         }       
5189
5190         d=*asc;
5191
5192         d->cversion=uni->cversion;
5193
5194         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5195         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5196         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5197         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5198         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5199         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5200         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5201         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5202
5203         DEBUGADD(8,( "version:         %d\n", d->cversion));
5204         DEBUGADD(8,( "name:            %s\n", d->name));
5205         DEBUGADD(8,( "environment:     %s\n", d->environment));
5206         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5207         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5208         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5209         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5210         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5211         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5212
5213         if (uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5214                 return True;
5215         
5216         SAFE_FREE(*asc);
5217         return False;
5218 }
5219
5220 /*******************************************************************
5221 ********************************************************************/  
5222 BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
5223                                 NT_PRINTER_DRIVER_INFO_LEVEL_6 **asc)
5224 {
5225         NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
5226         
5227         DEBUG(7,("uni_2_asc_printer_driver_6: Converting from UNICODE to ASCII\n"));
5228         
5229         if (*asc==NULL)
5230         {
5231                 *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_6 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_6));
5232                 if(*asc == NULL)
5233                         return False;
5234                 ZERO_STRUCTP(*asc);
5235         }       
5236
5237         d=*asc;
5238
5239         d->version=uni->version;
5240
5241         unistr2_to_ascii(d->name,            &uni->name,            sizeof(d->name)-1);
5242         unistr2_to_ascii(d->environment,     &uni->environment,     sizeof(d->environment)-1);
5243         unistr2_to_ascii(d->driverpath,      &uni->driverpath,      sizeof(d->driverpath)-1);
5244         unistr2_to_ascii(d->datafile,        &uni->datafile,        sizeof(d->datafile)-1);
5245         unistr2_to_ascii(d->configfile,      &uni->configfile,      sizeof(d->configfile)-1);
5246         unistr2_to_ascii(d->helpfile,        &uni->helpfile,        sizeof(d->helpfile)-1);
5247         unistr2_to_ascii(d->monitorname,     &uni->monitorname,     sizeof(d->monitorname)-1);
5248         unistr2_to_ascii(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
5249
5250         DEBUGADD(8,( "version:         %d\n", d->version));
5251         DEBUGADD(8,( "name:            %s\n", d->name));
5252         DEBUGADD(8,( "environment:     %s\n", d->environment));
5253         DEBUGADD(8,( "driverpath:      %s\n", d->driverpath));
5254         DEBUGADD(8,( "datafile:        %s\n", d->datafile));
5255         DEBUGADD(8,( "configfile:      %s\n", d->configfile));
5256         DEBUGADD(8,( "helpfile:        %s\n", d->helpfile));
5257         DEBUGADD(8,( "monitorname:     %s\n", d->monitorname));
5258         DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
5259
5260         if (!uniarray_2_dosarray(&uni->dependentfiles, &d->dependentfiles ))
5261                 goto error;
5262         if (!uniarray_2_dosarray(&uni->previousnames, &d->previousnames ))
5263                 goto error;
5264         
5265         return True;
5266         
5267 error:
5268         SAFE_FREE(*asc);
5269         return False;
5270 }
5271
5272 BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
5273                               NT_PRINTER_INFO_LEVEL_2  **asc)
5274 {
5275         NT_PRINTER_INFO_LEVEL_2 *d;
5276         time_t time_unix;
5277         
5278         DEBUG(7,("Converting from UNICODE to ASCII\n"));
5279         time_unix=time(NULL);
5280         
5281         if (*asc==NULL) {
5282                 DEBUGADD(8,("allocating memory\n"));
5283
5284                 *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2));
5285                 if(*asc == NULL)
5286                         return False;
5287                 ZERO_STRUCTP(*asc);
5288                 
5289                 /* we allocate memory iff called from 
5290                  * addprinter(ex) so we can do one time stuff here.
5291                  */
5292                 (*asc)->setuptime=time_unix;
5293
5294         }       
5295         DEBUGADD(8,("start converting\n"));
5296
5297         d=*asc;
5298                 
5299         d->attributes=uni->attributes;
5300         d->priority=uni->priority;
5301         d->default_priority=uni->default_priority;
5302         d->starttime=uni->starttime;
5303         d->untiltime=uni->untiltime;
5304         d->status=uni->status;
5305         d->cjobs=uni->cjobs;
5306         
5307         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
5308         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
5309         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
5310         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
5311         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
5312         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
5313         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
5314         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
5315         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
5316         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
5317         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
5318
5319         return True;
5320 }
5321
5322 /*******************************************************************
5323  * init a structure.
5324  ********************************************************************/
5325
5326 BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
5327                                 fstring servername, fstring env_name, uint32 level,
5328                                 NEW_BUFFER *buffer, uint32 offered)
5329 {
5330         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
5331         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
5332
5333         q_u->level=level;
5334         q_u->buffer=buffer;
5335         q_u->offered=offered;
5336
5337         return True;
5338 }
5339
5340 /*******************************************************************
5341  Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
5342 ********************************************************************/  
5343
5344 BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
5345 {
5346         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
5347         depth++;
5348
5349         if(!prs_align(ps))
5350                 return False;
5351         if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5352                 return False;
5353         if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
5354                 return False;
5355
5356         if(!prs_align(ps))
5357                 return False;
5358                 
5359         if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
5360                 return False;
5361         if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5362                 return False;
5363                 
5364         if(!prs_align(ps))
5365                 return False;
5366
5367         if(!prs_uint32("level", ps, depth, &q_u->level))
5368                 return False;
5369                 
5370         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5371                 return False;
5372                 
5373         if(!prs_align(ps))
5374                 return False;
5375                 
5376         if(!prs_uint32("offered", ps, depth, &q_u->offered))
5377                 return False;
5378
5379         return True;
5380 }
5381
5382 /*******************************************************************
5383  Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
5384 ********************************************************************/  
5385
5386 BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
5387 {               
5388         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
5389         depth++;
5390
5391         if (!prs_align(ps))
5392                 return False;
5393                 
5394         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5395                 return False;
5396
5397         if (!prs_align(ps))
5398                 return False;
5399                 
5400         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5401                 return False;
5402                 
5403         if (!prs_werror("status", ps, depth, &r_u->status))
5404                 return False;
5405
5406         return True;            
5407 }
5408
5409 /*******************************************************************
5410 ********************************************************************/  
5411
5412 BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
5413 {               
5414         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
5415         depth++;
5416
5417         if (!prs_align(ps))
5418                 return False;
5419                 
5420         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5421                 return False;
5422
5423         if (!prs_align(ps))
5424                 return False;
5425                 
5426         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5427                 return False;
5428                 
5429         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5430                 return False;
5431                 
5432         if (!prs_werror("status", ps, depth, &r_u->status))
5433                 return False;
5434
5435         return True;            
5436 }
5437
5438 /*******************************************************************
5439 ********************************************************************/  
5440
5441 BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
5442 {
5443         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
5444         depth++;
5445
5446         if (!prs_align(ps))
5447                 return False;
5448                 
5449         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5450                 return False;
5451         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5452                 return False;
5453                 
5454         if (!prs_align(ps))
5455                 return False;
5456                 
5457         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
5458                 return False;
5459         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
5460                 return False;
5461         
5462         if (!prs_align(ps))
5463                 return False;
5464                 
5465         if (!prs_uint32("level", ps, depth, &q_u->level))
5466                 return False;
5467                 
5468         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5469                 return False;
5470
5471         if (!prs_align(ps))
5472                 return False;
5473
5474         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5475                 return False;
5476
5477         return True;
5478 }
5479
5480 /*******************************************************************
5481 ********************************************************************/  
5482
5483 BOOL spoolss_io_q_addprintprocessor(char *desc, SPOOL_Q_ADDPRINTPROCESSOR *q_u, prs_struct *ps, int depth)
5484 {
5485         prs_debug(ps, depth, desc, "spoolss_io_q_addprintprocessor");
5486         depth++;
5487
5488         if (!prs_align(ps))
5489                 return False;
5490                 
5491         if (!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
5492                 return False;
5493         if (!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
5494                 return False;
5495                 
5496         if (!prs_align(ps))
5497                 return False;
5498         if (!smb_io_unistr2("environment", &q_u->environment, True, ps, depth))
5499                 return False;
5500                 
5501         if (!prs_align(ps))
5502                 return False;
5503         if (!smb_io_unistr2("path", &q_u->path, True, ps, depth))
5504                 return False;
5505
5506         if (!prs_align(ps))
5507                 return False;
5508         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5509                 return False;
5510
5511         return True;
5512 }
5513
5514 /*******************************************************************
5515 ********************************************************************/  
5516
5517 BOOL spoolss_io_r_addprintprocessor(char *desc, SPOOL_R_ADDPRINTPROCESSOR *r_u, prs_struct *ps, int depth)
5518 {               
5519         prs_debug(ps, depth, desc, "spoolss_io_r_addprintproicessor");
5520         depth++;
5521
5522         if (!prs_align(ps))
5523                 return False;
5524                 
5525         if (!prs_werror("status", ps, depth, &r_u->status))
5526                 return False;
5527
5528         return True;            
5529 }
5530
5531 /*******************************************************************
5532 ********************************************************************/  
5533
5534 BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
5535 {               
5536         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
5537         depth++;
5538
5539         if (!prs_align(ps))
5540                 return False;
5541                 
5542         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5543                 return False;
5544
5545         if (!prs_align(ps))
5546                 return False;
5547                 
5548         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5549                 return False;
5550                 
5551         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5552                 return False;
5553                 
5554         if (!prs_werror("status", ps, depth, &r_u->status))
5555                 return False;
5556
5557         return True;            
5558 }
5559
5560 /*******************************************************************
5561 ********************************************************************/  
5562
5563 BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
5564 {
5565         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
5566         depth++;
5567
5568         if (!prs_align(ps))
5569                 return False;
5570                 
5571         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5572                 return False;
5573         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5574                 return False;
5575                 
5576         if (!prs_align(ps))
5577                 return False;
5578                 
5579         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
5580                 return False;
5581         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
5582                 return False;
5583         
5584         if (!prs_align(ps))
5585                 return False;
5586                 
5587         if (!prs_uint32("level", ps, depth, &q_u->level))
5588                 return False;
5589                 
5590         if(!spoolss_io_buffer("buffer", ps, depth, &q_u->buffer))
5591                 return False;
5592
5593         if (!prs_align(ps))
5594                 return False;
5595
5596         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5597                 return False;
5598
5599         return True;
5600 }
5601
5602 /*******************************************************************
5603  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
5604 ********************************************************************/  
5605
5606 BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
5607 {
5608         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
5609         depth++;
5610
5611         if (!prs_align(ps))
5612                 return False;
5613                 
5614         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
5615                 return False;
5616         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
5617                 return False;
5618                 
5619         if (!prs_align(ps))
5620                 return False;
5621                                 
5622         if (!prs_uint32("level", ps, depth, &q_u->level))
5623                 return False;
5624                 
5625         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
5626                 return False;
5627
5628         if (!prs_align(ps))
5629                 return False;
5630
5631         if (!prs_uint32("offered", ps, depth, &q_u->offered))
5632                 return False;
5633
5634         return True;
5635 }
5636
5637 /*******************************************************************
5638 ********************************************************************/  
5639
5640 BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
5641 {               
5642         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
5643         depth++;
5644
5645         if (!prs_align(ps))
5646                 return False;
5647                 
5648         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
5649                 return False;
5650
5651         if (!prs_align(ps))
5652                 return False;
5653                 
5654         if (!prs_uint32("needed", ps, depth, &r_u->needed))
5655                 return False;
5656                 
5657         if (!prs_uint32("returned", ps, depth, &r_u->returned))
5658                 return False;
5659                 
5660         if (!prs_werror("status", ps, depth, &r_u->status))
5661                 return False;
5662
5663         return True;            
5664 }
5665
5666 /*******************************************************************
5667 ********************************************************************/  
5668
5669 BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
5670 {       
5671         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
5672         depth++;
5673
5674         if(!prs_align(ps))
5675                 return False;
5676         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
5677                 return False;
5678
5679         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
5680                 return False;
5681
5682         if(!prs_align(ps))
5683                 return False;
5684
5685         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
5686                 return False;
5687
5688         if(!prs_uint32("type", ps, depth, &r_u->type))
5689                 return False;
5690
5691         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
5692                 return False;
5693         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
5694                 return False;
5695         if(!prs_align(ps))
5696                 return False;
5697
5698         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
5699                 return False;
5700         if(!prs_werror("status", ps, depth, &r_u->status))
5701                 return False;
5702
5703         return True;
5704 }
5705
5706 /*******************************************************************
5707 ********************************************************************/  
5708
5709 BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
5710 {
5711         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
5712         depth++;
5713
5714         if(!prs_align(ps))
5715                 return False;
5716         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
5717                 return False;
5718         if(!prs_uint32("index", ps, depth, &q_u->index))
5719                 return False;
5720         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
5721                 return False;
5722         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
5723                 return False;
5724
5725         return True;
5726 }
5727
5728 /*******************************************************************
5729 ********************************************************************/  
5730
5731 BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
5732                 const POLICY_HND *hnd,
5733                 uint32 idx, uint32 valuelen, uint32 datalen)
5734 {
5735         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5736         q_u->index=idx;
5737         q_u->valuesize=valuelen;
5738         q_u->datasize=datalen;
5739
5740         return True;
5741 }
5742
5743 /*******************************************************************
5744 ********************************************************************/  
5745 BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd,
5746                                 char* value, char* data)
5747 {
5748         UNISTR2 tmp;
5749
5750         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
5751         q_u->type = REG_SZ;
5752         init_unistr2(&q_u->value, value, strlen(value)+1);
5753
5754         init_unistr2(&tmp, data, strlen(data)+1);
5755         q_u->max_len = q_u->real_len = tmp.uni_max_len*2;
5756         q_u->data = talloc(ctx, q_u->real_len);
5757         memcpy(q_u->data, tmp.buffer, q_u->real_len);
5758         
5759         return True;
5760 }
5761 /*******************************************************************
5762 ********************************************************************/  
5763
5764 BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
5765 {
5766         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
5767         depth++;
5768
5769         if(!prs_align(ps))
5770                 return False;
5771         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5772                 return False;
5773         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
5774                 return False;
5775
5776         if(!prs_align(ps))
5777                 return False;
5778
5779         if(!prs_uint32("type", ps, depth, &q_u->type))
5780                 return False;
5781
5782         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
5783                 return False;
5784
5785         switch (q_u->type)
5786         {
5787                 case REG_SZ:
5788                 case REG_BINARY:
5789                 case REG_DWORD:
5790                 case REG_MULTI_SZ:
5791             if (q_u->max_len) {
5792                 if (UNMARSHALLING(ps))
5793                                 q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
5794                         if(q_u->data == NULL)
5795                                 return False;
5796                         if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
5797                                 return False;
5798             }
5799                         if(!prs_align(ps))
5800                                 return False;
5801                         break;
5802         }       
5803         
5804         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
5805                 return False;
5806
5807         return True;
5808 }
5809
5810 /*******************************************************************
5811 ********************************************************************/  
5812
5813 BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
5814 {
5815         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
5816         depth++;
5817
5818         if(!prs_align(ps))
5819                 return False;
5820         if(!prs_werror("status",     ps, depth, &r_u->status))
5821                 return False;
5822
5823         return True;
5824 }
5825
5826 /*******************************************************************
5827 ********************************************************************/  
5828 BOOL spoolss_io_q_resetprinter(char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth)
5829 {
5830         prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter");
5831         depth++;
5832
5833         if (!prs_align(ps))
5834                 return False;
5835         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5836                 return False;
5837
5838         if (!prs_uint32("datatype_ptr", ps, depth, &q_u->datatype_ptr))
5839                 return False;
5840                 
5841         if (q_u->datatype_ptr) {
5842                 if (!smb_io_unistr2("datatype", &q_u->datatype, q_u->datatype_ptr?True:False, ps, depth))
5843                 return False;
5844         }
5845
5846         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
5847                 return False;
5848
5849         return True;
5850 }
5851
5852
5853 /*******************************************************************
5854 ********************************************************************/  
5855 BOOL spoolss_io_r_resetprinter(char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth)
5856 {
5857         prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter");
5858         depth++;
5859
5860         if(!prs_align(ps))
5861                 return False;
5862         if(!prs_werror("status",     ps, depth, &r_u->status))
5863                 return False;
5864
5865         return True;
5866 }
5867
5868 /*******************************************************************
5869 ********************************************************************/  
5870 BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
5871                                 uint32 type, const uint8 *data, uint32 len)
5872 {
5873         DEBUG(5,("converting a specific param struct\n"));
5874
5875         if (*param == NULL)
5876         {
5877                 *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
5878                 if(*param == NULL)
5879                         return False;
5880                 memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
5881                 DEBUGADD(6,("Allocated a new PARAM struct\n"));
5882         }
5883         unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
5884         (*param)->type = type;
5885         
5886         /* le champ data n'est pas NULL termine */
5887         /* on stocke donc la longueur */
5888         
5889         (*param)->data_len=len;
5890         
5891         if (len) {
5892                 (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
5893                 if((*param)->data == NULL)
5894                         return False;
5895                 memcpy((*param)->data, data, len);
5896         }
5897                 
5898         DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
5899         dump_data(10, (char *)(*param)->data, (*param)->data_len);
5900
5901         return True;
5902 }
5903
5904 /*******************************************************************
5905 ********************************************************************/  
5906
5907 static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
5908 {
5909         prs_debug(ps, depth, desc, "spoolss_io_addform");
5910         depth++;
5911         if(!prs_align(ps))
5912                 return False;
5913
5914         if (ptr!=0)
5915         {
5916                 if(!prs_uint32("flags",    ps, depth, &f->flags))
5917                         return False;
5918                 if(!prs_uint32("name_ptr", ps, depth, &f->name_ptr))
5919                         return False;
5920                 if(!prs_uint32("size_x",   ps, depth, &f->size_x))
5921                         return False;
5922                 if(!prs_uint32("size_y",   ps, depth, &f->size_y))
5923                         return False;
5924                 if(!prs_uint32("left",     ps, depth, &f->left))
5925                         return False;
5926                 if(!prs_uint32("top",      ps, depth, &f->top))
5927                         return False;
5928                 if(!prs_uint32("right",    ps, depth, &f->right))
5929                         return False;
5930                 if(!prs_uint32("bottom",   ps, depth, &f->bottom))
5931                         return False;
5932
5933                 if(!smb_io_unistr2("", &f->name, f->name_ptr, ps, depth))
5934                         return False;
5935         }
5936
5937         return True;
5938 }
5939
5940 /*******************************************************************
5941 ********************************************************************/  
5942
5943 BOOL spoolss_io_q_deleteform(char *desc, SPOOL_Q_DELETEFORM *q_u, prs_struct *ps, int depth)
5944 {
5945         prs_debug(ps, depth, desc, "spoolss_io_q_deleteform");
5946         depth++;
5947
5948         if(!prs_align(ps))
5949                 return False;
5950         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5951                 return False;
5952         if(!smb_io_unistr2("form name", &q_u->name, True, ps, depth))
5953                 return False;
5954
5955         return True;
5956 }
5957
5958 /*******************************************************************
5959 ********************************************************************/  
5960
5961 BOOL spoolss_io_r_deleteform(char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps, int depth)
5962 {
5963         prs_debug(ps, depth, desc, "spoolss_io_r_deleteform");
5964         depth++;
5965
5966         if(!prs_align(ps))
5967                 return False;
5968         if(!prs_werror("status",        ps, depth, &r_u->status))
5969                 return False;
5970
5971         return True;
5972 }
5973
5974 /*******************************************************************
5975 ********************************************************************/  
5976
5977 BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
5978 {
5979         uint32 useless_ptr=1;
5980         prs_debug(ps, depth, desc, "spoolss_io_q_addform");
5981         depth++;
5982
5983         if(!prs_align(ps))
5984                 return False;
5985         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
5986                 return False;
5987         if(!prs_uint32("level",  ps, depth, &q_u->level))
5988                 return False;
5989         if(!prs_uint32("level2", ps, depth, &q_u->level2))
5990                 return False;
5991
5992         if (q_u->level==1)
5993         {
5994                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
5995                         return False;
5996                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
5997                         return False;
5998         }
5999
6000         return True;
6001 }
6002
6003 /*******************************************************************
6004 ********************************************************************/  
6005
6006 BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
6007 {
6008         prs_debug(ps, depth, desc, "spoolss_io_r_addform");
6009         depth++;
6010
6011         if(!prs_align(ps))
6012                 return False;
6013         if(!prs_werror("status",        ps, depth, &r_u->status))
6014                 return False;
6015
6016         return True;
6017 }
6018
6019 /*******************************************************************
6020 ********************************************************************/  
6021
6022 BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth)
6023 {
6024         uint32 useless_ptr=1;
6025         prs_debug(ps, depth, desc, "spoolss_io_q_setform");
6026         depth++;
6027
6028         if(!prs_align(ps))
6029                 return False;
6030         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6031                 return False;
6032         if(!smb_io_unistr2("", &q_u->name, True, ps, depth))
6033                 return False;
6034               
6035         if(!prs_align(ps))
6036                 return False;
6037         
6038         if(!prs_uint32("level",  ps, depth, &q_u->level))
6039                 return False;
6040         if(!prs_uint32("level2", ps, depth, &q_u->level2))
6041                 return False;
6042
6043         if (q_u->level==1)
6044         {
6045                 if(!prs_uint32("useless_ptr", ps, depth, &useless_ptr))
6046                         return False;
6047                 if(!spoolss_io_addform("", &q_u->form, useless_ptr, ps, depth))
6048                         return False;
6049         }
6050
6051         return True;
6052 }
6053
6054 /*******************************************************************
6055 ********************************************************************/  
6056
6057 BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth)
6058 {
6059         prs_debug(ps, depth, desc, "spoolss_io_r_setform");
6060         depth++;
6061
6062         if(!prs_align(ps))
6063                 return False;
6064         if(!prs_werror("status",        ps, depth, &r_u->status))
6065                 return False;
6066
6067         return True;
6068 }
6069
6070 /*******************************************************************
6071  Parse a SPOOL_R_GETJOB structure.
6072 ********************************************************************/  
6073
6074 BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
6075 {               
6076         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
6077         depth++;
6078
6079         if (!prs_align(ps))
6080                 return False;
6081                 
6082         if (!spoolss_io_buffer("", ps, depth, &r_u->buffer))
6083                 return False;
6084
6085         if (!prs_align(ps))
6086                 return False;
6087                 
6088         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6089                 return False;
6090                 
6091         if (!prs_werror("status", ps, depth, &r_u->status))
6092                 return False;
6093
6094         return True;            
6095 }
6096
6097 /*******************************************************************
6098  Parse a SPOOL_Q_GETJOB structure.
6099 ********************************************************************/  
6100
6101 BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
6102 {
6103         prs_debug(ps, depth, desc, "");
6104         depth++;
6105
6106         if(!prs_align(ps))
6107                 return False;
6108
6109         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6110                 return False;
6111         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
6112                 return False;
6113         if(!prs_uint32("level", ps, depth, &q_u->level))
6114                 return False;
6115         
6116         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
6117                 return False;
6118
6119         if(!prs_align(ps))
6120                 return False;
6121         
6122         if(!prs_uint32("offered", ps, depth, &q_u->offered))
6123                 return False;
6124
6125         return True;
6126 }
6127
6128 void free_devmode(DEVICEMODE *devmode)
6129 {
6130         if (devmode!=NULL) {
6131                 SAFE_FREE(devmode->private);
6132                 SAFE_FREE(devmode);
6133         }
6134 }
6135
6136 void free_printer_info_1(PRINTER_INFO_1 *printer)
6137 {
6138         SAFE_FREE(printer);
6139 }
6140
6141 void free_printer_info_2(PRINTER_INFO_2 *printer)
6142 {
6143         if (printer!=NULL) {
6144                 free_devmode(printer->devmode);
6145                 printer->devmode = NULL;
6146                 SAFE_FREE(printer);
6147         }
6148 }
6149
6150 void free_printer_info_3(PRINTER_INFO_3 *printer)
6151 {
6152         SAFE_FREE(printer);
6153 }
6154
6155 void free_printer_info_4(PRINTER_INFO_4 *printer)
6156 {
6157         SAFE_FREE(printer);
6158 }
6159
6160 void free_printer_info_5(PRINTER_INFO_5 *printer)
6161 {
6162         SAFE_FREE(printer);
6163 }
6164
6165 void free_job_info_2(JOB_INFO_2 *job)
6166 {
6167     if (job!=NULL)
6168         free_devmode(job->devmode);
6169 }
6170
6171 /*******************************************************************
6172  * init a structure.
6173  ********************************************************************/
6174
6175 BOOL make_spoolss_q_replyopenprinter(SPOOL_Q_REPLYOPENPRINTER *q_u, 
6176                                const fstring string, uint32 printer, uint32 type)
6177 {      
6178         if (q_u == NULL)
6179                 return False;
6180
6181         init_unistr2(&q_u->string, string, strlen(string)+1);
6182
6183         q_u->printer=printer;
6184         q_u->type=type;
6185
6186         q_u->unknown0=0x0;
6187         q_u->unknown1=0x0;
6188
6189         return True;
6190 }
6191
6192 /*******************************************************************
6193  Parse a SPOOL_Q_REPLYOPENPRINTER structure.
6194 ********************************************************************/  
6195
6196 BOOL spoolss_io_q_replyopenprinter(char *desc, SPOOL_Q_REPLYOPENPRINTER *q_u, prs_struct *ps, int depth)
6197 {
6198         prs_debug(ps, depth, desc, "spoolss_io_q_replyopenprinter");
6199         depth++;
6200
6201         if(!prs_align(ps))
6202                 return False;
6203
6204         if(!smb_io_unistr2("", &q_u->string, True, ps, depth))
6205                 return False;
6206
6207         if(!prs_align(ps))
6208                 return False;
6209
6210         if(!prs_uint32("printer", ps, depth, &q_u->printer))
6211                 return False;
6212         if(!prs_uint32("type", ps, depth, &q_u->type))
6213                 return False;
6214         
6215         if(!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6216                 return False;
6217         if(!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6218                 return False;
6219
6220         return True;
6221 }
6222
6223 /*******************************************************************
6224  Parse a SPOOL_R_REPLYOPENPRINTER structure.
6225 ********************************************************************/  
6226
6227 BOOL spoolss_io_r_replyopenprinter(char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, prs_struct *ps, int depth)
6228 {               
6229         prs_debug(ps, depth, desc, "spoolss_io_r_replyopenprinter");
6230         depth++;
6231
6232         if (!prs_align(ps))
6233                 return False;
6234
6235         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6236                 return False;
6237
6238         if (!prs_werror("status", ps, depth, &r_u->status))
6239                 return False;
6240
6241         return True;            
6242 }
6243
6244 /*******************************************************************
6245  * init a structure.
6246  ********************************************************************/
6247 BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd, 
6248                                         uint32 condition, uint32 change_id)
6249 {
6250
6251         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6252
6253         q_u->condition = condition;
6254         q_u->change_id = change_id;
6255
6256         /* magic values */
6257         q_u->unknown1 = 0x1;
6258         memset(q_u->unknown2, 0x0, 5);
6259         q_u->unknown2[0] = 0x1;
6260
6261         return True;
6262 }
6263
6264 /*******************************************************************
6265  Parse a SPOOL_Q_ROUTERREPLYPRINTER structure.
6266 ********************************************************************/
6267 BOOL spoolss_io_q_routerreplyprinter (char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth)
6268 {
6269
6270         prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter");
6271         depth++;
6272
6273         if (!prs_align(ps))
6274                 return False;
6275
6276         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6277                 return False;
6278
6279         if (!prs_uint32("condition", ps, depth, &q_u->condition))
6280                 return False;
6281
6282         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6283                 return False;
6284
6285         if (!prs_uint32("change_id", ps, depth, &q_u->change_id))
6286                 return False;
6287
6288         if (!prs_uint8s(False, "private",  ps, depth, q_u->unknown2, 5))
6289                 return False;
6290
6291         return True;
6292 }
6293
6294 /*******************************************************************
6295  Parse a SPOOL_R_ROUTERREPLYPRINTER structure.
6296 ********************************************************************/
6297 BOOL spoolss_io_r_routerreplyprinter (char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth)
6298 {
6299         prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter");
6300         depth++;
6301
6302         if (!prs_align(ps))
6303                 return False;
6304
6305         if (!prs_werror("status", ps, depth, &r_u->status))
6306                 return False;
6307
6308         return True;
6309 }
6310
6311 /*******************************************************************
6312  * init a structure.
6313  ********************************************************************/
6314
6315 BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd)
6316 {      
6317         if (q_u == NULL)
6318                 return False;
6319
6320         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6321
6322         return True;
6323 }
6324
6325 /*******************************************************************
6326  Parse a SPOOL_Q_REPLYCLOSEPRINTER structure.
6327 ********************************************************************/  
6328
6329 BOOL spoolss_io_q_replycloseprinter(char *desc, SPOOL_Q_REPLYCLOSEPRINTER *q_u, prs_struct *ps, int depth)
6330 {
6331         prs_debug(ps, depth, desc, "spoolss_io_q_replycloseprinter");
6332         depth++;
6333
6334         if(!prs_align(ps))
6335                 return False;
6336
6337         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6338                 return False;
6339
6340         return True;
6341 }
6342
6343 /*******************************************************************
6344  Parse a SPOOL_R_REPLYCLOSEPRINTER structure.
6345 ********************************************************************/  
6346
6347 BOOL spoolss_io_r_replycloseprinter(char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, prs_struct *ps, int depth)
6348 {               
6349         prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter");
6350         depth++;
6351
6352         if (!prs_align(ps))
6353                 return False;
6354
6355         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
6356                 return False;
6357
6358         if (!prs_werror("status", ps, depth, &r_u->status))
6359                 return False;
6360
6361         return True;            
6362 }
6363
6364 #if 0   /* JERRY - not currently used but could be :-) */
6365
6366 /*******************************************************************
6367  Deep copy a SPOOL_NOTIFY_INFO_DATA structure
6368  ******************************************************************/
6369 static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, 
6370                                 SPOOL_NOTIFY_INFO_DATA *src, int n)
6371 {
6372         int i;
6373
6374         memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n);
6375         
6376         for (i=0; i<n; i++) {
6377                 int len;
6378                 uint16 *s = NULL;
6379                 
6380                 if (src->size != POINTER) 
6381                         continue;
6382                 len = src->notify_data.data.length;
6383                 s = malloc(sizeof(uint16)*len);
6384                 if (s == NULL) {
6385                         DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n"));
6386                         return False;
6387                 }
6388                 
6389                 memcpy(s, src->notify_data.data.string, len*2);
6390                 dst->notify_data.data.string = s;
6391         }
6392         
6393         return True;
6394 }
6395
6396 /*******************************************************************
6397  Deep copy a SPOOL_NOTIFY_INFO structure
6398  ******************************************************************/
6399 static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src)
6400 {
6401         if (!dst) {
6402                 DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n"));
6403                 return False;
6404         }
6405                 
6406         dst->version = src->version;
6407         dst->flags   = src->flags;
6408         dst->count   = src->count;
6409         
6410         if (dst->count) 
6411         {
6412                 dst->data = malloc(dst->count * sizeof(SPOOL_NOTIFY_INFO_DATA));
6413                 
6414                 DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n",
6415                         dst->count));
6416
6417                 if (dst->data == NULL) {
6418                         DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", 
6419                                 dst->count));
6420                         return False;
6421                 }
6422                 
6423                 return (copy_spool_notify_info_data(dst->data, src->data, src->count));
6424         }
6425         
6426         return True;
6427 }
6428 #endif  /* JERRY */
6429
6430 /*******************************************************************
6431  * init a structure.
6432  ********************************************************************/
6433
6434 BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
6435                                 uint32 change_low, uint32 change_high,
6436                                 SPOOL_NOTIFY_INFO *info)
6437 {      
6438         if (q_u == NULL)
6439                 return False;
6440
6441         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
6442
6443         q_u->change_low=change_low;
6444         q_u->change_high=change_high;
6445
6446         q_u->unknown0=0x0;
6447         q_u->unknown1=0x0;
6448
6449         q_u->info_ptr=0xaddee11e;
6450
6451         q_u->info.version=2;
6452         
6453         if (info->count) {
6454                 DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n",
6455                         info->count));
6456                 q_u->info.version = info->version;
6457                 q_u->info.flags   = info->flags;
6458                 q_u->info.count   = info->count;
6459                 /* pointer field - be careful! */
6460                 q_u->info.data    = info->data;
6461         }
6462         else  {
6463         q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED;
6464         q_u->info.count=0;
6465         }
6466
6467         return True;
6468 }
6469
6470 /*******************************************************************
6471  Parse a SPOOL_Q_REPLY_RRPCN structure.
6472 ********************************************************************/  
6473
6474 BOOL spoolss_io_q_reply_rrpcn(char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct *ps, int depth)
6475 {
6476         prs_debug(ps, depth, desc, "spoolss_io_q_reply_rrpcn");
6477         depth++;
6478
6479         if(!prs_align(ps))
6480                 return False;
6481
6482         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6483                 return False;
6484
6485         if (!prs_uint32("change_low", ps, depth, &q_u->change_low))
6486                 return False;
6487
6488         if (!prs_uint32("change_high", ps, depth, &q_u->change_high))
6489                 return False;
6490
6491         if (!prs_uint32("unknown0", ps, depth, &q_u->unknown0))
6492                 return False;
6493
6494         if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1))
6495                 return False;
6496
6497         if (!prs_uint32("info_ptr", ps, depth, &q_u->info_ptr))
6498                 return False;
6499
6500         if(q_u->info_ptr!=0)
6501                 if(!smb_io_notify_info(desc, &q_u->info, ps, depth))
6502                         return False;
6503                 
6504         return True;
6505 }
6506
6507 /*******************************************************************
6508  Parse a SPOOL_R_REPLY_RRPCN structure.
6509 ********************************************************************/  
6510
6511 BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth)
6512 {               
6513         prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn");
6514         depth++;
6515
6516         if (!prs_align(ps))
6517                 return False;
6518
6519         if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
6520                 return False;
6521
6522         if (!prs_werror("status", ps, depth, &r_u->status))
6523                 return False;
6524
6525         return True;            
6526 }
6527
6528 /*******************************************************************
6529  * read a structure.
6530  * called from spoolss_q_getprinterdataex (srv_spoolss.c)
6531  ********************************************************************/
6532
6533 BOOL spoolss_io_q_getprinterdataex(char *desc, SPOOL_Q_GETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6534 {
6535         if (q_u == NULL)
6536                 return False;
6537
6538         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdataex");
6539         depth++;
6540
6541         if (!prs_align(ps))
6542                 return False;
6543         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
6544                 return False;
6545         if (!prs_align(ps))
6546                 return False;
6547         if (!smb_io_unistr2("keyname", &q_u->keyname,True,ps,depth))
6548                 return False;
6549         if (!prs_align(ps))
6550                 return False;
6551         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
6552                 return False;
6553         if (!prs_align(ps))
6554                 return False;
6555         if (!prs_uint32("size", ps, depth, &q_u->size))
6556                 return False;
6557
6558         return True;
6559 }
6560
6561 /*******************************************************************
6562  * write a structure.
6563  * called from spoolss_r_getprinterdataex (srv_spoolss.c)
6564  ********************************************************************/
6565
6566 BOOL spoolss_io_r_getprinterdataex(char *desc, SPOOL_R_GETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6567 {
6568         if (r_u == NULL)
6569                 return False;
6570
6571         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdataex");
6572         depth++;
6573
6574         if (!prs_align(ps))
6575                 return False;
6576         if (!prs_uint32("type", ps, depth, &r_u->type))
6577                 return False;
6578         if (!prs_uint32("size", ps, depth, &r_u->size))
6579                 return False;
6580         
6581         if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
6582                 return False;
6583                 
6584         if (!prs_align(ps))
6585                 return False;
6586         
6587         if (!prs_uint32("needed", ps, depth, &r_u->needed))
6588                 return False;
6589         if (!prs_werror("status", ps, depth, &r_u->status))
6590                 return False;
6591                 
6592         return True;
6593 }
6594
6595 /*******************************************************************
6596  * read a structure.
6597  ********************************************************************/  
6598
6599 BOOL spoolss_io_q_setprinterdataex(char *desc, SPOOL_Q_SETPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6600 {
6601         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdataex");
6602         depth++;
6603
6604         if(!prs_align(ps))
6605                 return False;
6606         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6607                 return False;
6608         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6609                 return False;
6610
6611         if(!prs_align(ps))
6612                 return False;
6613
6614         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
6615                 return False;
6616
6617         if(!prs_align(ps))
6618                 return False;
6619
6620         if(!prs_uint32("type", ps, depth, &q_u->type))
6621                 return False;
6622
6623         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
6624                 return False;
6625
6626         switch (q_u->type)
6627         {
6628                 case 0x1:
6629                 case 0x3:
6630                 case 0x4:
6631                 case 0x7:
6632                         if (q_u->max_len) {
6633                                 if (UNMARSHALLING(ps))
6634                                         q_u->data=(uint8 *)prs_alloc_mem(ps, q_u->max_len * sizeof(uint8));
6635                                 if(q_u->data == NULL)
6636                                         return False;
6637                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
6638                                         return False;
6639                         }
6640                         if(!prs_align(ps))
6641                                 return False;
6642                         break;
6643         }       
6644         
6645         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
6646                 return False;
6647
6648         return True;
6649 }
6650
6651 /*******************************************************************
6652  * write a structure.
6653  ********************************************************************/  
6654
6655 BOOL spoolss_io_r_setprinterdataex(char *desc, SPOOL_R_SETPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6656 {
6657         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdataex");
6658         depth++;
6659
6660         if(!prs_align(ps))
6661                 return False;
6662         if(!prs_werror("status",     ps, depth, &r_u->status))
6663                 return False;
6664
6665         return True;
6666 }
6667
6668
6669 /*******************************************************************
6670  * read a structure.
6671  ********************************************************************/  
6672
6673 BOOL spoolss_io_q_enumprinterkey(char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
6674 {
6675         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
6676         depth++;
6677
6678         if(!prs_align(ps))
6679                 return False;
6680         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6681                 return False;
6682                 
6683         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6684                 return False;
6685
6686         if(!prs_align(ps))
6687                 return False;
6688         
6689         if(!prs_uint32("size", ps, depth, &q_u->size))
6690                 return False;
6691
6692         return True;
6693 }
6694
6695 /*******************************************************************
6696  * write a structure.
6697  ********************************************************************/  
6698
6699 BOOL spoolss_io_r_enumprinterkey(char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
6700 {
6701         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
6702         depth++;
6703
6704         if(!prs_align(ps))
6705                 return False;
6706
6707         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
6708                 return False;
6709         
6710         if(!prs_align(ps))
6711                 return False;
6712
6713         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6714                 return False;
6715
6716         if(!prs_werror("status",     ps, depth, &r_u->status))
6717                 return False;
6718
6719         return True;
6720 }
6721
6722
6723 /*******************************************************************
6724  * read a structure.
6725  ********************************************************************/  
6726
6727 BOOL spoolss_io_q_enumprinterdataex(char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
6728 {
6729         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
6730         depth++;
6731
6732         if(!prs_align(ps))
6733                 return False;
6734         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
6735                 return False;
6736                 
6737         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
6738                 return False;
6739
6740         if(!prs_align(ps))
6741                 return False;
6742         
6743         if(!prs_uint32("size", ps, depth, &q_u->size))
6744                 return False;
6745
6746         return True;
6747 }
6748
6749 /*******************************************************************
6750 ********************************************************************/  
6751 static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, 
6752                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
6753 {
6754         int     i;
6755         uint32  valuename_offset,
6756                 data_offset,
6757                 current_offset;
6758         const uint32 basic_unit = 20; /* size of static portion of enum_values */
6759         
6760         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
6761         depth++;        
6762         
6763         if (!prs_uint32("size", ps, depth, &ctr->size))
6764                 return False;
6765         
6766         /* offset data begins at 20 bytes per structure * size_of_array.
6767            Don't forget the uint32 at the beginning */
6768         
6769         current_offset = basic_unit * ctr->size_of_array;
6770         
6771         /* first loop to write basic enum_value information */
6772         
6773         for (i=0; i<ctr->size_of_array; i++) 
6774         {
6775                 valuename_offset = current_offset;
6776                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
6777                         return False;
6778
6779                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
6780                         return False;
6781         
6782                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
6783                         return False;
6784         
6785                 data_offset = ctr->values[i].value_len + valuename_offset;
6786                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
6787                         return False;
6788
6789                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
6790                         return False;
6791                         
6792                 current_offset = data_offset + ctr->values[i].data_len - basic_unit;
6793         }
6794
6795         /* loop #2 for writing the dynamically size objects
6796            while viewing conversations between Win2k -> Win2k,
6797            4-byte alignment does not seem to matter here   --jerry */
6798         
6799         for (i=0; i<ctr->size_of_array; i++) 
6800         {
6801         
6802                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
6803                         return False;
6804                 
6805                 if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
6806                         return False;
6807         }
6808
6809                 
6810
6811         return True;    
6812 }
6813
6814
6815 /*******************************************************************
6816  * write a structure.
6817  ********************************************************************/  
6818
6819 BOOL spoolss_io_r_enumprinterdataex(char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
6820 {
6821         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
6822         depth++;
6823
6824         if(!prs_align(ps))
6825                 return False;
6826                 
6827         if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
6828                 return False;
6829         
6830         if(!prs_align(ps))
6831                 return False;
6832
6833         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6834                 return False;
6835                 
6836         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
6837                 return False;
6838
6839         if(!prs_werror("status",     ps, depth, &r_u->status))
6840                 return False;
6841
6842         return True;
6843 }
6844
6845
6846 /*******************************************************************
6847  * write a structure.
6848  ********************************************************************/  
6849
6850 /* 
6851    uint32 GetPrintProcessorDirectory(
6852        [in] unistr2 *name,
6853        [in] unistr2 *environment,
6854        [in] uint32 level,
6855        [in,out] NEW_BUFFER buffer,
6856        [in] uint32 offered,
6857        [out] uint32 needed,
6858        [out] uint32 returned
6859    );
6860
6861 */
6862
6863 BOOL make_spoolss_q_getprintprocessordirectory(SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, const char *name, char *environment, int level, NEW_BUFFER *buffer, uint32 offered)
6864 {
6865         DEBUG(5,("make_spoolss_q_getprintprocessordirectory\n"));
6866
6867         init_unistr2(&q_u->name, name, strlen(name)+1);
6868         init_unistr2(&q_u->environment, environment, strlen(environment)+1);
6869
6870         q_u->level = level;
6871
6872         q_u->buffer = buffer;
6873         q_u->offered = offered;
6874
6875         return True;
6876 }
6877
6878 BOOL spoolss_io_q_getprintprocessordirectory(char *desc, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, prs_struct *ps, int depth)
6879 {
6880         uint32 ptr;
6881
6882         prs_debug(ps, depth, desc, "spoolss_io_q_getprintprocessordirectory");
6883         depth++;
6884
6885         if(!prs_align(ps))
6886                 return False;   
6887
6888         if (!prs_uint32("ptr", ps, depth, &ptr)) 
6889                 return False;
6890
6891         if (ptr) {
6892                 if(!smb_io_unistr2("name", &q_u->name, True, ps, depth))
6893                         return False;
6894         }
6895
6896         if (!prs_align(ps))
6897                 return False;
6898
6899         if (!prs_uint32("ptr", ps, depth, &ptr))
6900                 return False;
6901
6902         if (ptr) {
6903                 if(!smb_io_unistr2("environment", &q_u->environment, True, 
6904                                    ps, depth))
6905                         return False;
6906         }
6907
6908         if (!prs_align(ps))
6909                 return False;
6910
6911         if(!prs_uint32("level",   ps, depth, &q_u->level))
6912                 return False;
6913
6914         if(!spoolss_io_buffer("", ps, depth, &q_u->buffer))
6915                 return False;
6916         
6917         if(!prs_align(ps))
6918                 return False;
6919
6920         if(!prs_uint32("offered", ps, depth, &q_u->offered))
6921                 return False;
6922
6923         return True;
6924 }
6925
6926 /*******************************************************************
6927  * write a structure.
6928  ********************************************************************/  
6929
6930 BOOL spoolss_io_r_getprintprocessordirectory(char *desc, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u, prs_struct *ps, int depth)
6931 {
6932         prs_debug(ps, depth, desc, "spoolss_io_r_getprintprocessordirectory");
6933         depth++;
6934
6935         if(!prs_align(ps))
6936                 return False;
6937
6938         if(!spoolss_io_buffer("", ps, depth, &r_u->buffer))
6939                 return False;
6940         
6941         if(!prs_align(ps))
6942                 return False;
6943
6944         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
6945                 return False;
6946                 
6947         if(!prs_werror("status",     ps, depth, &r_u->status))
6948                 return False;
6949
6950         return True;
6951 }
6952
6953 BOOL smb_io_printprocessordirectory_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_DIRECTORY_1 *info, int depth)
6954 {
6955         prs_struct *ps=&buffer->prs;
6956
6957         prs_debug(ps, depth, desc, "smb_io_printprocessordirectory_1");
6958         depth++;
6959
6960         buffer->struct_start=prs_offset(ps);
6961
6962         if (!smb_io_unistr(desc, &info->name, ps, depth))
6963                 return False;
6964
6965         return True;
6966 }
6967
6968 /*******************************************************************
6969  * init a structure.
6970  ********************************************************************/
6971
6972 BOOL make_spoolss_q_addform(SPOOL_Q_ADDFORM *q_u, POLICY_HND *handle, 
6973                             int level, FORM *form)
6974 {
6975         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
6976         q_u->level = level;
6977         q_u->level2 = level;
6978         memcpy(&q_u->form, form, sizeof(FORM));
6979
6980         return True;
6981 }
6982
6983 /*******************************************************************
6984  * init a structure.
6985  ********************************************************************/
6986
6987 BOOL make_spoolss_q_setform(SPOOL_Q_SETFORM *q_u, POLICY_HND *handle, 
6988                             int level, char *form_name, FORM *form)
6989 {
6990         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
6991         q_u->level = level;
6992         q_u->level2 = level;
6993         memcpy(&q_u->form, form, sizeof(FORM));
6994         init_unistr2(&q_u->name, form_name, strlen(form_name) + 1);
6995
6996         return True;
6997 }
6998
6999 /*******************************************************************
7000  * init a structure.
7001  ********************************************************************/
7002
7003 BOOL make_spoolss_q_deleteform(SPOOL_Q_DELETEFORM *q_u, POLICY_HND *handle, char *form)
7004 {
7005         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7006         init_unistr2(&q_u->name, form, strlen(form) + 1);
7007         return True;
7008 }
7009
7010 /*******************************************************************
7011  * init a structure.
7012  ********************************************************************/
7013
7014 BOOL make_spoolss_q_getform(SPOOL_Q_GETFORM *q_u, POLICY_HND *handle, 
7015                             char *formname, uint32 level, NEW_BUFFER *buffer,
7016                             uint32 offered)
7017 {
7018         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7019         q_u->level = level;
7020         init_unistr2(&q_u->formname, formname, strlen(formname) + 1);
7021         q_u->buffer=buffer;
7022         q_u->offered=offered;
7023
7024         return True;
7025 }
7026
7027 /*******************************************************************
7028  * init a structure.
7029  ********************************************************************/
7030
7031 BOOL make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
7032                               uint32 level, NEW_BUFFER *buffer,
7033                               uint32 offered)
7034 {
7035         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
7036         q_u->level = level;
7037         q_u->buffer=buffer;
7038         q_u->offered=offered;
7039
7040         return True;
7041 }