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