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