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