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