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