The first of Martin Zielinski <mz@seh.de> Vista printing patches.
[samba.git] / source / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean Fran├žois Micouleau      1998-2000,
7  *  Copyright (C) Gerald Carter                2000-2002,
8  *  Copyright (C) Tim Potter                   2001-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 3 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, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29
30 /*******************************************************************
31 This should be moved in a more generic lib.
32 ********************************************************************/  
33
34 bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
35 {
36         if(!prs_uint16("year", ps, depth, &systime->year))
37                 return False;
38         if(!prs_uint16("month", ps, depth, &systime->month))
39                 return False;
40         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
41                 return False;
42         if(!prs_uint16("day", ps, depth, &systime->day))
43                 return False;
44         if(!prs_uint16("hour", ps, depth, &systime->hour))
45                 return False;
46         if(!prs_uint16("minute", ps, depth, &systime->minute))
47                 return False;
48         if(!prs_uint16("second", ps, depth, &systime->second))
49                 return False;
50         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
51                 return False;
52
53         return True;
54 }
55
56 /*******************************************************************
57 ********************************************************************/  
58
59 bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
60 {
61         systime->year=unixtime->tm_year+1900;
62         systime->month=unixtime->tm_mon+1;
63         systime->dayofweek=unixtime->tm_wday;
64         systime->day=unixtime->tm_mday;
65         systime->hour=unixtime->tm_hour;
66         systime->minute=unixtime->tm_min;
67         systime->second=unixtime->tm_sec;
68         systime->milliseconds=0;
69
70         return True;
71 }
72
73 /*******************************************************************
74 reads or writes an DOC_INFO structure.
75 ********************************************************************/  
76
77 static bool smb_io_doc_info_1(const char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth)
78 {
79         if (info_1 == NULL) return False;
80
81         prs_debug(ps, depth, desc, "smb_io_doc_info_1");
82         depth++;
83  
84         if(!prs_align(ps))
85                 return False;
86         
87         if(!prs_uint32("p_docname",    ps, depth, &info_1->p_docname))
88                 return False;
89         if(!prs_uint32("p_outputfile", ps, depth, &info_1->p_outputfile))
90                 return False;
91         if(!prs_uint32("p_datatype",   ps, depth, &info_1->p_datatype))
92                 return False;
93
94         if(!smb_io_unistr2("", &info_1->docname,    info_1->p_docname,    ps, depth))
95                 return False;
96         if(!smb_io_unistr2("", &info_1->outputfile, info_1->p_outputfile, ps, depth))
97                 return False;
98         if(!smb_io_unistr2("", &info_1->datatype,   info_1->p_datatype,   ps, depth))
99                 return False;
100
101         return True;
102 }
103
104 /*******************************************************************
105 reads or writes an DOC_INFO structure.
106 ********************************************************************/  
107
108 static bool smb_io_doc_info(const char *desc, DOC_INFO *info, prs_struct *ps, int depth)
109 {
110         uint32 useless_ptr=0;
111         
112         if (info == NULL) return False;
113
114         prs_debug(ps, depth, desc, "smb_io_doc_info");
115         depth++;
116  
117         if(!prs_align(ps))
118                 return False;
119         
120         if(!prs_uint32("switch_value", ps, depth, &info->switch_value))
121                 return False;
122         
123         if(!prs_uint32("doc_info_X ptr", ps, depth, &useless_ptr))
124                 return False;
125
126         switch (info->switch_value)
127         {
128                 case 1: 
129                         if(!smb_io_doc_info_1("",&info->doc_info_1, ps, depth))
130                                 return False;
131                         break;
132                 case 2:
133                         /*
134                           this is just a placeholder
135                           
136                           MSDN July 1998 says doc_info_2 is only on
137                           Windows 95, and as Win95 doesn't do RPC to print
138                           this case is nearly impossible
139                           
140                           Maybe one day with Windows for dishwasher 2037 ...
141                           
142                         */
143                         /* smb_io_doc_info_2("",&info->doc_info_2, ps, depth); */
144                         break;
145                 default:
146                         DEBUG(0,("Something is obviously wrong somewhere !\n"));
147                         break;
148         }
149
150         return True;
151 }
152
153 /*******************************************************************
154 reads or writes an DOC_INFO_CONTAINER structure.
155 ********************************************************************/  
156
157 static bool smb_io_doc_info_container(const char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth)
158 {
159         if (cont == NULL) return False;
160
161         prs_debug(ps, depth, desc, "smb_io_doc_info_container");
162         depth++;
163  
164         if(!prs_align(ps))
165                 return False;
166         
167         if(!prs_uint32("level", ps, depth, &cont->level))
168                 return False;
169         
170         if(!smb_io_doc_info("",&cont->docinfo, ps, depth))
171                 return False;
172
173         return True;
174 }
175
176 /*******************************************************************
177 reads or writes an NOTIFY OPTION TYPE structure.
178 ********************************************************************/  
179
180 /* NOTIFY_OPTION_TYPE and NOTIFY_OPTION_TYPE_DATA are really one
181    structure.  The _TYPE structure is really the deferred referrants (i.e
182    the notify fields array) of the _TYPE structure. -tpot */
183
184 static bool smb_io_notify_option_type(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
185 {
186         prs_debug(ps, depth, desc, "smb_io_notify_option_type");
187         depth++;
188  
189         if (!prs_align(ps))
190                 return False;
191
192         if(!prs_uint16("type", ps, depth, &type->type))
193                 return False;
194         if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
195                 return False;
196         if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
197                 return False;
198         if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
199                 return False;
200         if(!prs_uint32("count", ps, depth, &type->count))
201                 return False;
202         if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
203                 return False;
204
205         return True;
206 }
207
208 /*******************************************************************
209 reads or writes an NOTIFY OPTION TYPE DATA.
210 ********************************************************************/  
211
212 static bool smb_io_notify_option_type_data(const char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
213 {
214         int i;
215
216         prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
217         depth++;
218  
219         /* if there are no fields just return */
220         if (type->fields_ptr==0)
221                 return True;
222
223         if(!prs_align(ps))
224                 return False;
225
226         if(!prs_uint32("count2", ps, depth, &type->count2))
227                 return False;
228         
229         if (type->count2 != type->count)
230                 DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
231
232         if (type->count2 > MAX_NOTIFY_TYPE_FOR_NOW) {
233                 return False;
234         }
235
236         /* parse the option type data */
237         for(i=0;i<type->count2;i++)
238                 if(!prs_uint16("fields",ps,depth,&type->fields[i]))
239                         return False;
240         return True;
241 }
242
243 /*******************************************************************
244 reads or writes an NOTIFY OPTION structure.
245 ********************************************************************/  
246
247 static bool smb_io_notify_option_type_ctr(const char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
248 {               
249         int i;
250         
251         prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
252         depth++;
253  
254         if(!prs_uint32("count", ps, depth, &ctr->count))
255                 return False;
256
257         /* reading */
258         if (UNMARSHALLING(ps) && ctr->count)
259                 if((ctr->type=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION_TYPE,ctr->count)) == NULL)
260                         return False;
261                 
262         /* the option type struct */
263         for(i=0;i<ctr->count;i++)
264                 if(!smb_io_notify_option_type("", &ctr->type[i] , ps, depth))
265                         return False;
266
267         /* the type associated with the option type struct */
268         for(i=0;i<ctr->count;i++)
269                 if(!smb_io_notify_option_type_data("", &ctr->type[i] , ps, depth))
270                         return False;
271         
272         return True;
273 }
274
275 /*******************************************************************
276 reads or writes an NOTIFY OPTION structure.
277 ********************************************************************/  
278
279 static bool smb_io_notify_option(const char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
280 {
281         prs_debug(ps, depth, desc, "smb_io_notify_option");
282         depth++;
283         
284         if(!prs_uint32("version", ps, depth, &option->version))
285                 return False;
286         if(!prs_uint32("flags", ps, depth, &option->flags))
287                 return False;
288         if(!prs_uint32("count", ps, depth, &option->count))
289                 return False;
290         if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
291                 return False;
292         
293         /* marshalling or unmarshalling, that would work */     
294         if (option->option_type_ptr!=0) {
295                 if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
296                         return False;
297         }
298         else {
299                 option->ctr.type=NULL;
300                 option->ctr.count=0;
301         }
302         
303         return True;
304 }
305
306 /*******************************************************************
307 reads or writes an NOTIFY INFO DATA structure.
308 ********************************************************************/  
309
310 static bool smb_io_notify_info_data(const char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
311 {
312         uint32 useless_ptr=0x0FF0ADDE;
313
314         prs_debug(ps, depth, desc, "smb_io_notify_info_data");
315         depth++;
316
317         if(!prs_align(ps))
318                 return False;
319         if(!prs_uint16("type",           ps, depth, &data->type))
320                 return False;
321         if(!prs_uint16("field",          ps, depth, &data->field))
322                 return False;
323
324         if(!prs_uint32("how many words", ps, depth, &data->size))
325                 return False;
326         if(!prs_uint32("id",             ps, depth, &data->id))
327                 return False;
328         if(!prs_uint32("how many words", ps, depth, &data->size))
329                 return False;
330
331         switch (data->enc_type) {
332
333                 /* One and two value data has two uint32 values */
334
335         case NOTIFY_ONE_VALUE:
336         case NOTIFY_TWO_VALUE:
337
338                 if(!prs_uint32("value[0]", ps, depth, &data->notify_data.value[0]))
339                         return False;
340                 if(!prs_uint32("value[1]", ps, depth, &data->notify_data.value[1]))
341                         return False;
342                 break;
343
344                 /* Pointers and strings have a string length and a
345                    pointer.  For a string the length is expressed as
346                    the number of uint16 characters plus a trailing
347                    \0\0. */
348
349         case NOTIFY_POINTER:
350
351                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length ))
352                         return False;
353                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
354                         return False;
355
356                 break;
357
358         case NOTIFY_STRING:
359
360                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
361                         return False;
362
363                 if(!prs_uint32("pointer", ps, depth, &useless_ptr))
364                         return False;
365
366                 break;
367
368         case NOTIFY_SECDESC:
369                 if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
370                         return False;
371                 if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
372                         return False;
373                 
374                 break;
375
376         default:
377                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
378                           data->enc_type));
379                 break;
380         }
381
382         return True;
383 }
384
385 /*******************************************************************
386 reads or writes an NOTIFY INFO DATA structure.
387 ********************************************************************/  
388
389 bool smb_io_notify_info_data_strings(const char *desc,SPOOL_NOTIFY_INFO_DATA *data,
390                                      prs_struct *ps, int depth)
391 {
392         prs_debug(ps, depth, desc, "smb_io_notify_info_data_strings");
393         depth++;
394         
395         if(!prs_align(ps))
396                 return False;
397
398         switch(data->enc_type) {
399
400                 /* No data for values */
401
402         case NOTIFY_ONE_VALUE:
403         case NOTIFY_TWO_VALUE:
404
405                 break;
406
407                 /* Strings start with a length in uint16s */
408
409         case NOTIFY_STRING:
410
411                 if (MARSHALLING(ps))
412                         data->notify_data.data.length /= 2;
413
414                 if(!prs_uint32("string length", ps, depth, &data->notify_data.data.length))
415                         return False;
416
417                 if (UNMARSHALLING(ps) && data->notify_data.data.length) {
418                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
419                                                                 data->notify_data.data.length);
420
421                         if (!data->notify_data.data.string) 
422                                 return False;
423                 }
424
425                 if (!prs_uint16uni(True, "string", ps, depth, data->notify_data.data.string,
426                                    data->notify_data.data.length))
427                         return False;
428
429                 if (MARSHALLING(ps))
430                         data->notify_data.data.length *= 2;
431
432                 break;
433
434         case NOTIFY_POINTER:
435
436                 if (UNMARSHALLING(ps) && data->notify_data.data.length) {
437                         data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16,
438                                                                 data->notify_data.data.length);
439
440                         if (!data->notify_data.data.string) 
441                                 return False;
442                 }
443
444                 if(!prs_uint8s(True,"buffer",ps,depth,(uint8*)data->notify_data.data.string,data->notify_data.data.length))
445                         return False;
446
447                 break;
448
449         case NOTIFY_SECDESC:    
450                 if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
451                         return False;
452                 if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
453                         return False;
454                 break;
455
456         default:
457                 DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
458                           data->enc_type));
459                 break;
460         }
461
462 #if 0
463         if (isvalue==False) {
464
465                 /* length of string in unicode include \0 */
466                 x=data->notify_data.data.length+1;
467
468                 if (data->field != 16)
469                 if(!prs_uint32("string length", ps, depth, &x ))
470                         return False;
471
472                 if (MARSHALLING(ps)) {
473                         /* These are already in little endian format. Don't byte swap. */
474                         if (x == 1) {
475
476                                 /* No memory allocated for this string
477                                    therefore following the data.string
478                                    pointer is a bad idea.  Use a pointer to
479                                    the uint32 length union member to
480                                    provide a source for a unicode NULL */
481
482                                 if(!prs_uint8s(True,"string",ps,depth, (uint8 *)&data->notify_data.data.length,x*2)) 
483                                         return False;
484                         } else {
485
486                                 if (data->field == 16)
487                                         x /= 2;
488
489                                 if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
490                                         return False;
491                         }
492                 } else {
493
494                         /* Tallocate memory for string */
495
496                         if (x) {
497                                 data->notify_data.data.string = PRS_ALLOC_MEM(ps, uint16, x * 2);
498                                 if (!data->notify_data.data.string) 
499                                         return False;
500                         } else {
501                                 data->notify_data.data.string = NULL;
502                         }
503
504                         if(!prs_uint16uni(True,"string",ps,depth,data->notify_data.data.string,x))
505                                 return False;
506                 }
507         }
508
509 #endif
510
511 #if 0   /* JERRY */
512         /* Win2k does not seem to put this parse align here */
513         if(!prs_align(ps))
514                 return False;
515 #endif
516
517         return True;
518 }
519
520 /*******************************************************************
521 reads or writes an NOTIFY INFO structure.
522 ********************************************************************/  
523
524 static bool smb_io_notify_info(const char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
525 {
526         int i;
527
528         prs_debug(ps, depth, desc, "smb_io_notify_info");
529         depth++;
530  
531         if(!prs_align(ps))
532                 return False;
533
534         if(!prs_uint32("count", ps, depth, &info->count))
535                 return False;
536         if(!prs_uint32("version", ps, depth, &info->version))
537                 return False;
538         if(!prs_uint32("flags", ps, depth, &info->flags))
539                 return False;
540         if(!prs_uint32("count", ps, depth, &info->count))
541                 return False;
542
543         for (i=0;i<info->count;i++) {
544                 if(!smb_io_notify_info_data(desc, &info->data[i], ps, depth))
545                         return False;
546         }
547
548         /* now do the strings at the end of the stream */       
549         for (i=0;i<info->count;i++) {
550                 if(!smb_io_notify_info_data_strings(desc, &info->data[i], ps, depth))
551                         return False;
552         }
553
554         return True;
555 }
556
557 /*******************************************************************
558 ********************************************************************/  
559
560 bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
561 {
562         prs_debug(ps, depth, desc, "");
563         depth++;
564
565         if (!prs_align(ps))
566                 return False;
567
568         if (!prs_uint32("size", ps, depth, &q_u->size))
569                 return False;
570
571         if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
572                 return False;
573         if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
574                 return False;
575
576         if (!prs_uint32("build", ps, depth, &q_u->build))
577                 return False;
578         if (!prs_uint32("major", ps, depth, &q_u->major))
579                 return False;
580         if (!prs_uint32("minor", ps, depth, &q_u->minor))
581                 return False;
582         if (!prs_uint32("processor", ps, depth, &q_u->processor))
583                 return False;
584
585         if (!prs_io_unistr2("", ps, depth, q_u->client_name))
586                 return False;
587         if (!prs_align(ps))
588                 return False;
589
590         if (!prs_io_unistr2("", ps, depth, q_u->user_name))
591                 return False;
592
593         return True;
594 }
595
596 /*******************************************************************
597 ********************************************************************/  
598
599 static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
600 {
601         if (q_u==NULL)
602                 return False;
603
604         prs_debug(ps, depth, desc, "spool_io_user_level");
605         depth++;
606
607         if (!prs_align(ps))
608                 return False;
609
610         if (!prs_uint32("level", ps, depth, &q_u->level))
611                 return False;
612         
613         switch ( q_u->level ) 
614         {       
615                 case 1:
616                         if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, 
617                                 sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
618                         {
619                                 return False;
620                         }
621                         break;
622                 default:
623                         return False;   
624         }       
625
626         return True;
627 }
628
629 /*******************************************************************
630  * read or write a DEVICEMODE struct.
631  * on reading allocate memory for the private member
632  ********************************************************************/
633
634 #define DM_NUM_OPTIONAL_FIELDS          8
635
636 bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
637 {
638         int available_space;            /* size of the device mode left to parse */
639                                         /* only important on unmarshalling       */
640         int i = 0;
641         uint16 *unistr_buffer;
642         int j;
643                                         
644         struct optional_fields {
645                 fstring         name;
646                 uint32*         field;
647         } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
648                 { "icmmethod",          NULL },
649                 { "icmintent",          NULL },
650                 { "mediatype",          NULL },
651                 { "dithertype",         NULL },
652                 { "reserved1",          NULL },
653                 { "reserved2",          NULL },
654                 { "panningwidth",       NULL },
655                 { "panningheight",      NULL }
656         };
657
658         /* assign at run time to keep non-gcc compilers happy */
659
660         opt_fields[0].field = &devmode->icmmethod;
661         opt_fields[1].field = &devmode->icmintent;
662         opt_fields[2].field = &devmode->mediatype;
663         opt_fields[3].field = &devmode->dithertype;
664         opt_fields[4].field = &devmode->reserved1;
665         opt_fields[5].field = &devmode->reserved2;
666         opt_fields[6].field = &devmode->panningwidth;
667         opt_fields[7].field = &devmode->panningheight;
668                 
669         
670         prs_debug(ps, depth, desc, "spoolss_io_devmode");
671         depth++;
672
673         if (UNMARSHALLING(ps)) {
674                 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
675                 if (devmode->devicename.buffer == NULL)
676                         return False;
677                 unistr_buffer = devmode->devicename.buffer;
678         }
679         else {
680                 /* devicename is a static sized string but the buffer we set is not */
681                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
682                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
683                 for ( j=0; devmode->devicename.buffer[j]; j++ )
684                         unistr_buffer[j] = devmode->devicename.buffer[j];
685         }
686                 
687         if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
688                 return False;
689         
690         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
691                 return False;
692                 
693         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
694                 return False;
695         if (!prs_uint16("size",             ps, depth, &devmode->size))
696                 return False;
697         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
698                 return False;
699         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
700                 return False;
701         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
702                 return False;
703         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
704                 return False;
705         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
706                 return False;
707         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
708                 return False;
709         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
710                 return False;
711         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
712                 return False;
713         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
714                 return False;
715         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
716                 return False;
717         if (!prs_uint16("color",            ps, depth, &devmode->color))
718                 return False;
719         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
720                 return False;
721         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
722                 return False;
723         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
724                 return False;
725         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
726                 return False;
727
728         if (UNMARSHALLING(ps)) {
729                 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
730                 if (devmode->formname.buffer == NULL)
731                         return False;
732                 unistr_buffer = devmode->formname.buffer;
733         }
734         else {
735                 /* devicename is a static sized string but the buffer we set is not */
736                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
737                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
738                 for ( j=0; devmode->formname.buffer[j]; j++ )
739                         unistr_buffer[j] = devmode->formname.buffer[j];
740         }
741         
742         if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
743                 return False;
744         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
745                 return False;
746         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
747                 return False;
748         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
749                 return False;
750         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
751                 return False;
752         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
753                 return False;
754         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
755                 return False;
756         /* 
757          * every device mode I've ever seen on the wire at least has up 
758          * to the displayfrequency field.   --jerry (05-09-2002)
759          */
760          
761         /* add uint32's + uint16's + two UNICODE strings */
762          
763         available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
764         
765         /* Sanity check - we only have uint32's left tp parse */
766         
767         if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
768                 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
769                         available_space, devmode->size));
770                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
771                 return False;
772         }
773
774         /* 
775          * Conditional parsing.  Assume that the DeviceMode has been 
776          * zero'd by the caller. 
777          */
778         
779         while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
780         {
781                 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
782                 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
783                         return False;
784                 available_space -= sizeof(uint32);
785                 i++;
786         }        
787         
788         /* Sanity Check - we should no available space at this point unless 
789            MS changes the device mode structure */
790                 
791         if (available_space) {
792                 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
793                 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
794                         available_space, devmode->size));
795                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
796                 return False;
797         }
798
799
800         if (devmode->driverextra!=0) {
801                 if (UNMARSHALLING(ps)) {
802                         devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
803                         if(devmode->dev_private == NULL)
804                                 return False;
805                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
806                 }
807                         
808                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
809                 if (!prs_uint8s(False, "dev_private",  ps, depth,
810                                 devmode->dev_private, devmode->driverextra))
811                         return False;
812         }
813
814         return True;
815 }
816
817 /*******************************************************************
818  Read or write a DEVICEMODE container
819 ********************************************************************/  
820
821 static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
822 {
823         if (dm_c==NULL)
824                 return False;
825
826         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
827         depth++;
828
829         if(!prs_align(ps))
830                 return False;
831         
832         if (!prs_uint32("size", ps, depth, &dm_c->size))
833                 return False;
834
835         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
836                 return False;
837
838         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
839                 if (UNMARSHALLING(ps))
840                         /* if while reading there is no DEVMODE ... */
841                         dm_c->devmode=NULL;
842                 return True;
843         }
844         
845         /* so we have a DEVICEMODE to follow */         
846         if (UNMARSHALLING(ps)) {
847                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
848                 dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
849                 if(dm_c->devmode == NULL)
850                         return False;
851         }
852         
853         /* this is bad code, shouldn't be there */
854         if (!prs_uint32("size", ps, depth, &dm_c->size))
855                 return False;
856                 
857         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
858                 return False;
859
860         return True;
861 }
862
863 /*******************************************************************
864 ********************************************************************/  
865
866 static bool spoolss_io_printer_default(const char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
867 {
868         if (pd==NULL)
869                 return False;
870
871         prs_debug(ps, depth, desc, "spoolss_io_printer_default");
872         depth++;
873
874         if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
875                 return False;
876
877         if (!smb_io_unistr2("datatype", &pd->datatype, pd->datatype_ptr, ps,depth))
878                 return False;
879         
880         if (!prs_align(ps))
881                 return False;
882
883         if (!spoolss_io_devmode_cont("", &pd->devmode_cont, ps, depth))
884                 return False;
885
886         if (!prs_align(ps))
887                 return False;
888
889         if (!prs_uint32("access_required", ps, depth, &pd->access_required))
890                 return False;
891
892         return True;
893 }
894
895 /*******************************************************************
896  * init a structure.
897  ********************************************************************/
898
899 bool make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
900                 const fstring printername, 
901                 const fstring datatype, 
902                 uint32 access_required,
903                 const fstring clientname,
904                 const fstring user_name)
905 {
906         DEBUG(5,("make_spoolss_q_open_printer_ex\n"));
907
908         q_u->printername = TALLOC_P( talloc_tos(), UNISTR2 );
909         if (!q_u->printername) {
910                 return False;
911         }
912         init_unistr2(q_u->printername, printername, UNI_STR_TERMINATE);
913
914         q_u->printer_default.datatype_ptr = 0;
915
916         q_u->printer_default.devmode_cont.size=0;
917         q_u->printer_default.devmode_cont.devmode_ptr=0;
918         q_u->printer_default.devmode_cont.devmode=NULL;
919         q_u->printer_default.access_required=access_required;
920
921         q_u->user_switch = 1;
922         
923         q_u->user_ctr.level                 = 1;
924         q_u->user_ctr.user.user1            = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
925         if (!q_u->user_ctr.user.user1) {
926                 return False;
927         }
928         q_u->user_ctr.user.user1->size      = strlen(clientname) + strlen(user_name) + 10;
929         q_u->user_ctr.user.user1->build     = 1381;
930         q_u->user_ctr.user.user1->major     = 2;
931         q_u->user_ctr.user.user1->minor     = 0;
932         q_u->user_ctr.user.user1->processor = 0;
933
934         q_u->user_ctr.user.user1->client_name = TALLOC_P( talloc_tos(), UNISTR2 );
935         if (!q_u->user_ctr.user.user1->client_name) {
936                 return False;
937         }
938         q_u->user_ctr.user.user1->user_name   = TALLOC_P( talloc_tos(), UNISTR2 );
939         if (!q_u->user_ctr.user.user1->user_name) {
940                 return False;
941         }
942
943         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
944         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
945         
946         return True;
947 }
948
949 /*******************************************************************
950  * init a structure.
951  ********************************************************************/
952
953 bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
954         const char *srv_name, const char* clientname, const char* user_name,
955         uint32 level, PRINTER_INFO_CTR *ctr)
956 {
957         DEBUG(5,("make_spoolss_q_addprinterex\n"));
958         
959         if (!ctr || !ctr->printers_2) 
960                 return False;
961
962         ZERO_STRUCTP(q_u);
963
964         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
965         if (!q_u->server_name) {
966                 return False;
967         }
968         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
969
970         q_u->level = level;
971         
972         q_u->info.level = level;
973         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
974         switch (level) {
975                 case 2:
976                         /* init q_u->info.info2 from *info */
977                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
978                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
979                                 return False;
980                         }
981                         break;
982                 default :
983                         break;
984         }
985
986         q_u->user_switch=1;
987
988         q_u->user_ctr.level                 = 1;
989         q_u->user_ctr.user.user1            = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
990         if (!q_u->user_ctr.user.user1) {
991                 return False;
992         }
993         q_u->user_ctr.user.user1->build     = 1381;
994         q_u->user_ctr.user.user1->major     = 2; 
995         q_u->user_ctr.user.user1->minor     = 0;
996         q_u->user_ctr.user.user1->processor = 0;
997
998         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
999         if (!q_u->user_ctr.user.user1->client_name) {
1000                 return False;
1001         }
1002         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
1003         if (!q_u->user_ctr.user.user1->user_name) {
1004                 return False;
1005         }
1006         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
1007         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
1008
1009         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
1010                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
1011         
1012         return True;
1013 }
1014         
1015 /*******************************************************************
1016 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
1017 *******************************************************************/
1018
1019 bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
1020                                 PRINTER_INFO_2 *info)
1021 {
1022
1023         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
1024
1025         /* allocate the necessary memory */
1026         if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
1027                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
1028                 return False;
1029         }
1030
1031         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
1032         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
1033         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
1034         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
1035         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
1036         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
1037         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
1038         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
1039         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
1040         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
1041         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
1042         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
1043         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1044         inf->attributes         = info->attributes;
1045         inf->priority           = info->priority;
1046         inf->default_priority   = info->defaultpriority;
1047         inf->starttime          = info->starttime;
1048         inf->untiltime          = info->untiltime;
1049         inf->cjobs              = info->cjobs;
1050         inf->averageppm = info->averageppm;
1051         init_unistr2_from_unistr(inf, &inf->servername, &info->servername);
1052         init_unistr2_from_unistr(inf, &inf->printername, &info->printername);
1053         init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename);
1054         init_unistr2_from_unistr(inf, &inf->portname, &info->portname);
1055         init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername);
1056         init_unistr2_from_unistr(inf, &inf->comment, &info->comment);
1057         init_unistr2_from_unistr(inf, &inf->location, &info->location);
1058         init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile);
1059         init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor);
1060         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
1061         init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters);
1062         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
1063
1064         *spool_info2 = inf;
1065
1066         return True;
1067 }
1068
1069 /*******************************************************************
1070 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
1071 *******************************************************************/
1072
1073 bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
1074                                 PRINTER_INFO_3 *info)
1075 {
1076
1077         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
1078
1079         /* allocate the necessary memory */
1080         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
1081                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
1082                 return False;
1083         }
1084         
1085         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
1086
1087         *spool_info3 = inf;
1088
1089         return True;
1090 }
1091
1092 /*******************************************************************
1093 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
1094 *******************************************************************/
1095
1096 bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
1097                                 PRINTER_INFO_7 *info)
1098 {
1099
1100         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
1101
1102         /* allocate the necessary memory */
1103         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
1104                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
1105                 return False;
1106         }
1107
1108         inf->guid_ptr = (info->guid.buffer!=NULL)?1:0;
1109         inf->action = info->action;
1110         init_unistr2_from_unistr(inf, &inf->guid, &info->guid);
1111
1112         *spool_info7 = inf;
1113
1114         return True;
1115 }
1116
1117
1118 /*******************************************************************
1119  * read a structure.
1120  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1121  ********************************************************************/
1122
1123 bool spoolss_io_q_open_printer(const char *desc, SPOOL_Q_OPEN_PRINTER *q_u, prs_struct *ps, int depth)
1124 {
1125         if (q_u == NULL)
1126                 return False;
1127
1128         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer");
1129         depth++;
1130
1131         if (!prs_align(ps))
1132                 return False;
1133
1134         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1135                 return False;
1136         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1137                 return False;
1138         
1139         if (!prs_align(ps))
1140                 return False;
1141
1142         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1143                 return False;
1144                 
1145         return True;
1146 }
1147
1148 /*******************************************************************
1149  * write a structure.
1150  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1151  * called from spoolss_open_printer_ex (cli_spoolss.c)
1152  ********************************************************************/
1153
1154 bool spoolss_io_r_open_printer(const char *desc, SPOOL_R_OPEN_PRINTER *r_u, prs_struct *ps, int depth)
1155 {
1156         if (r_u == NULL) return False;
1157
1158         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer");
1159         depth++;
1160         
1161         if (!prs_align(ps))
1162                 return False;
1163
1164         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1165                 return False;   
1166
1167         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1168                 return False;
1169                 
1170         return True;
1171 }
1172
1173
1174 /*******************************************************************
1175  * read a structure.
1176  * called from spoolss_q_open_printer_ex (srv_spoolss.c)
1177  ********************************************************************/
1178
1179 bool spoolss_io_q_open_printer_ex(const char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
1180 {
1181         if (q_u == NULL)
1182                 return False;
1183
1184         prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
1185         depth++;
1186
1187         if (!prs_align(ps))
1188                 return False;
1189
1190         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->printername))
1191                 return False;
1192         if (!prs_io_unistr2("printername", ps, depth, q_u->printername))
1193                 return False;
1194         
1195         if (!prs_align(ps))
1196                 return False;
1197
1198         if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
1199                 return False;
1200
1201         if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
1202                 return False;   
1203         if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
1204                 return False;
1205         
1206         return True;
1207 }
1208
1209 /*******************************************************************
1210  * write a structure.
1211  * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
1212  * called from spoolss_open_printer_ex (cli_spoolss.c)
1213  ********************************************************************/
1214
1215 bool spoolss_io_r_open_printer_ex(const char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
1216 {
1217         if (r_u == NULL) return False;
1218
1219         prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
1220         depth++;
1221         
1222         if (!prs_align(ps))
1223                 return False;
1224
1225         if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth))
1226                 return False;
1227
1228         if (!prs_werror("status code", ps, depth, &(r_u->status)))
1229                 return False;
1230
1231         return True;
1232 }
1233
1234 /*******************************************************************
1235  * init a structure.
1236  ********************************************************************/
1237 bool make_spoolss_q_deleteprinterdriverex( TALLOC_CTX *mem_ctx,
1238                                            SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, 
1239                                            const char *server,
1240                                            const char* arch, 
1241                                            const char* driver,
1242                                            int version)
1243 {
1244         DEBUG(5,("make_spoolss_q_deleteprinterdriverex\n"));
1245  
1246         q_u->server_ptr = (server!=NULL)?1:0;
1247         q_u->delete_flags = DPD_DELETE_UNUSED_FILES;
1248  
1249         /* these must be NULL terminated or else NT4 will
1250            complain about invalid parameters --jerry */
1251         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1252         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1253         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1254
1255         if (version >= 0) { 
1256                 q_u->delete_flags |= DPD_DELETE_SPECIFIC_VERSION;
1257                 q_u->version = version;
1258         }
1259
1260         return True;
1261 }
1262
1263
1264 /*******************************************************************
1265  * init a structure.
1266  ********************************************************************/
1267 bool make_spoolss_q_deleteprinterdriver(
1268         TALLOC_CTX *mem_ctx,
1269         SPOOL_Q_DELETEPRINTERDRIVER *q_u, 
1270         const char *server,
1271         const char* arch, 
1272         const char* driver 
1273 )
1274 {
1275         DEBUG(5,("make_spoolss_q_deleteprinterdriver\n"));
1276         
1277         q_u->server_ptr = (server!=NULL)?1:0;
1278
1279         /* these must be NULL terminated or else NT4 will
1280            complain about invalid parameters --jerry */
1281         init_unistr2(&q_u->server, server, UNI_STR_TERMINATE);
1282         init_unistr2(&q_u->arch, arch, UNI_STR_TERMINATE);
1283         init_unistr2(&q_u->driver, driver, UNI_STR_TERMINATE);
1284         
1285         return True;
1286 }
1287
1288 /*******************************************************************
1289  * make a structure.
1290  ********************************************************************/
1291
1292 bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
1293                                    const POLICY_HND *handle,
1294                                    const char *valuename, uint32 size)
1295 {
1296         if (q_u == NULL) return False;
1297
1298         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
1299
1300         q_u->handle = *handle;
1301         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1302         q_u->size = size;
1303
1304         return True;
1305 }
1306
1307 /*******************************************************************
1308  * make a structure.
1309  ********************************************************************/
1310
1311 bool make_spoolss_q_getprinterdataex(SPOOL_Q_GETPRINTERDATAEX *q_u,
1312                                      const POLICY_HND *handle,
1313                                      const char *keyname, 
1314                                      const char *valuename, uint32 size)
1315 {
1316         if (q_u == NULL) return False;
1317
1318         DEBUG(5,("make_spoolss_q_getprinterdataex\n"));
1319
1320         q_u->handle = *handle;
1321         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
1322         init_unistr2(&q_u->keyname, keyname, UNI_STR_TERMINATE);
1323         q_u->size = size;
1324
1325         return True;
1326 }
1327
1328 /*******************************************************************
1329  * read a structure.
1330  * called from spoolss_q_getprinterdata (srv_spoolss.c)
1331  ********************************************************************/
1332
1333 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
1334 {
1335         if (q_u == NULL)
1336                 return False;
1337
1338         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
1339         depth++;
1340
1341         if (!prs_align(ps))
1342                 return False;
1343         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1344                 return False;
1345         if (!prs_align(ps))
1346                 return False;
1347         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1348                 return False;
1349         if (!prs_align(ps))
1350                 return False;
1351         if (!prs_uint32("size", ps, depth, &q_u->size))
1352                 return False;
1353
1354         return True;
1355 }
1356
1357 /*******************************************************************
1358  * read a structure.
1359  * called from spoolss_q_deleteprinterdata (srv_spoolss.c)
1360  ********************************************************************/
1361
1362 bool spoolss_io_q_deleteprinterdata(const char *desc, SPOOL_Q_DELETEPRINTERDATA *q_u, prs_struct *ps, int depth)
1363 {
1364         if (q_u == NULL)
1365                 return False;
1366
1367         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdata");
1368         depth++;
1369
1370         if (!prs_align(ps))
1371                 return False;
1372         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1373                 return False;
1374         if (!prs_align(ps))
1375                 return False;
1376         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
1377                 return False;
1378
1379         return True;
1380 }
1381
1382 /*******************************************************************
1383  * write a structure.
1384  * called from spoolss_r_deleteprinterdata (srv_spoolss.c)
1385  ********************************************************************/
1386
1387 bool spoolss_io_r_deleteprinterdata(const char *desc, SPOOL_R_DELETEPRINTERDATA *r_u, prs_struct *ps, int depth)
1388 {
1389         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdata");
1390         depth++;
1391         if(!prs_werror("status", ps, depth, &r_u->status))
1392                 return False;
1393
1394         return True;
1395 }
1396
1397 /*******************************************************************
1398  * read a structure.
1399  * called from spoolss_q_deleteprinterdataex (srv_spoolss.c)
1400  ********************************************************************/
1401
1402 bool spoolss_io_q_deleteprinterdataex(const char *desc, SPOOL_Q_DELETEPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1403 {
1404         if (q_u == NULL)
1405                 return False;
1406
1407         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdataex");
1408         depth++;
1409
1410         if (!prs_align(ps))
1411                 return False;
1412         if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1413                 return False;
1414         
1415         if (!smb_io_unistr2("keyname  ", &q_u->keyname, True, ps, depth))
1416                 return False;
1417         if (!smb_io_unistr2("valuename", &q_u->valuename, True, ps, depth))
1418                 return False;
1419
1420         return True;
1421 }
1422
1423 /*******************************************************************
1424  * write a structure.
1425  * called from spoolss_r_deleteprinterdataex (srv_spoolss.c)
1426  ********************************************************************/
1427
1428 bool spoolss_io_r_deleteprinterdataex(const char *desc, SPOOL_R_DELETEPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1429 {
1430         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdataex");
1431         depth++;
1432         
1433         if(!prs_werror("status", ps, depth, &r_u->status))
1434                 return False;
1435
1436         return True;
1437 }
1438
1439 /*******************************************************************
1440  * write a structure.
1441  * called from spoolss_r_getprinterdata (srv_spoolss.c)
1442  ********************************************************************/
1443
1444 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
1445 {
1446         if (r_u == NULL)
1447                 return False;
1448
1449         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
1450         depth++;
1451
1452         if (!prs_align(ps))
1453                 return False;
1454         if (!prs_uint32("type", ps, depth, &r_u->type))
1455                 return False;
1456         if (!prs_uint32("size", ps, depth, &r_u->size))
1457                 return False;
1458         
1459         if (UNMARSHALLING(ps) && r_u->size) {
1460                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
1461                 if(!r_u->data)
1462                         return False;
1463         }
1464
1465         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
1466                 return False;
1467                 
1468         if (!prs_align(ps))
1469                 return False;
1470         
1471         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1472                 return False;
1473         if (!prs_werror("status", ps, depth, &r_u->status))
1474                 return False;
1475                 
1476         return True;
1477 }
1478
1479 /*******************************************************************
1480  * make a structure.
1481  ********************************************************************/
1482
1483 bool make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd)
1484 {
1485         if (q_u == NULL) return False;
1486
1487         DEBUG(5,("make_spoolss_q_closeprinter\n"));
1488
1489         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1490
1491         return True;
1492 }
1493
1494 /*******************************************************************
1495  * read a structure.
1496  * called from static spoolss_q_abortprinter (srv_spoolss.c)
1497  * called from spoolss_abortprinter (cli_spoolss.c)
1498  ********************************************************************/
1499
1500 bool spoolss_io_q_abortprinter(const char *desc, SPOOL_Q_ABORTPRINTER *q_u, prs_struct *ps, int depth)
1501 {
1502         if (q_u == NULL) return False;
1503
1504         prs_debug(ps, depth, desc, "spoolss_io_q_abortprinter");
1505         depth++;
1506
1507         if (!prs_align(ps))
1508                 return False;
1509
1510         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1511                 return False;
1512
1513         return True;
1514 }
1515
1516 /*******************************************************************
1517  * write a structure.
1518  * called from spoolss_r_abortprinter (srv_spoolss.c)
1519  ********************************************************************/
1520
1521 bool spoolss_io_r_abortprinter(const char *desc, SPOOL_R_ABORTPRINTER *r_u, prs_struct *ps, int depth)
1522 {
1523         prs_debug(ps, depth, desc, "spoolss_io_r_abortprinter");
1524         depth++;
1525         if(!prs_werror("status", ps, depth, &r_u->status))
1526                 return False;
1527
1528         return True;
1529 }
1530
1531 /*******************************************************************
1532  * read a structure.
1533  * called from static spoolss_q_deleteprinter (srv_spoolss.c)
1534  * called from spoolss_deleteprinter (cli_spoolss.c)
1535  ********************************************************************/
1536
1537 bool spoolss_io_q_deleteprinter(const char *desc, SPOOL_Q_DELETEPRINTER *q_u, prs_struct *ps, int depth)
1538 {
1539         if (q_u == NULL) return False;
1540
1541         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinter");
1542         depth++;
1543
1544         if (!prs_align(ps))
1545                 return False;
1546
1547         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1548                 return False;
1549
1550         return True;
1551 }
1552
1553 /*******************************************************************
1554  * write a structure.
1555  * called from static spoolss_r_deleteprinter (srv_spoolss.c)
1556  * called from spoolss_deleteprinter (cli_spoolss.c)
1557  ********************************************************************/
1558
1559 bool spoolss_io_r_deleteprinter(const char *desc, SPOOL_R_DELETEPRINTER *r_u, prs_struct *ps, int depth)
1560 {
1561         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinter");
1562         depth++;
1563         
1564         if (!prs_align(ps))
1565                 return False;
1566
1567         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1568                 return False;
1569         if (!prs_werror("status", ps, depth, &r_u->status))
1570                 return False;
1571         
1572         return True;
1573 }
1574
1575
1576 /*******************************************************************
1577  * read a structure.
1578  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1579  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1580  ********************************************************************/
1581
1582 bool spoolss_io_q_deleteprinterdriver(const char *desc, SPOOL_Q_DELETEPRINTERDRIVER *q_u, prs_struct *ps, int depth)
1583 {
1584         if (q_u == NULL) return False;
1585
1586         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriver");
1587         depth++;
1588
1589         if (!prs_align(ps))
1590                 return False;
1591
1592         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1593                 return False;           
1594         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1595                 return False;
1596         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1597                 return False;
1598         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1599                 return False;
1600
1601
1602         return True;
1603 }
1604
1605
1606 /*******************************************************************
1607  * write a structure.
1608  ********************************************************************/
1609 bool spoolss_io_r_deleteprinterdriver(const char *desc, SPOOL_R_DELETEPRINTERDRIVER *r_u, prs_struct *ps, int depth)
1610 {
1611         if (r_u == NULL) return False;
1612
1613         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriver");
1614         depth++;
1615
1616         if (!prs_align(ps))
1617                 return False;
1618
1619         if (!prs_werror("status", ps, depth, &r_u->status))
1620                 return False;
1621
1622         return True;
1623 }
1624
1625
1626 /*******************************************************************
1627  * read a structure.
1628  * called from api_spoolss_deleteprinterdriver (srv_spoolss.c)
1629  * called from spoolss_deleteprinterdriver (cli_spoolss.c)
1630  ********************************************************************/
1631
1632 bool spoolss_io_q_deleteprinterdriverex(const char *desc, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, prs_struct *ps, int depth)
1633 {
1634         if (q_u == NULL) return False;
1635
1636         prs_debug(ps, depth, desc, "spoolss_io_q_deleteprinterdriverex");
1637         depth++;
1638
1639         if (!prs_align(ps))
1640                 return False;
1641
1642         if(!prs_uint32("server_ptr", ps, depth, &q_u->server_ptr))
1643                 return False;           
1644         if(!smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth))
1645                 return False;
1646         if(!smb_io_unistr2("arch", &q_u->arch, True, ps, depth))
1647                 return False;
1648         if(!smb_io_unistr2("driver", &q_u->driver, True, ps, depth))
1649                 return False;
1650
1651         if (!prs_align(ps))
1652                 return False;
1653
1654         if(!prs_uint32("delete_flags ", ps, depth, &q_u->delete_flags))
1655                 return False;           
1656         if(!prs_uint32("version      ", ps, depth, &q_u->version))
1657                 return False;           
1658
1659
1660         return True;
1661 }
1662
1663
1664 /*******************************************************************
1665  * write a structure.
1666  ********************************************************************/
1667 bool spoolss_io_r_deleteprinterdriverex(const char *desc, SPOOL_R_DELETEPRINTERDRIVEREX *r_u, prs_struct *ps, int depth)
1668 {
1669         if (r_u == NULL) return False;
1670
1671         prs_debug(ps, depth, desc, "spoolss_io_r_deleteprinterdriverex");
1672         depth++;
1673
1674         if (!prs_align(ps))
1675                 return False;
1676
1677         if (!prs_werror("status", ps, depth, &r_u->status))
1678                 return False;
1679
1680         return True;
1681 }
1682
1683
1684
1685 /*******************************************************************
1686  * read a structure.
1687  * called from static spoolss_q_closeprinter (srv_spoolss.c)
1688  * called from spoolss_closeprinter (cli_spoolss.c)
1689  ********************************************************************/
1690
1691 bool spoolss_io_q_closeprinter(const char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth)
1692 {
1693         if (q_u == NULL) return False;
1694
1695         prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
1696         depth++;
1697
1698         if (!prs_align(ps))
1699                 return False;
1700
1701         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1702                 return False;
1703
1704         return True;
1705 }
1706
1707 /*******************************************************************
1708  * write a structure.
1709  * called from static spoolss_r_closeprinter (srv_spoolss.c)
1710  * called from spoolss_closeprinter (cli_spoolss.c)
1711  ********************************************************************/
1712
1713 bool spoolss_io_r_closeprinter(const char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth)
1714 {
1715         prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
1716         depth++;
1717         
1718         if (!prs_align(ps))
1719                 return False;
1720
1721         if (!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
1722                 return False;
1723         if (!prs_werror("status", ps, depth, &r_u->status))
1724                 return False;
1725         
1726         return True;
1727 }
1728
1729 /*******************************************************************
1730  * read a structure.
1731  * called from spoolss_q_startdocprinter (srv_spoolss.c)
1732  ********************************************************************/
1733
1734 bool spoolss_io_q_startdocprinter(const char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth)
1735 {
1736         if (q_u == NULL) return False;
1737
1738         prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter");
1739         depth++;
1740
1741         if(!prs_align(ps))
1742                 return False;
1743
1744         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1745                 return False;
1746         
1747         if(!smb_io_doc_info_container("",&q_u->doc_info_container, ps, depth))
1748                 return False;
1749
1750         return True;
1751 }
1752
1753 /*******************************************************************
1754  * write a structure.
1755  * called from spoolss_r_startdocprinter (srv_spoolss.c)
1756  ********************************************************************/
1757
1758 bool spoolss_io_r_startdocprinter(const char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth)
1759 {
1760         prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter");
1761         depth++;
1762         if(!prs_uint32("jobid", ps, depth, &r_u->jobid))
1763                 return False;
1764         if(!prs_werror("status", ps, depth, &r_u->status))
1765                 return False;
1766
1767         return True;
1768 }
1769
1770 /*******************************************************************
1771  * read a structure.
1772  * called from spoolss_q_enddocprinter (srv_spoolss.c)
1773  ********************************************************************/
1774
1775 bool spoolss_io_q_enddocprinter(const char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth)
1776 {
1777         if (q_u == NULL) return False;
1778
1779         prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter");
1780         depth++;
1781
1782         if(!prs_align(ps))
1783                 return False;
1784
1785         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1786                 return False;
1787
1788         return True;
1789 }
1790
1791 /*******************************************************************
1792  * write a structure.
1793  * called from spoolss_r_enddocprinter (srv_spoolss.c)
1794  ********************************************************************/
1795
1796 bool spoolss_io_r_enddocprinter(const char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth)
1797 {
1798         prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter");
1799         depth++;
1800         if(!prs_werror("status", ps, depth, &r_u->status))
1801                 return False;
1802
1803         return True;
1804 }
1805
1806 /*******************************************************************
1807  * read a structure.
1808  * called from spoolss_q_startpageprinter (srv_spoolss.c)
1809  ********************************************************************/
1810
1811 bool spoolss_io_q_startpageprinter(const char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth)
1812 {
1813         if (q_u == NULL) return False;
1814
1815         prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter");
1816         depth++;
1817
1818         if(!prs_align(ps))
1819                 return False;
1820
1821         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1822                 return False;
1823
1824         return True;
1825 }
1826
1827 /*******************************************************************
1828  * write a structure.
1829  * called from spoolss_r_startpageprinter (srv_spoolss.c)
1830  ********************************************************************/
1831
1832 bool spoolss_io_r_startpageprinter(const char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth)
1833 {
1834         prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter");
1835         depth++;
1836         if(!prs_werror("status", ps, depth, &r_u->status))
1837                 return False;
1838
1839         return True;
1840 }
1841
1842 /*******************************************************************
1843  * read a structure.
1844  * called from spoolss_q_endpageprinter (srv_spoolss.c)
1845  ********************************************************************/
1846
1847 bool spoolss_io_q_endpageprinter(const char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth)
1848 {
1849         if (q_u == NULL) return False;
1850
1851         prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter");
1852         depth++;
1853
1854         if(!prs_align(ps))
1855                 return False;
1856
1857         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1858                 return False;
1859
1860         return True;
1861 }
1862
1863 /*******************************************************************
1864  * write a structure.
1865  * called from spoolss_r_endpageprinter (srv_spoolss.c)
1866  ********************************************************************/
1867
1868 bool spoolss_io_r_endpageprinter(const char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth)
1869 {
1870         prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter");
1871         depth++;
1872         if(!prs_werror("status", ps, depth, &r_u->status))
1873                 return False;
1874
1875         return True;
1876 }
1877
1878 /*******************************************************************
1879  * read a structure.
1880  * called from spoolss_q_writeprinter (srv_spoolss.c)
1881  ********************************************************************/
1882
1883 bool spoolss_io_q_writeprinter(const char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth)
1884 {
1885         if (q_u == NULL) return False;
1886
1887         prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter");
1888         depth++;
1889
1890         if(!prs_align(ps))
1891                 return False;
1892
1893         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1894                 return False;
1895         if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size))
1896                 return False;
1897         
1898         if (q_u->buffer_size!=0)
1899         {
1900                 if (UNMARSHALLING(ps))
1901                         q_u->buffer=PRS_ALLOC_MEM(ps, uint8, q_u->buffer_size);
1902                 if(q_u->buffer == NULL)
1903                         return False;   
1904                 if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size))
1905                         return False;
1906         }
1907         if(!prs_align(ps))
1908                 return False;
1909         if(!prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2))
1910                 return False;
1911
1912         return True;
1913 }
1914
1915 /*******************************************************************
1916  * write a structure.
1917  * called from spoolss_r_writeprinter (srv_spoolss.c)
1918  ********************************************************************/
1919
1920 bool spoolss_io_r_writeprinter(const char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth)
1921 {
1922         prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter");
1923         depth++;
1924         if(!prs_uint32("buffer_written", ps, depth, &r_u->buffer_written))
1925                 return False;
1926         if(!prs_werror("status", ps, depth, &r_u->status))
1927                 return False;
1928
1929         return True;
1930 }
1931
1932 /*******************************************************************
1933  * read a structure.
1934  * called from spoolss_q_rffpcnex (srv_spoolss.c)
1935  ********************************************************************/
1936
1937 bool spoolss_io_q_rffpcnex(const char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
1938 {
1939         prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
1940         depth++;
1941
1942         if(!prs_align(ps))
1943                 return False;
1944
1945         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1946                 return False;
1947         if(!prs_uint32("flags", ps, depth, &q_u->flags))
1948                 return False;
1949         if(!prs_uint32("options", ps, depth, &q_u->options))
1950                 return False;
1951         if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
1952                 return False;
1953         if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
1954                 return False;
1955
1956         if(!prs_align(ps))
1957                 return False;
1958                 
1959         if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
1960                 return False;
1961
1962         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
1963                 return False;
1964         
1965         if (q_u->option_ptr!=0) {
1966         
1967                 if (UNMARSHALLING(ps))
1968                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
1969                                 return False;
1970         
1971                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
1972                         return False;
1973         }
1974         
1975         return True;
1976 }
1977
1978 /*******************************************************************
1979  * write a structure.
1980  * called from spoolss_r_rffpcnex (srv_spoolss.c)
1981  ********************************************************************/
1982
1983 bool spoolss_io_r_rffpcnex(const char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
1984 {
1985         prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
1986         depth++;
1987
1988         if(!prs_werror("status", ps, depth, &r_u->status))
1989                 return False;
1990
1991         return True;
1992 }
1993
1994 /*******************************************************************
1995  * read a structure.
1996  * called from spoolss_q_rfnpcnex (srv_spoolss.c)
1997  ********************************************************************/
1998
1999 bool spoolss_io_q_rfnpcnex(const char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
2000 {
2001         prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
2002         depth++;
2003
2004         if(!prs_align(ps))
2005                 return False;
2006
2007         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
2008                 return False;
2009
2010         if(!prs_uint32("change", ps, depth, &q_u->change))
2011                 return False;
2012         
2013         if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
2014                 return False;
2015         
2016         if (q_u->option_ptr!=0) {
2017         
2018                 if (UNMARSHALLING(ps))
2019                         if((q_u->option=PRS_ALLOC_MEM(ps,SPOOL_NOTIFY_OPTION,1)) == NULL)
2020                                 return False;
2021         
2022                 if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
2023                         return False;
2024         }
2025
2026         return True;
2027 }
2028
2029 /*******************************************************************
2030  * write a structure.
2031  * called from spoolss_r_rfnpcnex (srv_spoolss.c)
2032  ********************************************************************/
2033
2034 bool spoolss_io_r_rfnpcnex(const char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
2035 {
2036         prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
2037         depth++;
2038
2039         if(!prs_align(ps))
2040                 return False;
2041                 
2042         if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
2043                 return False;
2044
2045         if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
2046                 return False;
2047         
2048         if(!prs_align(ps))
2049                 return False;
2050         if(!prs_werror("status", ps, depth, &r_u->status))
2051                 return False;
2052
2053         return True;
2054 }
2055
2056 /*******************************************************************
2057  * return the length of a uint16 (obvious, but the code is clean)
2058  ********************************************************************/
2059
2060 static uint32 size_of_uint16(uint16 *value)
2061 {
2062         return (sizeof(*value));
2063 }
2064
2065 /*******************************************************************
2066  * return the length of a uint32 (obvious, but the code is clean)
2067  ********************************************************************/
2068
2069 static uint32 size_of_uint32(uint32 *value)
2070 {
2071         return (sizeof(*value));
2072 }
2073
2074 /*******************************************************************
2075  * return the length of a NTTIME (obvious, but the code is clean)
2076  ********************************************************************/
2077
2078 static uint32 size_of_nttime(NTTIME *value)
2079 {
2080         return (sizeof(*value));
2081 }
2082
2083 /*******************************************************************
2084  * return the length of a uint32 (obvious, but the code is clean)
2085  ********************************************************************/
2086
2087 static uint32 size_of_device_mode(DEVICEMODE *devmode)
2088 {
2089         if (devmode==NULL)
2090                 return (4);
2091         else 
2092                 return (4+devmode->size+devmode->driverextra);
2093 }
2094
2095 /*******************************************************************
2096  * return the length of a uint32 (obvious, but the code is clean)
2097  ********************************************************************/
2098
2099 static uint32 size_of_systemtime(SYSTEMTIME *systime)
2100 {
2101         if (systime==NULL)
2102                 return (4);
2103         else 
2104                 return (sizeof(SYSTEMTIME) +4);
2105 }
2106
2107 /*******************************************************************
2108  Parse a DEVMODE structure and its relative pointer.
2109 ********************************************************************/
2110
2111 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
2112 {
2113         prs_struct *ps=&buffer->prs;
2114
2115         prs_debug(ps, depth, desc, "smb_io_reldevmode");
2116         depth++;
2117
2118         if (MARSHALLING(ps)) {
2119                 uint32 struct_offset = prs_offset(ps);
2120                 uint32 relative_offset;
2121                 
2122                 if (*devmode == NULL) {
2123                         relative_offset=0;
2124                         if (!prs_uint32("offset", ps, depth, &relative_offset))
2125                                 return False;
2126                         DEBUG(8, ("boing, the devmode was NULL\n"));
2127                         
2128                         return True;
2129                 }
2130                 
2131                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
2132
2133                 /* mz:  we have to align the device mode for VISTA */
2134                 if (buffer->string_at_end % 4) {
2135                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
2136                 }
2137
2138                 if(!prs_set_offset(ps, buffer->string_at_end))
2139                         return False;
2140                 
2141                 /* write the DEVMODE */
2142                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2143                         return False;
2144
2145                 if(!prs_set_offset(ps, struct_offset))
2146                         return False;
2147                 
2148                 relative_offset=buffer->string_at_end - buffer->struct_start;
2149                 /* write its offset */
2150                 if (!prs_uint32("offset", ps, depth, &relative_offset))
2151                         return False;
2152         }
2153         else {
2154                 uint32 old_offset;
2155                 
2156                 /* read the offset */
2157                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
2158                         return False;
2159                 if (buffer->string_at_end == 0) {
2160                         *devmode = NULL;
2161                         return True;
2162                 }
2163
2164                 old_offset = prs_offset(ps);
2165                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
2166                         return False;
2167
2168                 /* read the string */
2169                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
2170                         return False;
2171                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
2172                         return False;
2173
2174                 if(!prs_set_offset(ps, old_offset))
2175                         return False;
2176         }
2177         return True;
2178 }
2179
2180 /*******************************************************************
2181  Parse a PRINTER_INFO_0 structure.
2182 ********************************************************************/  
2183
2184 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
2185 {
2186         prs_struct *ps=&buffer->prs;
2187
2188         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
2189         depth++;        
2190         
2191         buffer->struct_start=prs_offset(ps);
2192
2193         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2194                 return False;
2195         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2196                 return False;
2197         
2198         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
2199                 return False;
2200         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
2201                 return False;
2202         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
2203                 return False;
2204
2205         if(!prs_uint16("year", ps, depth, &info->year))
2206                 return False;
2207         if(!prs_uint16("month", ps, depth, &info->month))
2208                 return False;
2209         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
2210                 return False;
2211         if(!prs_uint16("day", ps, depth, &info->day))
2212                 return False;
2213         if(!prs_uint16("hour", ps, depth, &info->hour))
2214                 return False;
2215         if(!prs_uint16("minute", ps, depth, &info->minute))
2216                 return False;
2217         if(!prs_uint16("second", ps, depth, &info->second))
2218                 return False;
2219         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
2220                 return False;
2221
2222         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
2223                 return False;
2224         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
2225                 return False;
2226
2227         if(!prs_uint16("major_version", ps, depth, &info->major_version))
2228                 return False;
2229         if(!prs_uint16("build_version", ps, depth, &info->build_version))
2230                 return False;
2231         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
2232                 return False;
2233         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
2234                 return False;
2235         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
2236                 return False;
2237         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
2238                 return False;
2239         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
2240                 return False;
2241         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
2242                 return False;
2243         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
2244                 return False;
2245         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
2246                 return False;
2247         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
2248                 return False;
2249         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
2250                 return False;
2251         if(!prs_uint32("change_id", ps, depth, &info->change_id))
2252                 return False;
2253         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
2254                 return False;
2255         if(!prs_uint32("status"   , ps, depth, &info->status))
2256                 return False;
2257         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
2258                 return False;
2259         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
2260                 return False;
2261         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
2262                 return False;
2263         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
2264                 return False;
2265         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
2266                 return False;
2267         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
2268                 return False;
2269         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
2270                 return False;
2271         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
2272                 return False;
2273         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
2274                 return False;
2275         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
2276                 return False;
2277
2278         return True;
2279 }
2280
2281 /*******************************************************************
2282  Parse a PRINTER_INFO_1 structure.
2283 ********************************************************************/  
2284
2285 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
2286 {
2287         prs_struct *ps=&buffer->prs;
2288
2289         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
2290         depth++;        
2291         
2292         buffer->struct_start=prs_offset(ps);
2293
2294         if (!prs_uint32("flags", ps, depth, &info->flags))
2295                 return False;
2296         if (!smb_io_relstr("description", buffer, depth, &info->description))
2297                 return False;
2298         if (!smb_io_relstr("name", buffer, depth, &info->name))
2299                 return False;
2300         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2301                 return False;   
2302
2303         return True;
2304 }
2305
2306 /*******************************************************************
2307  Parse a PRINTER_INFO_2 structure.
2308 ********************************************************************/  
2309
2310 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
2311 {
2312         prs_struct *ps=&buffer->prs;
2313         uint32 dm_offset, sd_offset, current_offset;
2314         uint32 dummy_value = 0, has_secdesc = 0;
2315
2316         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
2317         depth++;        
2318         
2319         buffer->struct_start=prs_offset(ps);
2320         
2321         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2322                 return False;
2323         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2324                 return False;
2325         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
2326                 return False;
2327         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2328                 return False;
2329         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2330                 return False;
2331         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
2332                 return False;
2333         if (!smb_io_relstr("location", buffer, depth, &info->location))
2334                 return False;
2335
2336         /* save current offset and wind forwared by a uint32 */
2337         dm_offset = prs_offset(ps);
2338         if (!prs_uint32("devmode", ps, depth, &dummy_value))
2339                 return False;
2340         
2341         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
2342                 return False;
2343         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2344                 return False;
2345         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2346                 return False;
2347         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2348                 return False;
2349
2350         /* save current offset for the sec_desc */
2351         sd_offset = prs_offset(ps);
2352         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
2353                 return False;
2354
2355         
2356         /* save current location so we can pick back up here */
2357         current_offset = prs_offset(ps);
2358         
2359         /* parse the devmode */
2360         if (!prs_set_offset(ps, dm_offset))
2361                 return False;
2362         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2363                 return False;
2364         
2365         /* parse the sec_desc */
2366         if (info->secdesc) {
2367                 if (!prs_set_offset(ps, sd_offset))
2368                         return False;
2369                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
2370                         return False;
2371         }
2372
2373         /* pick up where we left off */
2374         if (!prs_set_offset(ps, current_offset))
2375                 return False;
2376
2377         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2378                 return False;
2379         if (!prs_uint32("priority", ps, depth, &info->priority))
2380                 return False;
2381         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
2382                 return False;
2383         if (!prs_uint32("starttime", ps, depth, &info->starttime))
2384                 return False;
2385         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
2386                 return False;
2387         if (!prs_uint32("status", ps, depth, &info->status))
2388                 return False;
2389         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
2390                 return False;
2391         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
2392                 return False;
2393
2394         return True;
2395 }
2396
2397 /*******************************************************************
2398  Parse a PRINTER_INFO_3 structure.
2399 ********************************************************************/  
2400
2401 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
2402 {
2403         uint32 offset = 0;
2404         prs_struct *ps=&buffer->prs;
2405
2406         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
2407         depth++;        
2408         
2409         buffer->struct_start=prs_offset(ps);
2410         
2411         if (MARSHALLING(ps)) {
2412                 /* Ensure the SD is 8 byte aligned in the buffer. */
2413                 uint32 start = prs_offset(ps); /* Remember the start position. */
2414                 uint32 off_val = 0;
2415
2416                 /* Write a dummy value. */
2417                 if (!prs_uint32("offset", ps, depth, &off_val))
2418                         return False;
2419
2420                 /* 8 byte align. */
2421                 if (!prs_align_uint64(ps))
2422                         return False;
2423
2424                 /* Remember where we must seek back to write the SD. */
2425                 offset = prs_offset(ps);
2426
2427                 /* Calculate the real offset for the SD. */
2428
2429                 off_val = offset - start;
2430
2431                 /* Seek back to where we store the SD offset & store. */
2432                 prs_set_offset(ps, start);
2433                 if (!prs_uint32("offset", ps, depth, &off_val))
2434                         return False;
2435
2436                 /* Return to after the 8 byte align. */
2437                 prs_set_offset(ps, offset);
2438
2439         } else {
2440                 if (!prs_uint32("offset", ps, depth, &offset))
2441                         return False;
2442                 /* Seek within the buffer. */
2443                 if (!prs_set_offset(ps, offset))
2444                         return False;
2445         }
2446         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
2447                 return False;
2448
2449         return True;
2450 }
2451
2452 /*******************************************************************
2453  Parse a PRINTER_INFO_4 structure.
2454 ********************************************************************/  
2455
2456 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
2457 {
2458         prs_struct *ps=&buffer->prs;
2459
2460         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
2461         depth++;        
2462         
2463         buffer->struct_start=prs_offset(ps);
2464         
2465         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2466                 return False;
2467         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
2468                 return False;
2469         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2470                 return False;
2471         return True;
2472 }
2473
2474 /*******************************************************************
2475  Parse a PRINTER_INFO_5 structure.
2476 ********************************************************************/  
2477
2478 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
2479 {
2480         prs_struct *ps=&buffer->prs;
2481
2482         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
2483         depth++;        
2484         
2485         buffer->struct_start=prs_offset(ps);
2486         
2487         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2488                 return False;
2489         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
2490                 return False;
2491         if (!prs_uint32("attributes", ps, depth, &info->attributes))
2492                 return False;
2493         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
2494                 return False;
2495         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
2496                 return False;
2497         return True;
2498 }
2499
2500 /*******************************************************************
2501  Parse a PRINTER_INFO_6 structure.
2502 ********************************************************************/  
2503
2504 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
2505                            PRINTER_INFO_6 *info, int depth)
2506 {
2507         prs_struct *ps=&buffer->prs;
2508
2509         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
2510         depth++;        
2511         
2512         if (!prs_uint32("status", ps, depth, &info->status))
2513                 return False;
2514
2515         return True;
2516 }
2517
2518 /*******************************************************************
2519  Parse a PRINTER_INFO_7 structure.
2520 ********************************************************************/  
2521
2522 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
2523 {
2524         prs_struct *ps=&buffer->prs;
2525
2526         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
2527         depth++;        
2528         
2529         buffer->struct_start=prs_offset(ps);
2530         
2531         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
2532                 return False;
2533         if (!prs_uint32("action", ps, depth, &info->action))
2534                 return False;
2535         return True;
2536 }
2537
2538 /*******************************************************************
2539  Parse a PORT_INFO_1 structure.
2540 ********************************************************************/  
2541
2542 bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2543 {
2544         prs_struct *ps=&buffer->prs;
2545
2546         prs_debug(ps, depth, desc, "smb_io_port_info_1");
2547         depth++;        
2548         
2549         buffer->struct_start=prs_offset(ps);
2550         
2551         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2552                 return False;
2553
2554         return True;
2555 }
2556
2557 /*******************************************************************
2558  Parse a PORT_INFO_2 structure.
2559 ********************************************************************/  
2560
2561 bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2562 {
2563         prs_struct *ps=&buffer->prs;
2564
2565         prs_debug(ps, depth, desc, "smb_io_port_info_2");
2566         depth++;        
2567         
2568         buffer->struct_start=prs_offset(ps);
2569         
2570         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2571                 return False;
2572         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2573                 return False;
2574         if (!smb_io_relstr("description", buffer, depth, &info->description))
2575                 return False;
2576         if (!prs_uint32("port_type", ps, depth, &info->port_type))
2577                 return False;
2578         if (!prs_uint32("reserved", ps, depth, &info->reserved))
2579                 return False;
2580
2581         return True;
2582 }
2583
2584 /*******************************************************************
2585  Parse a DRIVER_INFO_1 structure.
2586 ********************************************************************/
2587
2588 bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
2589 {
2590         prs_struct *ps=&buffer->prs;
2591
2592         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
2593         depth++;        
2594         
2595         buffer->struct_start=prs_offset(ps);
2596
2597         if (!smb_io_relstr("name", buffer, depth, &info->name))
2598                 return False;
2599
2600         return True;
2601 }
2602
2603 /*******************************************************************
2604  Parse a DRIVER_INFO_2 structure.
2605 ********************************************************************/
2606
2607 bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
2608 {
2609         prs_struct *ps=&buffer->prs;
2610
2611         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
2612         depth++;        
2613         
2614         buffer->struct_start=prs_offset(ps);
2615
2616         if (!prs_uint32("version", ps, depth, &info->version))
2617                 return False;
2618         if (!smb_io_relstr("name", buffer, depth, &info->name))
2619                 return False;
2620         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2621                 return False;
2622         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2623                 return False;
2624         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2625                 return False;
2626         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2627                 return False;
2628
2629         return True;
2630 }
2631
2632 /*******************************************************************
2633  Parse a DRIVER_INFO_3 structure.
2634 ********************************************************************/
2635
2636 bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
2637 {
2638         prs_struct *ps=&buffer->prs;
2639
2640         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
2641         depth++;        
2642         
2643         buffer->struct_start=prs_offset(ps);
2644
2645         if (!prs_uint32("version", ps, depth, &info->version))
2646                 return False;
2647         if (!smb_io_relstr("name", buffer, depth, &info->name))
2648                 return False;
2649         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2650                 return False;
2651         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2652                 return False;
2653         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2654                 return False;
2655         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2656                 return False;
2657         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2658                 return False;
2659
2660         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2661                 return False;
2662
2663         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2664                 return False;
2665         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2666                 return False;
2667
2668         return True;
2669 }
2670
2671 /*******************************************************************
2672  Parse a DRIVER_INFO_6 structure.
2673 ********************************************************************/
2674
2675 bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
2676 {
2677         prs_struct *ps=&buffer->prs;
2678
2679         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
2680         depth++;        
2681         
2682         buffer->struct_start=prs_offset(ps);
2683
2684         if (!prs_uint32("version", ps, depth, &info->version))
2685                 return False;
2686         if (!smb_io_relstr("name", buffer, depth, &info->name))
2687                 return False;
2688         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
2689                 return False;
2690         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
2691                 return False;
2692         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
2693                 return False;
2694         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
2695                 return False;
2696         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
2697                 return False;
2698
2699         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
2700                 return False;
2701
2702         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
2703                 return False;
2704         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
2705                 return False;
2706
2707         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
2708                 return False;
2709
2710         if (!prs_uint64("date", ps, depth, &info->driver_date))
2711                 return False;
2712
2713         if (!prs_uint32("padding", ps, depth, &info->padding))
2714                 return False;
2715
2716         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
2717                 return False;
2718
2719         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
2720                 return False;
2721
2722         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
2723                 return False;
2724         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
2725                 return False;
2726         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
2727                 return False;
2728         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
2729                 return False;
2730         
2731         return True;
2732 }
2733
2734 /*******************************************************************
2735  Parse a JOB_INFO_1 structure.
2736 ********************************************************************/  
2737
2738 bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
2739 {
2740         prs_struct *ps=&buffer->prs;
2741
2742         prs_debug(ps, depth, desc, "smb_io_job_info_1");
2743         depth++;        
2744         
2745         buffer->struct_start=prs_offset(ps);
2746
2747         if (!prs_uint32("jobid", ps, depth, &info->jobid))
2748                 return False;
2749         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2750                 return False;
2751         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2752                 return False;
2753         if (!smb_io_relstr("username", buffer, depth, &info->username))
2754                 return False;
2755         if (!smb_io_relstr("document", buffer, depth, &info->document))
2756                 return False;
2757         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2758                 return False;
2759         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2760                 return False;
2761         if (!prs_uint32("status", ps, depth, &info->status))
2762                 return False;
2763         if (!prs_uint32("priority", ps, depth, &info->priority))
2764                 return False;
2765         if (!prs_uint32("position", ps, depth, &info->position))
2766                 return False;
2767         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
2768                 return False;
2769         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
2770                 return False;
2771         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
2772                 return False;
2773
2774         return True;
2775 }
2776
2777 /*******************************************************************
2778  Parse a JOB_INFO_2 structure.
2779 ********************************************************************/  
2780
2781 bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
2782 {       
2783         uint32 pipo=0;
2784         prs_struct *ps=&buffer->prs;
2785         
2786         prs_debug(ps, depth, desc, "smb_io_job_info_2");
2787         depth++;        
2788
2789         buffer->struct_start=prs_offset(ps);
2790         
2791         if (!prs_uint32("jobid",ps, depth, &info->jobid))
2792                 return False;
2793         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
2794                 return False;
2795         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
2796                 return False;
2797         if (!smb_io_relstr("username", buffer, depth, &info->username))
2798                 return False;
2799         if (!smb_io_relstr("document", buffer, depth, &info->document))
2800                 return False;
2801         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
2802                 return False;
2803         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
2804                 return False;
2805
2806         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
2807                 return False;
2808         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
2809                 return False;
2810         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
2811                 return False;
2812         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
2813                 return False;
2814         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
2815                 return False;
2816
2817 /*      SEC_DESC sec_desc;*/
2818         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
2819                 return False;
2820
2821         if (!prs_uint32("status",ps, depth, &info->status))
2822                 return False;
2823         if (!prs_uint32("priority",ps, depth, &info->priority))
2824                 return False;
2825         if (!prs_uint32("position",ps, depth, &info->position)) 
2826                 return False;
2827         if (!prs_uint32("starttime",ps, depth, &info->starttime))
2828                 return False;
2829         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
2830                 return False;
2831         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
2832                 return False;
2833         if (!prs_uint32("size",ps, depth, &info->size))
2834                 return False;
2835         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
2836                 return False;
2837         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
2838                 return False;
2839         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
2840                 return False;
2841
2842         return True;
2843 }
2844
2845 /*******************************************************************
2846 ********************************************************************/  
2847
2848 bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
2849 {
2850         prs_struct *ps=&buffer->prs;
2851         
2852         prs_debug(ps, depth, desc, "smb_io_form_1");
2853         depth++;
2854                 
2855         buffer->struct_start=prs_offset(ps);
2856         
2857         if (!prs_uint32("flag", ps, depth, &info->flag))
2858                 return False;
2859                 
2860         if (!smb_io_relstr("name", buffer, depth, &info->name))
2861                 return False;
2862
2863         if (!prs_uint32("width", ps, depth, &info->width))
2864                 return False;
2865         if (!prs_uint32("length", ps, depth, &info->length))
2866                 return False;
2867         if (!prs_uint32("left", ps, depth, &info->left))
2868                 return False;
2869         if (!prs_uint32("top", ps, depth, &info->top))
2870                 return False;
2871         if (!prs_uint32("right", ps, depth, &info->right))
2872                 return False;
2873         if (!prs_uint32("bottom", ps, depth, &info->bottom))
2874                 return False;
2875
2876         return True;
2877 }
2878
2879
2880
2881 /*******************************************************************
2882  Parse a DRIVER_DIRECTORY_1 structure.
2883 ********************************************************************/  
2884
2885 bool smb_io_driverdir_1(const char *desc, RPC_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
2886 {
2887         prs_struct *ps=&buffer->prs;
2888
2889         prs_debug(ps, depth, desc, "smb_io_driverdir_1");
2890         depth++;
2891
2892         buffer->struct_start=prs_offset(ps);
2893
2894         if (!smb_io_unistr(desc, &info->name, ps, depth))
2895                 return False;
2896
2897         return True;
2898 }
2899
2900 /*******************************************************************
2901  Parse a PORT_INFO_1 structure.
2902 ********************************************************************/  
2903
2904 bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
2905 {
2906         prs_struct *ps=&buffer->prs;
2907
2908         prs_debug(ps, depth, desc, "smb_io_port_1");
2909         depth++;
2910
2911         buffer->struct_start=prs_offset(ps);
2912
2913         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2914                 return False;
2915
2916         return True;
2917 }
2918
2919 /*******************************************************************
2920  Parse a PORT_INFO_2 structure.
2921 ********************************************************************/  
2922
2923 bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
2924 {
2925         prs_struct *ps=&buffer->prs;
2926
2927         prs_debug(ps, depth, desc, "smb_io_port_2");
2928         depth++;
2929
2930         buffer->struct_start=prs_offset(ps);
2931
2932         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
2933                 return False;
2934         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
2935                 return False;
2936         if(!smb_io_relstr("description", buffer, depth, &info->description))
2937                 return False;
2938         if(!prs_uint32("port_type", ps, depth, &info->port_type))
2939                 return False;
2940         if(!prs_uint32("reserved", ps, depth, &info->reserved))
2941                 return False;
2942
2943         return True;
2944 }
2945
2946 /*******************************************************************
2947 ********************************************************************/  
2948
2949 bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
2950 {
2951         prs_struct *ps=&buffer->prs;
2952
2953         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
2954         depth++;        
2955
2956         buffer->struct_start=prs_offset(ps);
2957         
2958         if (smb_io_relstr("name", buffer, depth, &info->name))
2959                 return False;
2960
2961         return True;
2962 }
2963
2964 /*******************************************************************
2965 ********************************************************************/  
2966
2967 bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
2968 {
2969         prs_struct *ps=&buffer->prs;
2970
2971         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
2972         depth++;        
2973
2974         buffer->struct_start=prs_offset(ps);
2975         
2976         if (smb_io_relstr("name", buffer, depth, &info->name))
2977                 return False;
2978
2979         return True;
2980 }
2981
2982 /*******************************************************************
2983 ********************************************************************/  
2984
2985 bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
2986 {
2987         prs_struct *ps=&buffer->prs;
2988
2989         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
2990         depth++;        
2991
2992         buffer->struct_start=prs_offset(ps);
2993
2994         if (!smb_io_relstr("name", buffer, depth, &info->name))
2995                 return False;
2996
2997         return True;
2998 }
2999
3000 /*******************************************************************
3001 ********************************************************************/  
3002
3003 bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
3004 {
3005         prs_struct *ps=&buffer->prs;
3006
3007         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
3008         depth++;        
3009
3010         buffer->struct_start=prs_offset(ps);
3011
3012         if (!smb_io_relstr("name", buffer, depth, &info->name))
3013                 return False;
3014         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
3015                 return False;
3016         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
3017                 return False;
3018
3019         return True;
3020 }
3021
3022 /*******************************************************************
3023 return the size required by a struct in the stream
3024 ********************************************************************/  
3025
3026 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
3027 {
3028         int size=0;
3029         
3030         size+=size_of_relative_string( &info->printername );
3031         size+=size_of_relative_string( &info->servername );
3032
3033         size+=size_of_uint32( &info->cjobs);
3034         size+=size_of_uint32( &info->total_jobs);
3035         size+=size_of_uint32( &info->total_bytes);
3036
3037         size+=size_of_uint16( &info->year);
3038         size+=size_of_uint16( &info->month);
3039         size+=size_of_uint16( &info->dayofweek);
3040         size+=size_of_uint16( &info->day);
3041         size+=size_of_uint16( &info->hour);
3042         size+=size_of_uint16( &info->minute);
3043         size+=size_of_uint16( &info->second);
3044         size+=size_of_uint16( &info->milliseconds);
3045
3046         size+=size_of_uint32( &info->global_counter);
3047         size+=size_of_uint32( &info->total_pages);
3048
3049         size+=size_of_uint16( &info->major_version);
3050         size+=size_of_uint16( &info->build_version);
3051
3052         size+=size_of_uint32( &info->unknown7);
3053         size+=size_of_uint32( &info->unknown8);
3054         size+=size_of_uint32( &info->unknown9);
3055         size+=size_of_uint32( &info->session_counter);
3056         size+=size_of_uint32( &info->unknown11);
3057         size+=size_of_uint32( &info->printer_errors);
3058         size+=size_of_uint32( &info->unknown13);
3059         size+=size_of_uint32( &info->unknown14);
3060         size+=size_of_uint32( &info->unknown15);
3061         size+=size_of_uint32( &info->unknown16);
3062         size+=size_of_uint32( &info->change_id);
3063         size+=size_of_uint32( &info->unknown18);
3064         size+=size_of_uint32( &info->status);
3065         size+=size_of_uint32( &info->unknown20);
3066         size+=size_of_uint32( &info->c_setprinter);
3067         
3068         size+=size_of_uint16( &info->unknown22);
3069         size+=size_of_uint16( &info->unknown23);
3070         size+=size_of_uint16( &info->unknown24);
3071         size+=size_of_uint16( &info->unknown25);
3072         size+=size_of_uint16( &info->unknown26);
3073         size+=size_of_uint16( &info->unknown27);
3074         size+=size_of_uint16( &info->unknown28);
3075         size+=size_of_uint16( &info->unknown29);
3076         
3077         return size;
3078 }
3079
3080 /*******************************************************************
3081 return the size required by a struct in the stream
3082 ********************************************************************/  
3083
3084 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
3085 {
3086         int size=0;
3087                 
3088         size+=size_of_uint32( &info->flags );   
3089         size+=size_of_relative_string( &info->description );
3090         size+=size_of_relative_string( &info->name );
3091         size+=size_of_relative_string( &info->comment );
3092
3093         return size;
3094 }
3095
3096 /*******************************************************************
3097 return the size required by a struct in the stream
3098 ********************************************************************/
3099
3100 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
3101 {
3102         uint32 size=0;
3103                 
3104         size += 4;
3105         
3106         size += ndr_size_security_descriptor( info->secdesc, 0 );
3107
3108         size+=size_of_device_mode( info->devmode );
3109         
3110         size+=size_of_relative_string( &info->servername );
3111         size+=size_of_relative_string( &info->printername );
3112         size+=size_of_relative_string( &info->sharename );
3113         size+=size_of_relative_string( &info->portname );
3114         size+=size_of_relative_string( &info->drivername );
3115         size+=size_of_relative_string( &info->comment );
3116         size+=size_of_relative_string( &info->location );
3117         
3118         size+=size_of_relative_string( &info->sepfile );
3119         size+=size_of_relative_string( &info->printprocessor );
3120         size+=size_of_relative_string( &info->datatype );
3121         size+=size_of_relative_string( &info->parameters );
3122
3123         size+=size_of_uint32( &info->attributes );
3124         size+=size_of_uint32( &info->priority );
3125         size+=size_of_uint32( &info->defaultpriority );
3126         size+=size_of_uint32( &info->starttime );
3127         size+=size_of_uint32( &info->untiltime );
3128         size+=size_of_uint32( &info->status );
3129         size+=size_of_uint32( &info->cjobs );
3130         size+=size_of_uint32( &info->averageppm );      
3131                 
3132         /* 
3133          * add any adjustments for alignment.  This is
3134          * not optimal since we could be calling this
3135          * function from a loop (e.g. enumprinters), but 
3136          * it is easier to maintain the calculation here and
3137          * not place the burden on the caller to remember.   --jerry
3138          */
3139         if ((size % 4) != 0)
3140                 size += 4 - (size % 4);
3141         
3142         return size;
3143 }
3144
3145 /*******************************************************************
3146 return the size required by a struct in the stream
3147 ********************************************************************/
3148
3149 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
3150 {
3151         uint32 size=0;
3152                 
3153         size+=size_of_relative_string( &info->printername );
3154         size+=size_of_relative_string( &info->servername );
3155
3156         size+=size_of_uint32( &info->attributes );
3157         return size;
3158 }
3159
3160 /*******************************************************************
3161 return the size required by a struct in the stream
3162 ********************************************************************/
3163
3164 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
3165 {
3166         uint32 size=0;
3167                 
3168         size+=size_of_relative_string( &info->printername );
3169         size+=size_of_relative_string( &info->portname );
3170
3171         size+=size_of_uint32( &info->attributes );
3172         size+=size_of_uint32( &info->device_not_selected_timeout );
3173         size+=size_of_uint32( &info->transmission_retry_timeout );
3174         return size;
3175 }
3176
3177 /*******************************************************************
3178 return the size required by a struct in the stream
3179 ********************************************************************/
3180
3181 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
3182 {
3183         return sizeof(uint32);
3184 }
3185
3186 /*******************************************************************
3187 return the size required by a struct in the stream
3188 ********************************************************************/
3189
3190 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
3191 {
3192         /* The 8 is for the self relative pointer - 8 byte aligned.. */
3193         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, 0 );
3194 }
3195
3196 /*******************************************************************
3197 return the size required by a struct in the stream
3198 ********************************************************************/
3199
3200 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
3201 {
3202         uint32 size=0;
3203                 
3204         size+=size_of_relative_string( &info->guid );
3205         size+=size_of_uint32( &info->action );
3206         return size;
3207 }
3208
3209 /*******************************************************************
3210 return the size required by a struct in the stream
3211 ********************************************************************/
3212
3213 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
3214 {
3215         int size=0;
3216         size+=size_of_relative_string( &info->name );
3217
3218         return size;
3219 }
3220
3221 /*******************************************************************
3222 return the size required by a struct in the stream
3223 ********************************************************************/
3224
3225 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
3226 {
3227         int size=0;
3228         size+=size_of_uint32( &info->version ); 
3229         size+=size_of_relative_string( &info->name );
3230         size+=size_of_relative_string( &info->architecture );
3231         size+=size_of_relative_string( &info->driverpath );
3232         size+=size_of_relative_string( &info->datafile );
3233         size+=size_of_relative_string( &info->configfile );
3234
3235         return size;
3236 }
3237
3238 /*******************************************************************
3239 return the size required by a string array.
3240 ********************************************************************/
3241
3242 uint32 spoolss_size_string_array(uint16 *string)
3243 {
3244         uint32 i = 0;
3245
3246         if (string) {
3247                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
3248         }
3249         i=i+2; /* to count all chars including the leading zero */
3250         i=2*i; /* because we need the value in bytes */
3251         i=i+4; /* the offset pointer size */
3252
3253         return i;
3254 }
3255
3256 /*******************************************************************
3257 return the size required by a struct in the stream
3258 ********************************************************************/
3259
3260 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
3261 {
3262         int size=0;
3263
3264         size+=size_of_uint32( &info->version ); 
3265         size+=size_of_relative_string( &info->name );
3266         size+=size_of_relative_string( &info->architecture );
3267         size+=size_of_relative_string( &info->driverpath );
3268         size+=size_of_relative_string( &info->datafile );
3269         size+=size_of_relative_string( &info->configfile );
3270         size+=size_of_relative_string( &info->helpfile );
3271         size+=size_of_relative_string( &info->monitorname );
3272         size+=size_of_relative_string( &info->defaultdatatype );
3273         
3274         size+=spoolss_size_string_array(info->dependentfiles);
3275
3276         return size;
3277 }
3278
3279 /*******************************************************************
3280 return the size required by a struct in the stream
3281 ********************************************************************/
3282
3283 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
3284 {
3285         uint32 size=0;
3286
3287         size+=size_of_uint32( &info->version ); 
3288         size+=size_of_relative_string( &info->name );
3289         size+=size_of_relative_string( &info->architecture );
3290         size+=size_of_relative_string( &info->driverpath );
3291         size+=size_of_relative_string( &info->datafile );
3292         size+=size_of_relative_string( &info->configfile );
3293         size+=size_of_relative_string( &info->helpfile );
3294
3295         size+=spoolss_size_string_array(info->dependentfiles);
3296
3297         size+=size_of_relative_string( &info->monitorname );
3298         size+=size_of_relative_string( &info->defaultdatatype );
3299         
3300         size+=spoolss_size_string_array(info->previousdrivernames);
3301
3302         size+=size_of_nttime(&info->driver_date);
3303         size+=size_of_uint32( &info->padding ); 
3304         size+=size_of_uint32( &info->driver_version_low );      
3305         size+=size_of_uint32( &info->driver_version_high );     
3306         size+=size_of_relative_string( &info->mfgname );
3307         size+=size_of_relative_string( &info->oem_url );
3308         size+=size_of_relative_string( &info->hardware_id );
3309         size+=size_of_relative_string( &info->provider );
3310
3311         return size;
3312 }
3313
3314 /*******************************************************************
3315 return the size required by a struct in the stream
3316 ********************************************************************/  
3317
3318 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
3319 {
3320         int size=0;
3321         size+=size_of_uint32( &info->jobid );
3322         size+=size_of_relative_string( &info->printername );
3323         size+=size_of_relative_string( &info->machinename );
3324         size+=size_of_relative_string( &info->username );
3325         size+=size_of_relative_string( &info->document );
3326         size+=size_of_relative_string( &info->datatype );
3327         size+=size_of_relative_string( &info->text_status );
3328         size+=size_of_uint32( &info->status );
3329         size+=size_of_uint32( &info->priority );
3330         size+=size_of_uint32( &info->position );
3331         size+=size_of_uint32( &info->totalpages );
3332         size+=size_of_uint32( &info->pagesprinted );
3333         size+=size_of_systemtime( &info->submitted );
3334
3335         return size;
3336 }
3337
3338 /*******************************************************************
3339 return the size required by a struct in the stream
3340 ********************************************************************/  
3341
3342 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
3343 {
3344         int size=0;
3345
3346         size+=4; /* size of sec desc ptr */
3347
3348         size+=size_of_uint32( &info->jobid );
3349         size+=size_of_relative_string( &info->printername );
3350         size+=size_of_relative_string( &info->machinename );
3351         size+=size_of_relative_string( &info->username );
3352         size+=size_of_relative_string( &info->document );
3353         size+=size_of_relative_string( &info->notifyname );
3354         size+=size_of_relative_string( &info->datatype );
3355         size+=size_of_relative_string( &info->printprocessor );
3356         size+=size_of_relative_string( &info->parameters );
3357         size+=size_of_relative_string( &info->drivername );
3358         size+=size_of_device_mode( info->devmode );
3359         size+=size_of_relative_string( &info->text_status );
3360 /*      SEC_DESC sec_desc;*/
3361         size+=size_of_uint32( &info->status );
3362         size+=size_of_uint32( &info->priority );
3363         size+=size_of_uint32( &info->position );
3364         size+=size_of_uint32( &info->starttime );
3365         size+=size_of_uint32( &info->untiltime );
3366         size+=size_of_uint32( &info->totalpages );
3367         size+=size_of_uint32( &info->size );
3368         size+=size_of_systemtime( &info->submitted );
3369         size+=size_of_uint32( &info->timeelapsed );
3370         size+=size_of_uint32( &info->pagesprinted );
3371
3372         return size;
3373 }
3374
3375 /*******************************************************************
3376 return the size required by a struct in the stream
3377 ********************************************************************/
3378
3379 uint32 spoolss_size_form_1(FORM_1 *info)
3380 {
3381         int size=0;
3382
3383         size+=size_of_uint32( &info->flag );
3384         size+=size_of_relative_string( &info->name );
3385         size+=size_of_uint32( &info->width );
3386         size+=size_of_uint32( &info->length );
3387         size+=size_of_uint32( &info->left );
3388         size+=size_of_uint32( &info->top );
3389         size+=size_of_uint32( &info->right );
3390         size+=size_of_uint32( &info->bottom );
3391
3392         return size;
3393 }
3394
3395 /*******************************************************************
3396 return the size required by a struct in the stream
3397 ********************************************************************/  
3398
3399 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
3400 {
3401         int size=0;
3402
3403         size+=size_of_relative_string( &info->port_name );
3404
3405         return size;
3406 }
3407
3408 /*******************************************************************
3409 return the size required by a struct in the stream
3410 ********************************************************************/  
3411
3412 uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
3413 {
3414         int size=0;
3415
3416         size=str_len_uni(&info->name);  /* the string length       */
3417         size=size+1;                    /* add the leading zero    */
3418         size=size*2;                    /* convert in char         */
3419
3420         return size;
3421 }
3422
3423 /*******************************************************************
3424 return the size required by a struct in the stream
3425 ********************************************************************/  
3426
3427 uint32 spoolss_size_printprocessordirectory_info_1(PRINTPROCESSOR_DIRECTORY_1 *info)
3428 {
3429         int size=0;
3430
3431         size=str_len_uni(&info->name);  /* the string length       */
3432         size=size+1;                    /* add the leading zero    */
3433         size=size*2;                    /* convert in char         */
3434
3435         return size;
3436 }
3437
3438 /*******************************************************************
3439 return the size required by a struct in the stream
3440 ********************************************************************/  
3441
3442 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
3443 {
3444         int size=0;
3445
3446         size+=size_of_relative_string( &info->port_name );
3447         size+=size_of_relative_string( &info->monitor_name );
3448         size+=size_of_relative_string( &info->description );
3449
3450         size+=size_of_uint32( &info->port_type );
3451         size+=size_of_uint32( &info->reserved );
3452
3453         return size;
3454 }
3455
3456 /*******************************************************************
3457 return the size required by a struct in the stream
3458 ********************************************************************/  
3459
3460 uint32 spoolss_size_printprocessor_info_1(PRINTPR