s3-spoolss: remove old rpccli_spoolss_enumprinterdrivers wrapper.
[ira/wip.git] / source3 / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000,
7  *  Copyright (C) Gerald Carter                2000-2002,
8  *  Copyright (C) Tim Potter                   2001-2002.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 3 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29
30 /*******************************************************************
31 This should be moved in a more generic lib.
32 ********************************************************************/  
33
34 bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
35 {
36         if(!prs_uint16("year", ps, depth, &systime->year))
37                 return False;
38         if(!prs_uint16("month", ps, depth, &systime->month))
39                 return False;
40         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
41                 return False;
42         if(!prs_uint16("day", ps, depth, &systime->day))
43                 return False;
44         if(!prs_uint16("hour", ps, depth, &systime->hour))
45                 return False;
46         if(!prs_uint16("minute", ps, depth, &systime->minute))
47                 return False;
48         if(!prs_uint16("second", ps, depth, &systime->second))
49                 return False;
50         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
51                 return False;
52
53         return True;
54 }
55
56 /*******************************************************************
57 ********************************************************************/  
58
59 bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
60 {
61         systime->year=unixtime->tm_year+1900;
62         systime->month=unixtime->tm_mon+1;
63         systime->dayofweek=unixtime->tm_wday;
64         systime->day=unixtime->tm_mday;
65         systime->hour=unixtime->tm_hour;
66         systime->minute=unixtime->tm_min;
67         systime->second=unixtime->tm_sec;
68         systime->milliseconds=0;
69
70         return True;
71 }
72
73 /*******************************************************************
74  * read or write a DEVICEMODE struct.
75  * on reading allocate memory for the private member
76  ********************************************************************/
77
78 #define DM_NUM_OPTIONAL_FIELDS          8
79
80 bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
81 {
82         int available_space;            /* size of the device mode left to parse */
83                                         /* only important on unmarshalling       */
84         int i = 0;
85         uint16 *unistr_buffer;
86         int j;
87                                         
88         struct optional_fields {
89                 fstring         name;
90                 uint32*         field;
91         } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
92                 { "icmmethod",          NULL },
93                 { "icmintent",          NULL },
94                 { "mediatype",          NULL },
95                 { "dithertype",         NULL },
96                 { "reserved1",          NULL },
97                 { "reserved2",          NULL },
98                 { "panningwidth",       NULL },
99                 { "panningheight",      NULL }
100         };
101
102         /* assign at run time to keep non-gcc compilers happy */
103
104         opt_fields[0].field = &devmode->icmmethod;
105         opt_fields[1].field = &devmode->icmintent;
106         opt_fields[2].field = &devmode->mediatype;
107         opt_fields[3].field = &devmode->dithertype;
108         opt_fields[4].field = &devmode->reserved1;
109         opt_fields[5].field = &devmode->reserved2;
110         opt_fields[6].field = &devmode->panningwidth;
111         opt_fields[7].field = &devmode->panningheight;
112                 
113         
114         prs_debug(ps, depth, desc, "spoolss_io_devmode");
115         depth++;
116
117         if (UNMARSHALLING(ps)) {
118                 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
119                 if (devmode->devicename.buffer == NULL)
120                         return False;
121                 unistr_buffer = devmode->devicename.buffer;
122         }
123         else {
124                 /* devicename is a static sized string but the buffer we set is not */
125                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
126                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
127                 for ( j=0; devmode->devicename.buffer[j]; j++ )
128                         unistr_buffer[j] = devmode->devicename.buffer[j];
129         }
130                 
131         if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
132                 return False;
133         
134         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
135                 return False;
136                 
137         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
138                 return False;
139         if (!prs_uint16("size",             ps, depth, &devmode->size))
140                 return False;
141         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
142                 return False;
143         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
144                 return False;
145         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
146                 return False;
147         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
148                 return False;
149         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
150                 return False;
151         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
152                 return False;
153         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
154                 return False;
155         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
156                 return False;
157         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
158                 return False;
159         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
160                 return False;
161         if (!prs_uint16("color",            ps, depth, &devmode->color))
162                 return False;
163         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
164                 return False;
165         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
166                 return False;
167         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
168                 return False;
169         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
170                 return False;
171
172         if (UNMARSHALLING(ps)) {
173                 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
174                 if (devmode->formname.buffer == NULL)
175                         return False;
176                 unistr_buffer = devmode->formname.buffer;
177         }
178         else {
179                 /* devicename is a static sized string but the buffer we set is not */
180                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
181                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
182                 for ( j=0; devmode->formname.buffer[j]; j++ )
183                         unistr_buffer[j] = devmode->formname.buffer[j];
184         }
185         
186         if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
187                 return False;
188         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
189                 return False;
190         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
191                 return False;
192         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
193                 return False;
194         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
195                 return False;
196         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
197                 return False;
198         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
199                 return False;
200         /* 
201          * every device mode I've ever seen on the wire at least has up 
202          * to the displayfrequency field.   --jerry (05-09-2002)
203          */
204          
205         /* add uint32's + uint16's + two UNICODE strings */
206          
207         available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
208         
209         /* Sanity check - we only have uint32's left tp parse */
210         
211         if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
212                 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
213                         available_space, devmode->size));
214                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
215                 return False;
216         }
217
218         /* 
219          * Conditional parsing.  Assume that the DeviceMode has been 
220          * zero'd by the caller. 
221          */
222         
223         while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
224         {
225                 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
226                 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
227                         return False;
228                 available_space -= sizeof(uint32);
229                 i++;
230         }        
231         
232         /* Sanity Check - we should no available space at this point unless 
233            MS changes the device mode structure */
234                 
235         if (available_space) {
236                 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
237                 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
238                         available_space, devmode->size));
239                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
240                 return False;
241         }
242
243
244         if (devmode->driverextra!=0) {
245                 if (UNMARSHALLING(ps)) {
246                         devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
247                         if(devmode->dev_private == NULL)
248                                 return False;
249                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
250                 }
251                         
252                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
253                 if (!prs_uint8s(False, "dev_private",  ps, depth,
254                                 devmode->dev_private, devmode->driverextra))
255                         return False;
256         }
257
258         return True;
259 }
260
261 /*******************************************************************
262  * make a structure.
263  ********************************************************************/
264
265 bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
266                                    const POLICY_HND *handle,
267                                    const char *valuename, uint32 size)
268 {
269         if (q_u == NULL) return False;
270
271         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
272
273         q_u->handle = *handle;
274         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
275         q_u->size = size;
276
277         return True;
278 }
279
280 /*******************************************************************
281  * read a structure.
282  * called from spoolss_q_getprinterdata (srv_spoolss.c)
283  ********************************************************************/
284
285 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
286 {
287         if (q_u == NULL)
288                 return False;
289
290         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
291         depth++;
292
293         if (!prs_align(ps))
294                 return False;
295         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
296                 return False;
297         if (!prs_align(ps))
298                 return False;
299         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
300                 return False;
301         if (!prs_align(ps))
302                 return False;
303         if (!prs_uint32("size", ps, depth, &q_u->size))
304                 return False;
305
306         return True;
307 }
308
309 /*******************************************************************
310  * write a structure.
311  * called from spoolss_r_getprinterdata (srv_spoolss.c)
312  ********************************************************************/
313
314 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
315 {
316         if (r_u == NULL)
317                 return False;
318
319         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
320         depth++;
321
322         if (!prs_align(ps))
323                 return False;
324         if (!prs_uint32("type", ps, depth, &r_u->type))
325                 return False;
326         if (!prs_uint32("size", ps, depth, &r_u->size))
327                 return False;
328         
329         if (UNMARSHALLING(ps) && r_u->size) {
330                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
331                 if(!r_u->data)
332                         return False;
333         }
334
335         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
336                 return False;
337                 
338         if (!prs_align(ps))
339                 return False;
340         
341         if (!prs_uint32("needed", ps, depth, &r_u->needed))
342                 return False;
343         if (!prs_werror("status", ps, depth, &r_u->status))
344                 return False;
345                 
346         return True;
347 }
348
349 /*******************************************************************
350  * return the length of a uint16 (obvious, but the code is clean)
351  ********************************************************************/
352
353 static uint32 size_of_uint16(uint16 *value)
354 {
355         return (sizeof(*value));
356 }
357
358 /*******************************************************************
359  * return the length of a uint32 (obvious, but the code is clean)
360  ********************************************************************/
361
362 static uint32 size_of_uint32(uint32 *value)
363 {
364         return (sizeof(*value));
365 }
366
367 /*******************************************************************
368  * return the length of a NTTIME (obvious, but the code is clean)
369  ********************************************************************/
370
371 static uint32 size_of_nttime(NTTIME *value)
372 {
373         return (sizeof(*value));
374 }
375
376 /*******************************************************************
377  * return the length of a uint32 (obvious, but the code is clean)
378  ********************************************************************/
379
380 static uint32 size_of_device_mode(DEVICEMODE *devmode)
381 {
382         if (devmode==NULL)
383                 return (4);
384         else 
385                 return (4+devmode->size+devmode->driverextra);
386 }
387
388 /*******************************************************************
389  Parse a DEVMODE structure and its relative pointer.
390 ********************************************************************/
391
392 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
393 {
394         prs_struct *ps=&buffer->prs;
395
396         prs_debug(ps, depth, desc, "smb_io_reldevmode");
397         depth++;
398
399         if (MARSHALLING(ps)) {
400                 uint32 struct_offset = prs_offset(ps);
401                 uint32 relative_offset;
402                 
403                 if (*devmode == NULL) {
404                         relative_offset=0;
405                         if (!prs_uint32("offset", ps, depth, &relative_offset))
406                                 return False;
407                         DEBUG(8, ("boing, the devmode was NULL\n"));
408                         
409                         return True;
410                 }
411                 
412                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
413
414                 /* mz:  we have to align the device mode for VISTA */
415                 if (buffer->string_at_end % 4) {
416                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
417                 }
418
419                 if(!prs_set_offset(ps, buffer->string_at_end))
420                         return False;
421                 
422                 /* write the DEVMODE */
423                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
424                         return False;
425
426                 if(!prs_set_offset(ps, struct_offset))
427                         return False;
428                 
429                 relative_offset=buffer->string_at_end - buffer->struct_start;
430                 /* write its offset */
431                 if (!prs_uint32("offset", ps, depth, &relative_offset))
432                         return False;
433         }
434         else {
435                 uint32 old_offset;
436                 
437                 /* read the offset */
438                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
439                         return False;
440                 if (buffer->string_at_end == 0) {
441                         *devmode = NULL;
442                         return True;
443                 }
444
445                 old_offset = prs_offset(ps);
446                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
447                         return False;
448
449                 /* read the string */
450                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
451                         return False;
452                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
453                         return False;
454
455                 if(!prs_set_offset(ps, old_offset))
456                         return False;
457         }
458         return True;
459 }
460
461 /*******************************************************************
462  Parse a PRINTER_INFO_0 structure.
463 ********************************************************************/  
464
465 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
466 {
467         prs_struct *ps=&buffer->prs;
468
469         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
470         depth++;        
471         
472         buffer->struct_start=prs_offset(ps);
473
474         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
475                 return False;
476         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
477                 return False;
478         
479         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
480                 return False;
481         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
482                 return False;
483         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
484                 return False;
485
486         if(!prs_uint16("year", ps, depth, &info->year))
487                 return False;
488         if(!prs_uint16("month", ps, depth, &info->month))
489                 return False;
490         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
491                 return False;
492         if(!prs_uint16("day", ps, depth, &info->day))
493                 return False;
494         if(!prs_uint16("hour", ps, depth, &info->hour))
495                 return False;
496         if(!prs_uint16("minute", ps, depth, &info->minute))
497                 return False;
498         if(!prs_uint16("second", ps, depth, &info->second))
499                 return False;
500         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
501                 return False;
502
503         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
504                 return False;
505         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
506                 return False;
507
508         if(!prs_uint16("major_version", ps, depth, &info->major_version))
509                 return False;
510         if(!prs_uint16("build_version", ps, depth, &info->build_version))
511                 return False;
512         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
513                 return False;
514         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
515                 return False;
516         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
517                 return False;
518         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
519                 return False;
520         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
521                 return False;
522         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
523                 return False;
524         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
525                 return False;
526         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
527                 return False;
528         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
529                 return False;
530         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
531                 return False;
532         if(!prs_uint32("change_id", ps, depth, &info->change_id))
533                 return False;
534         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
535                 return False;
536         if(!prs_uint32("status"   , ps, depth, &info->status))
537                 return False;
538         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
539                 return False;
540         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
541                 return False;
542         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
543                 return False;
544         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
545                 return False;
546         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
547                 return False;
548         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
549                 return False;
550         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
551                 return False;
552         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
553                 return False;
554         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
555                 return False;
556         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
557                 return False;
558
559         return True;
560 }
561
562 /*******************************************************************
563  Parse a PRINTER_INFO_1 structure.
564 ********************************************************************/  
565
566 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
567 {
568         prs_struct *ps=&buffer->prs;
569
570         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
571         depth++;        
572         
573         buffer->struct_start=prs_offset(ps);
574
575         if (!prs_uint32("flags", ps, depth, &info->flags))
576                 return False;
577         if (!smb_io_relstr("description", buffer, depth, &info->description))
578                 return False;
579         if (!smb_io_relstr("name", buffer, depth, &info->name))
580                 return False;
581         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
582                 return False;   
583
584         return True;
585 }
586
587 /*******************************************************************
588  Parse a PRINTER_INFO_2 structure.
589 ********************************************************************/  
590
591 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
592 {
593         prs_struct *ps=&buffer->prs;
594         uint32 dm_offset, sd_offset, current_offset;
595         uint32 dummy_value = 0, has_secdesc = 0;
596
597         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
598         depth++;        
599         
600         buffer->struct_start=prs_offset(ps);
601         
602         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
603                 return False;
604         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
605                 return False;
606         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
607                 return False;
608         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
609                 return False;
610         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
611                 return False;
612         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
613                 return False;
614         if (!smb_io_relstr("location", buffer, depth, &info->location))
615                 return False;
616
617         /* save current offset and wind forwared by a uint32 */
618         dm_offset = prs_offset(ps);
619         if (!prs_uint32("devmode", ps, depth, &dummy_value))
620                 return False;
621         
622         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
623                 return False;
624         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
625                 return False;
626         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
627                 return False;
628         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
629                 return False;
630
631         /* save current offset for the sec_desc */
632         sd_offset = prs_offset(ps);
633         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
634                 return False;
635
636         
637         /* save current location so we can pick back up here */
638         current_offset = prs_offset(ps);
639         
640         /* parse the devmode */
641         if (!prs_set_offset(ps, dm_offset))
642                 return False;
643         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
644                 return False;
645         
646         /* parse the sec_desc */
647         if (info->secdesc) {
648                 if (!prs_set_offset(ps, sd_offset))
649                         return False;
650                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
651                         return False;
652         }
653
654         /* pick up where we left off */
655         if (!prs_set_offset(ps, current_offset))
656                 return False;
657
658         if (!prs_uint32("attributes", ps, depth, &info->attributes))
659                 return False;
660         if (!prs_uint32("priority", ps, depth, &info->priority))
661                 return False;
662         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
663                 return False;
664         if (!prs_uint32("starttime", ps, depth, &info->starttime))
665                 return False;
666         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
667                 return False;
668         if (!prs_uint32("status", ps, depth, &info->status))
669                 return False;
670         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
671                 return False;
672         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
673                 return False;
674
675         return True;
676 }
677
678 /*******************************************************************
679  Parse a PRINTER_INFO_3 structure.
680 ********************************************************************/  
681
682 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
683 {
684         uint32 offset = 0;
685         prs_struct *ps=&buffer->prs;
686
687         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
688         depth++;        
689         
690         buffer->struct_start=prs_offset(ps);
691         
692         if (MARSHALLING(ps)) {
693                 /* Ensure the SD is 8 byte aligned in the buffer. */
694                 uint32 start = prs_offset(ps); /* Remember the start position. */
695                 uint32 off_val = 0;
696
697                 /* Write a dummy value. */
698                 if (!prs_uint32("offset", ps, depth, &off_val))
699                         return False;
700
701                 /* 8 byte align. */
702                 if (!prs_align_uint64(ps))
703                         return False;
704
705                 /* Remember where we must seek back to write the SD. */
706                 offset = prs_offset(ps);
707
708                 /* Calculate the real offset for the SD. */
709
710                 off_val = offset - start;
711
712                 /* Seek back to where we store the SD offset & store. */
713                 prs_set_offset(ps, start);
714                 if (!prs_uint32("offset", ps, depth, &off_val))
715                         return False;
716
717                 /* Return to after the 8 byte align. */
718                 prs_set_offset(ps, offset);
719
720         } else {
721                 if (!prs_uint32("offset", ps, depth, &offset))
722                         return False;
723                 /* Seek within the buffer. */
724                 if (!prs_set_offset(ps, offset))
725                         return False;
726         }
727         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
728                 return False;
729
730         return True;
731 }
732
733 /*******************************************************************
734  Parse a PRINTER_INFO_4 structure.
735 ********************************************************************/  
736
737 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
738 {
739         prs_struct *ps=&buffer->prs;
740
741         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
742         depth++;        
743         
744         buffer->struct_start=prs_offset(ps);
745         
746         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
747                 return False;
748         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
749                 return False;
750         if (!prs_uint32("attributes", ps, depth, &info->attributes))
751                 return False;
752         return True;
753 }
754
755 /*******************************************************************
756  Parse a PRINTER_INFO_5 structure.
757 ********************************************************************/  
758
759 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
760 {
761         prs_struct *ps=&buffer->prs;
762
763         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
764         depth++;        
765         
766         buffer->struct_start=prs_offset(ps);
767         
768         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
769                 return False;
770         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
771                 return False;
772         if (!prs_uint32("attributes", ps, depth, &info->attributes))
773                 return False;
774         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
775                 return False;
776         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
777                 return False;
778         return True;
779 }
780
781 /*******************************************************************
782  Parse a PRINTER_INFO_6 structure.
783 ********************************************************************/  
784
785 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
786                            PRINTER_INFO_6 *info, int depth)
787 {
788         prs_struct *ps=&buffer->prs;
789
790         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
791         depth++;        
792         
793         if (!prs_uint32("status", ps, depth, &info->status))
794                 return False;
795
796         return True;
797 }
798
799 /*******************************************************************
800  Parse a PRINTER_INFO_7 structure.
801 ********************************************************************/  
802
803 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
804 {
805         prs_struct *ps=&buffer->prs;
806
807         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
808         depth++;        
809         
810         buffer->struct_start=prs_offset(ps);
811         
812         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
813                 return False;
814         if (!prs_uint32("action", ps, depth, &info->action))
815                 return False;
816         return True;
817 }
818
819 /*******************************************************************
820  Parse a DRIVER_INFO_1 structure.
821 ********************************************************************/
822
823 bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
824 {
825         prs_struct *ps=&buffer->prs;
826
827         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
828         depth++;        
829         
830         buffer->struct_start=prs_offset(ps);
831
832         if (!smb_io_relstr("name", buffer, depth, &info->name))
833                 return False;
834
835         return True;
836 }
837
838 /*******************************************************************
839  Parse a DRIVER_INFO_2 structure.
840 ********************************************************************/
841
842 bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
843 {
844         prs_struct *ps=&buffer->prs;
845
846         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
847         depth++;        
848         
849         buffer->struct_start=prs_offset(ps);
850
851         if (!prs_uint32("version", ps, depth, &info->version))
852                 return False;
853         if (!smb_io_relstr("name", buffer, depth, &info->name))
854                 return False;
855         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
856                 return False;
857         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
858                 return False;
859         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
860                 return False;
861         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
862                 return False;
863
864         return True;
865 }
866
867 /*******************************************************************
868  Parse a DRIVER_INFO_3 structure.
869 ********************************************************************/
870
871 bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
872 {
873         prs_struct *ps=&buffer->prs;
874
875         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
876         depth++;        
877         
878         buffer->struct_start=prs_offset(ps);
879
880         if (!prs_uint32("version", ps, depth, &info->version))
881                 return False;
882         if (!smb_io_relstr("name", buffer, depth, &info->name))
883                 return False;
884         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
885                 return False;
886         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
887                 return False;
888         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
889                 return False;
890         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
891                 return False;
892         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
893                 return False;
894
895         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
896                 return False;
897
898         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
899                 return False;
900         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
901                 return False;
902
903         return True;
904 }
905
906 /*******************************************************************
907  Parse a DRIVER_INFO_6 structure.
908 ********************************************************************/
909
910 bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
911 {
912         prs_struct *ps=&buffer->prs;
913
914         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
915         depth++;        
916         
917         buffer->struct_start=prs_offset(ps);
918
919         if (!prs_uint32("version", ps, depth, &info->version))
920                 return False;
921         if (!smb_io_relstr("name", buffer, depth, &info->name))
922                 return False;
923         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
924                 return False;
925         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
926                 return False;
927         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
928                 return False;
929         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
930                 return False;
931         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
932                 return False;
933
934         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
935                 return False;
936
937         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
938                 return False;
939         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
940                 return False;
941
942         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
943                 return False;
944
945         if (!prs_uint64("date", ps, depth, &info->driver_date))
946                 return False;
947
948         if (!prs_uint32("padding", ps, depth, &info->padding))
949                 return False;
950
951         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
952                 return False;
953
954         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
955                 return False;
956
957         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
958                 return False;
959         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
960                 return False;
961         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
962                 return False;
963         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
964                 return False;
965         
966         return True;
967 }
968
969 /*******************************************************************
970 return the size required by a struct in the stream
971 ********************************************************************/  
972
973 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
974 {
975         int size=0;
976         
977         size+=size_of_relative_string( &info->printername );
978         size+=size_of_relative_string( &info->servername );
979
980         size+=size_of_uint32( &info->cjobs);
981         size+=size_of_uint32( &info->total_jobs);
982         size+=size_of_uint32( &info->total_bytes);
983
984         size+=size_of_uint16( &info->year);
985         size+=size_of_uint16( &info->month);
986         size+=size_of_uint16( &info->dayofweek);
987         size+=size_of_uint16( &info->day);
988         size+=size_of_uint16( &info->hour);
989         size+=size_of_uint16( &info->minute);
990         size+=size_of_uint16( &info->second);
991         size+=size_of_uint16( &info->milliseconds);
992
993         size+=size_of_uint32( &info->global_counter);
994         size+=size_of_uint32( &info->total_pages);
995
996         size+=size_of_uint16( &info->major_version);
997         size+=size_of_uint16( &info->build_version);
998
999         size+=size_of_uint32( &info->unknown7);
1000         size+=size_of_uint32( &info->unknown8);
1001         size+=size_of_uint32( &info->unknown9);
1002         size+=size_of_uint32( &info->session_counter);
1003         size+=size_of_uint32( &info->unknown11);
1004         size+=size_of_uint32( &info->printer_errors);
1005         size+=size_of_uint32( &info->unknown13);
1006         size+=size_of_uint32( &info->unknown14);
1007         size+=size_of_uint32( &info->unknown15);
1008         size+=size_of_uint32( &info->unknown16);
1009         size+=size_of_uint32( &info->change_id);
1010         size+=size_of_uint32( &info->unknown18);
1011         size+=size_of_uint32( &info->status);
1012         size+=size_of_uint32( &info->unknown20);
1013         size+=size_of_uint32( &info->c_setprinter);
1014         
1015         size+=size_of_uint16( &info->unknown22);
1016         size+=size_of_uint16( &info->unknown23);
1017         size+=size_of_uint16( &info->unknown24);
1018         size+=size_of_uint16( &info->unknown25);
1019         size+=size_of_uint16( &info->unknown26);
1020         size+=size_of_uint16( &info->unknown27);
1021         size+=size_of_uint16( &info->unknown28);
1022         size+=size_of_uint16( &info->unknown29);
1023         
1024         return size;
1025 }
1026
1027 /*******************************************************************
1028 return the size required by a struct in the stream
1029 ********************************************************************/  
1030
1031 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
1032 {
1033         int size=0;
1034                 
1035         size+=size_of_uint32( &info->flags );   
1036         size+=size_of_relative_string( &info->description );
1037         size+=size_of_relative_string( &info->name );
1038         size+=size_of_relative_string( &info->comment );
1039
1040         return size;
1041 }
1042
1043 /*******************************************************************
1044 return the size required by a struct in the stream
1045 ********************************************************************/
1046
1047 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
1048 {
1049         uint32 size=0;
1050                 
1051         size += 4;
1052         
1053         size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
1054
1055         size+=size_of_device_mode( info->devmode );
1056         
1057         size+=size_of_relative_string( &info->servername );
1058         size+=size_of_relative_string( &info->printername );
1059         size+=size_of_relative_string( &info->sharename );
1060         size+=size_of_relative_string( &info->portname );
1061         size+=size_of_relative_string( &info->drivername );
1062         size+=size_of_relative_string( &info->comment );
1063         size+=size_of_relative_string( &info->location );
1064         
1065         size+=size_of_relative_string( &info->sepfile );
1066         size+=size_of_relative_string( &info->printprocessor );
1067         size+=size_of_relative_string( &info->datatype );
1068         size+=size_of_relative_string( &info->parameters );
1069
1070         size+=size_of_uint32( &info->attributes );
1071         size+=size_of_uint32( &info->priority );
1072         size+=size_of_uint32( &info->defaultpriority );
1073         size+=size_of_uint32( &info->starttime );
1074         size+=size_of_uint32( &info->untiltime );
1075         size+=size_of_uint32( &info->status );
1076         size+=size_of_uint32( &info->cjobs );
1077         size+=size_of_uint32( &info->averageppm );      
1078                 
1079         /* 
1080          * add any adjustments for alignment.  This is
1081          * not optimal since we could be calling this
1082          * function from a loop (e.g. enumprinters), but 
1083          * it is easier to maintain the calculation here and
1084          * not place the burden on the caller to remember.   --jerry
1085          */
1086         if ((size % 4) != 0)
1087                 size += 4 - (size % 4);
1088         
1089         return size;
1090 }
1091
1092 /*******************************************************************
1093 return the size required by a struct in the stream
1094 ********************************************************************/
1095
1096 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
1097 {
1098         uint32 size=0;
1099                 
1100         size+=size_of_relative_string( &info->printername );
1101         size+=size_of_relative_string( &info->servername );
1102
1103         size+=size_of_uint32( &info->attributes );
1104         return size;
1105 }
1106
1107 /*******************************************************************
1108 return the size required by a struct in the stream
1109 ********************************************************************/
1110
1111 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
1112 {
1113         uint32 size=0;
1114                 
1115         size+=size_of_relative_string( &info->printername );
1116         size+=size_of_relative_string( &info->portname );
1117
1118         size+=size_of_uint32( &info->attributes );
1119         size+=size_of_uint32( &info->device_not_selected_timeout );
1120         size+=size_of_uint32( &info->transmission_retry_timeout );
1121         return size;
1122 }
1123
1124 /*******************************************************************
1125 return the size required by a struct in the stream
1126 ********************************************************************/
1127
1128 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
1129 {
1130         return sizeof(uint32);
1131 }
1132
1133 /*******************************************************************
1134 return the size required by a struct in the stream
1135 ********************************************************************/
1136
1137 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
1138 {
1139         /* The 8 is for the self relative pointer - 8 byte aligned.. */
1140         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
1141 }
1142
1143 /*******************************************************************
1144 return the size required by a struct in the stream
1145 ********************************************************************/
1146
1147 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
1148 {
1149         uint32 size=0;
1150                 
1151         size+=size_of_relative_string( &info->guid );
1152         size+=size_of_uint32( &info->action );
1153         return size;
1154 }
1155
1156 /*******************************************************************
1157 return the size required by a struct in the stream
1158 ********************************************************************/
1159
1160 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
1161 {
1162         int size=0;
1163         size+=size_of_relative_string( &info->name );
1164
1165         return size;
1166 }
1167
1168 /*******************************************************************
1169 return the size required by a struct in the stream
1170 ********************************************************************/
1171
1172 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
1173 {
1174         int size=0;
1175         size+=size_of_uint32( &info->version ); 
1176         size+=size_of_relative_string( &info->name );
1177         size+=size_of_relative_string( &info->architecture );
1178         size+=size_of_relative_string( &info->driverpath );
1179         size+=size_of_relative_string( &info->datafile );
1180         size+=size_of_relative_string( &info->configfile );
1181
1182         return size;
1183 }
1184
1185 /*******************************************************************
1186 return the size required by a string array.
1187 ********************************************************************/
1188
1189 uint32 spoolss_size_string_array(uint16 *string)
1190 {
1191         uint32 i = 0;
1192
1193         if (string) {
1194                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
1195         }
1196         i=i+2; /* to count all chars including the leading zero */
1197         i=2*i; /* because we need the value in bytes */
1198         i=i+4; /* the offset pointer size */
1199
1200         return i;
1201 }
1202
1203 /*******************************************************************
1204 return the size required by a struct in the stream
1205 ********************************************************************/
1206
1207 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
1208 {
1209         int size=0;
1210
1211         size+=size_of_uint32( &info->version ); 
1212         size+=size_of_relative_string( &info->name );
1213         size+=size_of_relative_string( &info->architecture );
1214         size+=size_of_relative_string( &info->driverpath );
1215         size+=size_of_relative_string( &info->datafile );
1216         size+=size_of_relative_string( &info->configfile );
1217         size+=size_of_relative_string( &info->helpfile );
1218         size+=size_of_relative_string( &info->monitorname );
1219         size+=size_of_relative_string( &info->defaultdatatype );
1220         
1221         size+=spoolss_size_string_array(info->dependentfiles);
1222
1223         return size;
1224 }
1225
1226 /*******************************************************************
1227 return the size required by a struct in the stream
1228 ********************************************************************/
1229
1230 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
1231 {
1232         uint32 size=0;
1233
1234         size+=size_of_uint32( &info->version ); 
1235         size+=size_of_relative_string( &info->name );
1236         size+=size_of_relative_string( &info->architecture );
1237         size+=size_of_relative_string( &info->driverpath );
1238         size+=size_of_relative_string( &info->datafile );
1239         size+=size_of_relative_string( &info->configfile );
1240         size+=size_of_relative_string( &info->helpfile );
1241
1242         size+=spoolss_size_string_array(info->dependentfiles);
1243
1244         size+=size_of_relative_string( &info->monitorname );
1245         size+=size_of_relative_string( &info->defaultdatatype );
1246         
1247         size+=spoolss_size_string_array(info->previousdrivernames);
1248
1249         size+=size_of_nttime(&info->driver_date);
1250         size+=size_of_uint32( &info->padding ); 
1251         size+=size_of_uint32( &info->driver_version_low );      
1252         size+=size_of_uint32( &info->driver_version_high );     
1253         size+=size_of_relative_string( &info->mfgname );
1254         size+=size_of_relative_string( &info->oem_url );
1255         size+=size_of_relative_string( &info->hardware_id );
1256         size+=size_of_relative_string( &info->provider );
1257
1258         return size;
1259 }
1260
1261 /*******************************************************************
1262 return the size required by a struct in the stream
1263 ********************************************************************/  
1264 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
1265 {
1266         uint32  size = 0; 
1267         
1268         if (!p)
1269                 return 0;
1270         
1271         /* uint32(offset) + uint32(length) + length) */
1272         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
1273         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
1274         
1275         size += size_of_uint32(&p->type);
1276                        
1277         return size;
1278 }
1279
1280 /*******************************************************************
1281  * read a structure.
1282  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
1283  ********************************************************************/
1284
1285 bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
1286 {
1287         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
1288         depth++;
1289
1290         if(!prs_align(ps))
1291                 return False;
1292         
1293         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1294                 return False;
1295         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
1296                 return False;
1297         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
1298                 return False;
1299         
1300         if(!prs_align(ps))
1301                 return False;
1302         if(!prs_uint32("level", ps, depth, &q_u->level))
1303                 return False;
1304                 
1305         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1306                 return False;
1307
1308         if(!prs_align(ps))
1309                 return False;
1310
1311         if(!prs_uint32("offered", ps, depth, &q_u->offered))
1312                 return False;
1313                 
1314         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
1315                 return False;
1316         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
1317                 return False;
1318
1319         return True;
1320 }
1321
1322 /*******************************************************************
1323  * read a structure.
1324  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
1325  ********************************************************************/
1326
1327 bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
1328 {
1329         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
1330         depth++;
1331
1332         if (!prs_align(ps))
1333                 return False;
1334                 
1335         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1336                 return False;
1337
1338         if (!prs_align(ps))
1339                 return False;
1340         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1341                 return False;
1342         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
1343                 return False;
1344         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
1345                 return False;           
1346         if (!prs_werror("status", ps, depth, &r_u->status))
1347                 return False;
1348
1349         return True;            
1350 }
1351
1352 /*******************************************************************
1353  * init a structure.
1354  ********************************************************************/
1355
1356 bool make_spoolss_q_enumprinters(
1357         SPOOL_Q_ENUMPRINTERS *q_u, 
1358         uint32 flags, 
1359         char *servername, 
1360         uint32 level, 
1361         RPC_BUFFER *buffer, 
1362         uint32 offered
1363 )
1364 {
1365         q_u->flags=flags;
1366         
1367         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
1368         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
1369
1370         q_u->level=level;
1371         q_u->buffer=buffer;
1372         q_u->offered=offered;
1373
1374         return True;
1375 }
1376
1377 /*******************************************************************
1378  * read a structure.
1379  * called from spoolss_enumprinters (srv_spoolss.c)
1380  ********************************************************************/
1381
1382 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
1383 {
1384         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
1385         depth++;
1386
1387         if (!prs_align(ps))
1388                 return False;
1389
1390         if (!prs_uint32("flags", ps, depth, &q_u->flags))
1391                 return False;
1392         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
1393                 return False;
1394
1395         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
1396                 return False;
1397                 
1398         if (!prs_align(ps))
1399                 return False;
1400         if (!prs_uint32("level", ps, depth, &q_u->level))
1401                 return False;
1402
1403         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1404                 return False;
1405
1406         if (!prs_align(ps))
1407                 return False;
1408         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1409                 return False;
1410
1411         return True;
1412 }
1413
1414 /*******************************************************************
1415  Parse a SPOOL_R_ENUMPRINTERS structure.
1416  ********************************************************************/
1417
1418 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
1419 {
1420         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
1421         depth++;
1422
1423         if (!prs_align(ps))
1424                 return False;
1425                 
1426         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1427                 return False;
1428
1429         if (!prs_align(ps))
1430                 return False;
1431                 
1432         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1433                 return False;
1434                 
1435         if (!prs_uint32("returned", ps, depth, &r_u->returned))
1436                 return False;
1437                 
1438         if (!prs_werror("status", ps, depth, &r_u->status))
1439                 return False;
1440
1441         return True;            
1442 }
1443
1444 /*******************************************************************
1445  * write a structure.
1446  * called from spoolss_r_enum_printers (srv_spoolss.c)
1447  *
1448  ********************************************************************/
1449
1450 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
1451 {       
1452         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
1453         depth++;
1454
1455         if (!prs_align(ps))
1456                 return False;
1457                 
1458         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1459                 return False;
1460
1461         if (!prs_align(ps))
1462                 return False;
1463
1464         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1465                 return False;
1466                 
1467         if (!prs_werror("status", ps, depth, &r_u->status))
1468                 return False;
1469
1470         return True;            
1471 }
1472
1473 /*******************************************************************
1474  * read a structure.
1475  * called from spoolss_getprinter (srv_spoolss.c)
1476  ********************************************************************/
1477
1478 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
1479 {
1480         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
1481         depth++;
1482
1483         if (!prs_align(ps))
1484                 return False;
1485
1486         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1487                 return False;
1488         if (!prs_uint32("level", ps, depth, &q_u->level))
1489                 return False;
1490
1491         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1492                 return False;
1493
1494         if (!prs_align(ps))
1495                 return False;
1496         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1497                 return False;
1498
1499         return True;
1500 }
1501
1502 /*******************************************************************
1503  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
1504 ********************************************************************/  
1505
1506 bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
1507 {
1508         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
1509         depth++;
1510
1511         if (!prs_align(ps))
1512                 return False;
1513                 
1514         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1515                 return False;
1516
1517         if (!prs_align(ps))
1518                 return False;
1519                 
1520         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1521                 return False;
1522                 
1523         if (!prs_uint32("returned", ps, depth, &r_u->returned))
1524                 return False;
1525                 
1526         if (!prs_werror("status", ps, depth, &r_u->status))
1527                 return False;
1528
1529         return True;            
1530 }
1531
1532 /*******************************************************************
1533  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
1534 ********************************************************************/  
1535
1536 bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
1537 {
1538
1539         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
1540         depth++;
1541
1542         if (!prs_align(ps))
1543                 return False;
1544                 
1545         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
1546                 return False;
1547         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
1548                 return False;
1549                 
1550         if (!prs_align(ps))
1551                 return False;
1552         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
1553                 return False;
1554         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
1555                 return False;
1556                 
1557         if (!prs_align(ps))
1558                 return False;
1559         if (!prs_uint32("level", ps, depth, &q_u->level))
1560                 return False;
1561                 
1562         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1563                 return False;
1564
1565         if (!prs_align(ps))
1566                 return False;
1567                 
1568         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1569                 return False;
1570
1571         return True;
1572 }
1573
1574 /*******************************************************************
1575  make a BUFFER5 struct from a uint16*
1576  ******************************************************************/
1577
1578 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
1579 {
1580
1581         buf5->buf_len = len;
1582         if (src) {
1583                 if (len) {
1584                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
1585                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
1586                                 return False;
1587                         }
1588                 } else {
1589                         buf5->buffer = NULL;
1590                 }
1591         } else {
1592                 buf5->buffer=NULL;
1593         }
1594         
1595         return True;
1596 }
1597
1598 /*******************************************************************
1599 ********************************************************************/  
1600
1601 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
1602 {       
1603         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
1604         depth++;
1605
1606         if(!prs_align(ps))
1607                 return False;
1608         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
1609                 return False;
1610
1611         if (UNMARSHALLING(ps) && r_u->valuesize) {
1612                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
1613                 if (!r_u->value) {
1614                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
1615                         return False;
1616                 }
1617         }
1618
1619         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
1620                 return False;
1621
1622         if(!prs_align(ps))
1623                 return False;
1624
1625         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
1626                 return False;
1627
1628         if(!prs_uint32("type", ps, depth, &r_u->type))
1629                 return False;
1630
1631         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
1632                 return False;
1633
1634         if (UNMARSHALLING(ps) && r_u->datasize) {
1635                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
1636                 if (!r_u->data) {
1637                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
1638                         return False;
1639                 }
1640         }
1641
1642         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
1643                 return False;
1644         if(!prs_align(ps))
1645                 return False;
1646
1647         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
1648                 return False;
1649         if(!prs_werror("status", ps, depth, &r_u->status))
1650                 return False;
1651
1652         return True;
1653 }
1654
1655 /*******************************************************************
1656 ********************************************************************/  
1657
1658 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
1659 {
1660         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
1661         depth++;
1662
1663         if(!prs_align(ps))
1664                 return False;
1665         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1666                 return False;
1667         if(!prs_uint32("index", ps, depth, &q_u->index))
1668                 return False;
1669         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
1670                 return False;
1671         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
1672                 return False;
1673
1674         return True;
1675 }
1676
1677 /*******************************************************************
1678 ********************************************************************/  
1679
1680 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
1681                 const POLICY_HND *hnd,
1682                 uint32 idx, uint32 valuelen, uint32 datalen)
1683 {
1684         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1685         q_u->index=idx;
1686         q_u->valuesize=valuelen;
1687         q_u->datasize=datalen;
1688
1689         return True;
1690 }
1691
1692 /*******************************************************************
1693 ********************************************************************/  
1694
1695 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
1696                                       const POLICY_HND *hnd, const char *key,
1697                                       uint32 size)
1698 {
1699         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1700         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
1701         q_u->size = size;
1702
1703         return True;
1704 }
1705
1706 /*******************************************************************
1707 ********************************************************************/  
1708 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
1709                                    char* value, uint32 data_type, char* data, uint32 data_size)
1710 {
1711         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1712         q_u->type = data_type;
1713         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
1714
1715         q_u->max_len = q_u->real_len = data_size;
1716         q_u->data = (unsigned char *)data;
1717         
1718         return True;
1719 }
1720
1721 /*******************************************************************
1722 ********************************************************************/  
1723
1724 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
1725 {
1726         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
1727         depth++;
1728
1729         if(!prs_align(ps))
1730                 return False;
1731         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1732                 return False;
1733         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
1734                 return False;
1735
1736         if(!prs_align(ps))
1737                 return False;
1738
1739         if(!prs_uint32("type", ps, depth, &q_u->type))
1740                 return False;
1741
1742         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
1743                 return False;
1744
1745         switch (q_u->type)
1746         {
1747                 case REG_SZ:
1748                 case REG_BINARY:
1749                 case REG_DWORD:
1750                 case REG_MULTI_SZ:
1751                         if (q_u->max_len) {
1752                                 if (UNMARSHALLING(ps))
1753                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
1754                                 if(q_u->data == NULL)
1755                                         return False;
1756                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
1757                                         return False;
1758                         }
1759                         if(!prs_align(ps))
1760                                 return False;
1761                         break;
1762         }       
1763         
1764         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
1765                 return False;
1766
1767         return True;
1768 }
1769
1770 /*******************************************************************
1771 ********************************************************************/  
1772
1773 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
1774 {
1775         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
1776         depth++;
1777
1778         if(!prs_align(ps))
1779                 return False;
1780         if(!prs_werror("status",     ps, depth, &r_u->status))
1781                 return False;
1782
1783         return True;
1784 }
1785
1786 void free_devmode(DEVICEMODE *devmode)
1787 {
1788         if (devmode!=NULL) {
1789                 SAFE_FREE(devmode->dev_private);
1790                 SAFE_FREE(devmode);
1791         }
1792 }
1793
1794 void free_printer_info_1(PRINTER_INFO_1 *printer)
1795 {
1796         SAFE_FREE(printer);
1797 }
1798
1799 void free_printer_info_2(PRINTER_INFO_2 *printer)
1800 {
1801         if (printer!=NULL) {
1802                 free_devmode(printer->devmode);
1803                 printer->devmode = NULL;
1804                 SAFE_FREE(printer);
1805         }
1806 }
1807
1808 void free_printer_info_3(PRINTER_INFO_3 *printer)
1809 {
1810         SAFE_FREE(printer);
1811 }
1812
1813 void free_printer_info_4(PRINTER_INFO_4 *printer)
1814 {
1815         SAFE_FREE(printer);
1816 }
1817
1818 void free_printer_info_5(PRINTER_INFO_5 *printer)
1819 {
1820         SAFE_FREE(printer);
1821 }
1822
1823 void free_printer_info_6(PRINTER_INFO_6 *printer)
1824 {
1825         SAFE_FREE(printer);
1826 }
1827
1828 void free_printer_info_7(PRINTER_INFO_7 *printer)
1829 {
1830         SAFE_FREE(printer);
1831 }
1832
1833 /*******************************************************************
1834  * read a structure.
1835  ********************************************************************/  
1836 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
1837                                    POLICY_HND *hnd, const char *key, 
1838                                    uint32 size)
1839 {
1840         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
1841
1842         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1843         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
1844         q_u->size = size;
1845
1846         return True;
1847 }
1848
1849 /*******************************************************************
1850  * read a structure.
1851  ********************************************************************/  
1852
1853 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
1854 {
1855         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
1856         depth++;
1857
1858         if(!prs_align(ps))
1859                 return False;
1860         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1861                 return False;
1862                 
1863         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
1864                 return False;
1865
1866         if(!prs_align(ps))
1867                 return False;
1868         
1869         if(!prs_uint32("size", ps, depth, &q_u->size))
1870                 return False;
1871
1872         return True;
1873 }
1874
1875 /*******************************************************************
1876  * write a structure.
1877  ********************************************************************/  
1878
1879 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
1880 {
1881         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
1882         depth++;
1883
1884         if(!prs_align(ps))
1885                 return False;
1886
1887         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
1888                 return False;
1889         
1890         if(!prs_align(ps))
1891                 return False;
1892
1893         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
1894                 return False;
1895
1896         if(!prs_werror("status",     ps, depth, &r_u->status))
1897                 return False;
1898
1899         return True;
1900 }
1901
1902 /*******************************************************************
1903  * read a structure.
1904  ********************************************************************/  
1905
1906 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1907 {
1908         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
1909         depth++;
1910
1911         if(!prs_align(ps))
1912                 return False;
1913         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1914                 return False;
1915                 
1916         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
1917                 return False;
1918
1919         if(!prs_align(ps))
1920                 return False;
1921         
1922         if(!prs_uint32("size", ps, depth, &q_u->size))
1923                 return False;
1924
1925         return True;
1926 }
1927
1928 /*******************************************************************
1929 ********************************************************************/  
1930
1931 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
1932                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
1933 {
1934         int     i;
1935         uint32  valuename_offset,
1936                 data_offset,
1937                 current_offset;
1938         const uint32 basic_unit = 20; /* size of static portion of enum_values */
1939
1940         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
1941         depth++;        
1942
1943         /* 
1944          * offset data begins at 20 bytes per structure * size_of_array.
1945          * Don't forget the uint32 at the beginning 
1946          * */
1947         
1948         current_offset = basic_unit * ctr->size_of_array;
1949         
1950         /* first loop to write basic enum_value information */
1951         
1952         if (UNMARSHALLING(ps) && ctr->size_of_array) {
1953                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
1954                 if (!ctr->values)
1955                         return False;
1956         }
1957
1958         for (i=0; i<ctr->size_of_array; i++) {
1959                 uint32 base_offset, return_offset;
1960
1961                 base_offset = prs_offset(ps);
1962
1963                 valuename_offset = current_offset;
1964                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
1965                         return False;
1966
1967                 /* Read or write the value. */
1968
1969                 return_offset = prs_offset(ps);
1970
1971                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
1972                         return False;
1973                 }
1974
1975                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
1976                         return False;
1977
1978                 /* And go back. */
1979                 if (!prs_set_offset(ps, return_offset))
1980                         return False;
1981
1982                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
1983                         return False;
1984         
1985                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
1986                         return False;
1987         
1988                 data_offset = ctr->values[i].value_len + valuename_offset;
1989                 
1990                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
1991                         return False;
1992
1993                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
1994                         return False;
1995                         
1996                 /* Read or write the data. */
1997
1998                 return_offset = prs_offset(ps);
1999
2000                 if (!prs_set_offset(ps, base_offset + data_offset)) {
2001                         return False;
2002                 }
2003
2004                 if ( ctr->values[i].data_len ) {
2005                         if ( UNMARSHALLING(ps) ) {
2006                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
2007                                 if (!ctr->values[i].data)
2008                                         return False;
2009                         }
2010                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
2011                                 return False;
2012                 }
2013
2014                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
2015                 /* account for 2 byte alignment */
2016                 current_offset += (current_offset % 2);
2017
2018                 /* Remember how far we got. */
2019                 data_offset = prs_offset(ps);
2020
2021                 /* And go back. */
2022                 if (!prs_set_offset(ps, return_offset))
2023                         return False;
2024
2025         }
2026
2027         /* Go to the last data offset we got to. */
2028
2029         if (!prs_set_offset(ps, data_offset))
2030                 return False;
2031
2032         /* And ensure we're 2 byte aligned. */
2033
2034         if ( !prs_align_uint16(ps) )
2035                 return False;
2036
2037         return True;    
2038 }
2039
2040 /*******************************************************************
2041  * write a structure.
2042  ********************************************************************/  
2043
2044 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
2045 {
2046         uint32 data_offset, end_offset;
2047         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
2048         depth++;
2049
2050         if(!prs_align(ps))
2051                 return False;
2052
2053         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
2054                 return False;
2055
2056         data_offset = prs_offset(ps);
2057
2058         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
2059                 return False;
2060
2061         if(!prs_align(ps))
2062                 return False;
2063
2064         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
2065                 return False;
2066
2067         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
2068                 return False;
2069
2070         if(!prs_werror("status",     ps, depth, &r_u->status))
2071                 return False;
2072
2073         r_u->ctr.size_of_array = r_u->returned;
2074
2075         end_offset = prs_offset(ps);
2076
2077         if (!prs_set_offset(ps, data_offset))
2078                 return False;
2079
2080         if (r_u->ctr.size)
2081                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
2082                         return False;
2083
2084         if (!prs_set_offset(ps, end_offset))
2085                 return False;
2086         return True;
2087 }