Properly strip /usr/lib and /usr/include for the merged build.
[amitay/samba.git] / source3 / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000,
7  *  Copyright (C) Gerald Carter                2000-2002,
8  *  Copyright (C) Tim Potter                   2001-2002.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 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  * return the length of a uint32 (obvious, but the code is clean)
390  ********************************************************************/
391
392 static uint32 size_of_systemtime(SYSTEMTIME *systime)
393 {
394         if (systime==NULL)
395                 return (4);
396         else 
397                 return (sizeof(SYSTEMTIME) +4);
398 }
399
400 /*******************************************************************
401  Parse a DEVMODE structure and its relative pointer.
402 ********************************************************************/
403
404 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
405 {
406         prs_struct *ps=&buffer->prs;
407
408         prs_debug(ps, depth, desc, "smb_io_reldevmode");
409         depth++;
410
411         if (MARSHALLING(ps)) {
412                 uint32 struct_offset = prs_offset(ps);
413                 uint32 relative_offset;
414                 
415                 if (*devmode == NULL) {
416                         relative_offset=0;
417                         if (!prs_uint32("offset", ps, depth, &relative_offset))
418                                 return False;
419                         DEBUG(8, ("boing, the devmode was NULL\n"));
420                         
421                         return True;
422                 }
423                 
424                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
425
426                 /* mz:  we have to align the device mode for VISTA */
427                 if (buffer->string_at_end % 4) {
428                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
429                 }
430
431                 if(!prs_set_offset(ps, buffer->string_at_end))
432                         return False;
433                 
434                 /* write the DEVMODE */
435                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
436                         return False;
437
438                 if(!prs_set_offset(ps, struct_offset))
439                         return False;
440                 
441                 relative_offset=buffer->string_at_end - buffer->struct_start;
442                 /* write its offset */
443                 if (!prs_uint32("offset", ps, depth, &relative_offset))
444                         return False;
445         }
446         else {
447                 uint32 old_offset;
448                 
449                 /* read the offset */
450                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
451                         return False;
452                 if (buffer->string_at_end == 0) {
453                         *devmode = NULL;
454                         return True;
455                 }
456
457                 old_offset = prs_offset(ps);
458                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
459                         return False;
460
461                 /* read the string */
462                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
463                         return False;
464                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
465                         return False;
466
467                 if(!prs_set_offset(ps, old_offset))
468                         return False;
469         }
470         return True;
471 }
472
473 /*******************************************************************
474  Parse a PRINTER_INFO_0 structure.
475 ********************************************************************/  
476
477 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
478 {
479         prs_struct *ps=&buffer->prs;
480
481         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
482         depth++;        
483         
484         buffer->struct_start=prs_offset(ps);
485
486         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
487                 return False;
488         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
489                 return False;
490         
491         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
492                 return False;
493         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
494                 return False;
495         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
496                 return False;
497
498         if(!prs_uint16("year", ps, depth, &info->year))
499                 return False;
500         if(!prs_uint16("month", ps, depth, &info->month))
501                 return False;
502         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
503                 return False;
504         if(!prs_uint16("day", ps, depth, &info->day))
505                 return False;
506         if(!prs_uint16("hour", ps, depth, &info->hour))
507                 return False;
508         if(!prs_uint16("minute", ps, depth, &info->minute))
509                 return False;
510         if(!prs_uint16("second", ps, depth, &info->second))
511                 return False;
512         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
513                 return False;
514
515         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
516                 return False;
517         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
518                 return False;
519
520         if(!prs_uint16("major_version", ps, depth, &info->major_version))
521                 return False;
522         if(!prs_uint16("build_version", ps, depth, &info->build_version))
523                 return False;
524         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
525                 return False;
526         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
527                 return False;
528         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
529                 return False;
530         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
531                 return False;
532         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
533                 return False;
534         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
535                 return False;
536         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
537                 return False;
538         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
539                 return False;
540         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
541                 return False;
542         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
543                 return False;
544         if(!prs_uint32("change_id", ps, depth, &info->change_id))
545                 return False;
546         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
547                 return False;
548         if(!prs_uint32("status"   , ps, depth, &info->status))
549                 return False;
550         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
551                 return False;
552         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
553                 return False;
554         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
555                 return False;
556         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
557                 return False;
558         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
559                 return False;
560         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
561                 return False;
562         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
563                 return False;
564         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
565                 return False;
566         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
567                 return False;
568         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
569                 return False;
570
571         return True;
572 }
573
574 /*******************************************************************
575  Parse a PRINTER_INFO_1 structure.
576 ********************************************************************/  
577
578 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
579 {
580         prs_struct *ps=&buffer->prs;
581
582         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
583         depth++;        
584         
585         buffer->struct_start=prs_offset(ps);
586
587         if (!prs_uint32("flags", ps, depth, &info->flags))
588                 return False;
589         if (!smb_io_relstr("description", buffer, depth, &info->description))
590                 return False;
591         if (!smb_io_relstr("name", buffer, depth, &info->name))
592                 return False;
593         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
594                 return False;   
595
596         return True;
597 }
598
599 /*******************************************************************
600  Parse a PRINTER_INFO_2 structure.
601 ********************************************************************/  
602
603 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
604 {
605         prs_struct *ps=&buffer->prs;
606         uint32 dm_offset, sd_offset, current_offset;
607         uint32 dummy_value = 0, has_secdesc = 0;
608
609         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
610         depth++;        
611         
612         buffer->struct_start=prs_offset(ps);
613         
614         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
615                 return False;
616         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
617                 return False;
618         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
619                 return False;
620         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
621                 return False;
622         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
623                 return False;
624         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
625                 return False;
626         if (!smb_io_relstr("location", buffer, depth, &info->location))
627                 return False;
628
629         /* save current offset and wind forwared by a uint32 */
630         dm_offset = prs_offset(ps);
631         if (!prs_uint32("devmode", ps, depth, &dummy_value))
632                 return False;
633         
634         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
635                 return False;
636         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
637                 return False;
638         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
639                 return False;
640         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
641                 return False;
642
643         /* save current offset for the sec_desc */
644         sd_offset = prs_offset(ps);
645         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
646                 return False;
647
648         
649         /* save current location so we can pick back up here */
650         current_offset = prs_offset(ps);
651         
652         /* parse the devmode */
653         if (!prs_set_offset(ps, dm_offset))
654                 return False;
655         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
656                 return False;
657         
658         /* parse the sec_desc */
659         if (info->secdesc) {
660                 if (!prs_set_offset(ps, sd_offset))
661                         return False;
662                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
663                         return False;
664         }
665
666         /* pick up where we left off */
667         if (!prs_set_offset(ps, current_offset))
668                 return False;
669
670         if (!prs_uint32("attributes", ps, depth, &info->attributes))
671                 return False;
672         if (!prs_uint32("priority", ps, depth, &info->priority))
673                 return False;
674         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
675                 return False;
676         if (!prs_uint32("starttime", ps, depth, &info->starttime))
677                 return False;
678         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
679                 return False;
680         if (!prs_uint32("status", ps, depth, &info->status))
681                 return False;
682         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
683                 return False;
684         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
685                 return False;
686
687         return True;
688 }
689
690 /*******************************************************************
691  Parse a PRINTER_INFO_3 structure.
692 ********************************************************************/  
693
694 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
695 {
696         uint32 offset = 0;
697         prs_struct *ps=&buffer->prs;
698
699         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
700         depth++;        
701         
702         buffer->struct_start=prs_offset(ps);
703         
704         if (MARSHALLING(ps)) {
705                 /* Ensure the SD is 8 byte aligned in the buffer. */
706                 uint32 start = prs_offset(ps); /* Remember the start position. */
707                 uint32 off_val = 0;
708
709                 /* Write a dummy value. */
710                 if (!prs_uint32("offset", ps, depth, &off_val))
711                         return False;
712
713                 /* 8 byte align. */
714                 if (!prs_align_uint64(ps))
715                         return False;
716
717                 /* Remember where we must seek back to write the SD. */
718                 offset = prs_offset(ps);
719
720                 /* Calculate the real offset for the SD. */
721
722                 off_val = offset - start;
723
724                 /* Seek back to where we store the SD offset & store. */
725                 prs_set_offset(ps, start);
726                 if (!prs_uint32("offset", ps, depth, &off_val))
727                         return False;
728
729                 /* Return to after the 8 byte align. */
730                 prs_set_offset(ps, offset);
731
732         } else {
733                 if (!prs_uint32("offset", ps, depth, &offset))
734                         return False;
735                 /* Seek within the buffer. */
736                 if (!prs_set_offset(ps, offset))
737                         return False;
738         }
739         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
740                 return False;
741
742         return True;
743 }
744
745 /*******************************************************************
746  Parse a PRINTER_INFO_4 structure.
747 ********************************************************************/  
748
749 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
750 {
751         prs_struct *ps=&buffer->prs;
752
753         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
754         depth++;        
755         
756         buffer->struct_start=prs_offset(ps);
757         
758         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
759                 return False;
760         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
761                 return False;
762         if (!prs_uint32("attributes", ps, depth, &info->attributes))
763                 return False;
764         return True;
765 }
766
767 /*******************************************************************
768  Parse a PRINTER_INFO_5 structure.
769 ********************************************************************/  
770
771 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
772 {
773         prs_struct *ps=&buffer->prs;
774
775         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
776         depth++;        
777         
778         buffer->struct_start=prs_offset(ps);
779         
780         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
781                 return False;
782         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
783                 return False;
784         if (!prs_uint32("attributes", ps, depth, &info->attributes))
785                 return False;
786         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
787                 return False;
788         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
789                 return False;
790         return True;
791 }
792
793 /*******************************************************************
794  Parse a PRINTER_INFO_6 structure.
795 ********************************************************************/  
796
797 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
798                            PRINTER_INFO_6 *info, int depth)
799 {
800         prs_struct *ps=&buffer->prs;
801
802         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
803         depth++;        
804         
805         if (!prs_uint32("status", ps, depth, &info->status))
806                 return False;
807
808         return True;
809 }
810
811 /*******************************************************************
812  Parse a PRINTER_INFO_7 structure.
813 ********************************************************************/  
814
815 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
816 {
817         prs_struct *ps=&buffer->prs;
818
819         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
820         depth++;        
821         
822         buffer->struct_start=prs_offset(ps);
823         
824         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
825                 return False;
826         if (!prs_uint32("action", ps, depth, &info->action))
827                 return False;
828         return True;
829 }
830
831 /*******************************************************************
832  Parse a DRIVER_INFO_1 structure.
833 ********************************************************************/
834
835 bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
836 {
837         prs_struct *ps=&buffer->prs;
838
839         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
840         depth++;        
841         
842         buffer->struct_start=prs_offset(ps);
843
844         if (!smb_io_relstr("name", buffer, depth, &info->name))
845                 return False;
846
847         return True;
848 }
849
850 /*******************************************************************
851  Parse a DRIVER_INFO_2 structure.
852 ********************************************************************/
853
854 bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
855 {
856         prs_struct *ps=&buffer->prs;
857
858         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
859         depth++;        
860         
861         buffer->struct_start=prs_offset(ps);
862
863         if (!prs_uint32("version", ps, depth, &info->version))
864                 return False;
865         if (!smb_io_relstr("name", buffer, depth, &info->name))
866                 return False;
867         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
868                 return False;
869         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
870                 return False;
871         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
872                 return False;
873         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
874                 return False;
875
876         return True;
877 }
878
879 /*******************************************************************
880  Parse a DRIVER_INFO_3 structure.
881 ********************************************************************/
882
883 bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
884 {
885         prs_struct *ps=&buffer->prs;
886
887         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
888         depth++;        
889         
890         buffer->struct_start=prs_offset(ps);
891
892         if (!prs_uint32("version", ps, depth, &info->version))
893                 return False;
894         if (!smb_io_relstr("name", buffer, depth, &info->name))
895                 return False;
896         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
897                 return False;
898         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
899                 return False;
900         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
901                 return False;
902         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
903                 return False;
904         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
905                 return False;
906
907         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
908                 return False;
909
910         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
911                 return False;
912         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
913                 return False;
914
915         return True;
916 }
917
918 /*******************************************************************
919  Parse a DRIVER_INFO_6 structure.
920 ********************************************************************/
921
922 bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
923 {
924         prs_struct *ps=&buffer->prs;
925
926         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
927         depth++;        
928         
929         buffer->struct_start=prs_offset(ps);
930
931         if (!prs_uint32("version", ps, depth, &info->version))
932                 return False;
933         if (!smb_io_relstr("name", buffer, depth, &info->name))
934                 return False;
935         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
936                 return False;
937         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
938                 return False;
939         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
940                 return False;
941         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
942                 return False;
943         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
944                 return False;
945
946         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
947                 return False;
948
949         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
950                 return False;
951         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
952                 return False;
953
954         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
955                 return False;
956
957         if (!prs_uint64("date", ps, depth, &info->driver_date))
958                 return False;
959
960         if (!prs_uint32("padding", ps, depth, &info->padding))
961                 return False;
962
963         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
964                 return False;
965
966         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
967                 return False;
968
969         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
970                 return False;
971         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
972                 return False;
973         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
974                 return False;
975         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
976                 return False;
977         
978         return True;
979 }
980
981 /*******************************************************************
982  Parse a JOB_INFO_1 structure.
983 ********************************************************************/  
984
985 bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
986 {
987         prs_struct *ps=&buffer->prs;
988
989         prs_debug(ps, depth, desc, "smb_io_job_info_1");
990         depth++;        
991         
992         buffer->struct_start=prs_offset(ps);
993
994         if (!prs_uint32("jobid", ps, depth, &info->jobid))
995                 return False;
996         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
997                 return False;
998         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
999                 return False;
1000         if (!smb_io_relstr("username", buffer, depth, &info->username))
1001                 return False;
1002         if (!smb_io_relstr("document", buffer, depth, &info->document))
1003                 return False;
1004         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1005                 return False;
1006         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
1007                 return False;
1008         if (!prs_uint32("status", ps, depth, &info->status))
1009                 return False;
1010         if (!prs_uint32("priority", ps, depth, &info->priority))
1011                 return False;
1012         if (!prs_uint32("position", ps, depth, &info->position))
1013                 return False;
1014         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
1015                 return False;
1016         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
1017                 return False;
1018         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
1019                 return False;
1020
1021         return True;
1022 }
1023
1024 /*******************************************************************
1025  Parse a JOB_INFO_2 structure.
1026 ********************************************************************/  
1027
1028 bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
1029 {       
1030         uint32 pipo=0;
1031         prs_struct *ps=&buffer->prs;
1032         
1033         prs_debug(ps, depth, desc, "smb_io_job_info_2");
1034         depth++;        
1035
1036         buffer->struct_start=prs_offset(ps);
1037         
1038         if (!prs_uint32("jobid",ps, depth, &info->jobid))
1039                 return False;
1040         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1041                 return False;
1042         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
1043                 return False;
1044         if (!smb_io_relstr("username", buffer, depth, &info->username))
1045                 return False;
1046         if (!smb_io_relstr("document", buffer, depth, &info->document))
1047                 return False;
1048         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
1049                 return False;
1050         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1051                 return False;
1052
1053         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1054                 return False;
1055         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
1056                 return False;
1057         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
1058                 return False;
1059         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1060                 return False;
1061         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
1062                 return False;
1063
1064 /*      SEC_DESC sec_desc;*/
1065         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
1066                 return False;
1067
1068         if (!prs_uint32("status",ps, depth, &info->status))
1069                 return False;
1070         if (!prs_uint32("priority",ps, depth, &info->priority))
1071                 return False;
1072         if (!prs_uint32("position",ps, depth, &info->position)) 
1073                 return False;
1074         if (!prs_uint32("starttime",ps, depth, &info->starttime))
1075                 return False;
1076         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
1077                 return False;
1078         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
1079                 return False;
1080         if (!prs_uint32("size",ps, depth, &info->size))
1081                 return False;
1082         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
1083                 return False;
1084         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
1085                 return False;
1086         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
1087                 return False;
1088
1089         return True;
1090 }
1091
1092 /*******************************************************************
1093 return the size required by a struct in the stream
1094 ********************************************************************/  
1095
1096 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
1097 {
1098         int 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->cjobs);
1104         size+=size_of_uint32( &info->total_jobs);
1105         size+=size_of_uint32( &info->total_bytes);
1106
1107         size+=size_of_uint16( &info->year);
1108         size+=size_of_uint16( &info->month);
1109         size+=size_of_uint16( &info->dayofweek);
1110         size+=size_of_uint16( &info->day);
1111         size+=size_of_uint16( &info->hour);
1112         size+=size_of_uint16( &info->minute);
1113         size+=size_of_uint16( &info->second);
1114         size+=size_of_uint16( &info->milliseconds);
1115
1116         size+=size_of_uint32( &info->global_counter);
1117         size+=size_of_uint32( &info->total_pages);
1118
1119         size+=size_of_uint16( &info->major_version);
1120         size+=size_of_uint16( &info->build_version);
1121
1122         size+=size_of_uint32( &info->unknown7);
1123         size+=size_of_uint32( &info->unknown8);
1124         size+=size_of_uint32( &info->unknown9);
1125         size+=size_of_uint32( &info->session_counter);
1126         size+=size_of_uint32( &info->unknown11);
1127         size+=size_of_uint32( &info->printer_errors);
1128         size+=size_of_uint32( &info->unknown13);
1129         size+=size_of_uint32( &info->unknown14);
1130         size+=size_of_uint32( &info->unknown15);
1131         size+=size_of_uint32( &info->unknown16);
1132         size+=size_of_uint32( &info->change_id);
1133         size+=size_of_uint32( &info->unknown18);
1134         size+=size_of_uint32( &info->status);
1135         size+=size_of_uint32( &info->unknown20);
1136         size+=size_of_uint32( &info->c_setprinter);
1137         
1138         size+=size_of_uint16( &info->unknown22);
1139         size+=size_of_uint16( &info->unknown23);
1140         size+=size_of_uint16( &info->unknown24);
1141         size+=size_of_uint16( &info->unknown25);
1142         size+=size_of_uint16( &info->unknown26);
1143         size+=size_of_uint16( &info->unknown27);
1144         size+=size_of_uint16( &info->unknown28);
1145         size+=size_of_uint16( &info->unknown29);
1146         
1147         return size;
1148 }
1149
1150 /*******************************************************************
1151 return the size required by a struct in the stream
1152 ********************************************************************/  
1153
1154 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
1155 {
1156         int size=0;
1157                 
1158         size+=size_of_uint32( &info->flags );   
1159         size+=size_of_relative_string( &info->description );
1160         size+=size_of_relative_string( &info->name );
1161         size+=size_of_relative_string( &info->comment );
1162
1163         return size;
1164 }
1165
1166 /*******************************************************************
1167 return the size required by a struct in the stream
1168 ********************************************************************/
1169
1170 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
1171 {
1172         uint32 size=0;
1173                 
1174         size += 4;
1175         
1176         size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
1177
1178         size+=size_of_device_mode( info->devmode );
1179         
1180         size+=size_of_relative_string( &info->servername );
1181         size+=size_of_relative_string( &info->printername );
1182         size+=size_of_relative_string( &info->sharename );
1183         size+=size_of_relative_string( &info->portname );
1184         size+=size_of_relative_string( &info->drivername );
1185         size+=size_of_relative_string( &info->comment );
1186         size+=size_of_relative_string( &info->location );
1187         
1188         size+=size_of_relative_string( &info->sepfile );
1189         size+=size_of_relative_string( &info->printprocessor );
1190         size+=size_of_relative_string( &info->datatype );
1191         size+=size_of_relative_string( &info->parameters );
1192
1193         size+=size_of_uint32( &info->attributes );
1194         size+=size_of_uint32( &info->priority );
1195         size+=size_of_uint32( &info->defaultpriority );
1196         size+=size_of_uint32( &info->starttime );
1197         size+=size_of_uint32( &info->untiltime );
1198         size+=size_of_uint32( &info->status );
1199         size+=size_of_uint32( &info->cjobs );
1200         size+=size_of_uint32( &info->averageppm );      
1201                 
1202         /* 
1203          * add any adjustments for alignment.  This is
1204          * not optimal since we could be calling this
1205          * function from a loop (e.g. enumprinters), but 
1206          * it is easier to maintain the calculation here and
1207          * not place the burden on the caller to remember.   --jerry
1208          */
1209         if ((size % 4) != 0)
1210                 size += 4 - (size % 4);
1211         
1212         return size;
1213 }
1214
1215 /*******************************************************************
1216 return the size required by a struct in the stream
1217 ********************************************************************/
1218
1219 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
1220 {
1221         uint32 size=0;
1222                 
1223         size+=size_of_relative_string( &info->printername );
1224         size+=size_of_relative_string( &info->servername );
1225
1226         size+=size_of_uint32( &info->attributes );
1227         return size;
1228 }
1229
1230 /*******************************************************************
1231 return the size required by a struct in the stream
1232 ********************************************************************/
1233
1234 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
1235 {
1236         uint32 size=0;
1237                 
1238         size+=size_of_relative_string( &info->printername );
1239         size+=size_of_relative_string( &info->portname );
1240
1241         size+=size_of_uint32( &info->attributes );
1242         size+=size_of_uint32( &info->device_not_selected_timeout );
1243         size+=size_of_uint32( &info->transmission_retry_timeout );
1244         return size;
1245 }
1246
1247 /*******************************************************************
1248 return the size required by a struct in the stream
1249 ********************************************************************/
1250
1251 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
1252 {
1253         return sizeof(uint32);
1254 }
1255
1256 /*******************************************************************
1257 return the size required by a struct in the stream
1258 ********************************************************************/
1259
1260 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
1261 {
1262         /* The 8 is for the self relative pointer - 8 byte aligned.. */
1263         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
1264 }
1265
1266 /*******************************************************************
1267 return the size required by a struct in the stream
1268 ********************************************************************/
1269
1270 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
1271 {
1272         uint32 size=0;
1273                 
1274         size+=size_of_relative_string( &info->guid );
1275         size+=size_of_uint32( &info->action );
1276         return size;
1277 }
1278
1279 /*******************************************************************
1280 return the size required by a struct in the stream
1281 ********************************************************************/
1282
1283 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
1284 {
1285         int size=0;
1286         size+=size_of_relative_string( &info->name );
1287
1288         return size;
1289 }
1290
1291 /*******************************************************************
1292 return the size required by a struct in the stream
1293 ********************************************************************/
1294
1295 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
1296 {
1297         int size=0;
1298         size+=size_of_uint32( &info->version ); 
1299         size+=size_of_relative_string( &info->name );
1300         size+=size_of_relative_string( &info->architecture );
1301         size+=size_of_relative_string( &info->driverpath );
1302         size+=size_of_relative_string( &info->datafile );
1303         size+=size_of_relative_string( &info->configfile );
1304
1305         return size;
1306 }
1307
1308 /*******************************************************************
1309 return the size required by a string array.
1310 ********************************************************************/
1311
1312 uint32 spoolss_size_string_array(uint16 *string)
1313 {
1314         uint32 i = 0;
1315
1316         if (string) {
1317                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
1318         }
1319         i=i+2; /* to count all chars including the leading zero */
1320         i=2*i; /* because we need the value in bytes */
1321         i=i+4; /* the offset pointer size */
1322
1323         return i;
1324 }
1325
1326 /*******************************************************************
1327 return the size required by a struct in the stream
1328 ********************************************************************/
1329
1330 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
1331 {
1332         int size=0;
1333
1334         size+=size_of_uint32( &info->version ); 
1335         size+=size_of_relative_string( &info->name );
1336         size+=size_of_relative_string( &info->architecture );
1337         size+=size_of_relative_string( &info->driverpath );
1338         size+=size_of_relative_string( &info->datafile );
1339         size+=size_of_relative_string( &info->configfile );
1340         size+=size_of_relative_string( &info->helpfile );
1341         size+=size_of_relative_string( &info->monitorname );
1342         size+=size_of_relative_string( &info->defaultdatatype );
1343         
1344         size+=spoolss_size_string_array(info->dependentfiles);
1345
1346         return size;
1347 }
1348
1349 /*******************************************************************
1350 return the size required by a struct in the stream
1351 ********************************************************************/
1352
1353 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
1354 {
1355         uint32 size=0;
1356
1357         size+=size_of_uint32( &info->version ); 
1358         size+=size_of_relative_string( &info->name );
1359         size+=size_of_relative_string( &info->architecture );
1360         size+=size_of_relative_string( &info->driverpath );
1361         size+=size_of_relative_string( &info->datafile );
1362         size+=size_of_relative_string( &info->configfile );
1363         size+=size_of_relative_string( &info->helpfile );
1364
1365         size+=spoolss_size_string_array(info->dependentfiles);
1366
1367         size+=size_of_relative_string( &info->monitorname );
1368         size+=size_of_relative_string( &info->defaultdatatype );
1369         
1370         size+=spoolss_size_string_array(info->previousdrivernames);
1371
1372         size+=size_of_nttime(&info->driver_date);
1373         size+=size_of_uint32( &info->padding ); 
1374         size+=size_of_uint32( &info->driver_version_low );      
1375         size+=size_of_uint32( &info->driver_version_high );     
1376         size+=size_of_relative_string( &info->mfgname );
1377         size+=size_of_relative_string( &info->oem_url );
1378         size+=size_of_relative_string( &info->hardware_id );
1379         size+=size_of_relative_string( &info->provider );
1380
1381         return size;
1382 }
1383
1384 /*******************************************************************
1385 return the size required by a struct in the stream
1386 ********************************************************************/  
1387
1388 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
1389 {
1390         int size=0;
1391         size+=size_of_uint32( &info->jobid );
1392         size+=size_of_relative_string( &info->printername );
1393         size+=size_of_relative_string( &info->machinename );
1394         size+=size_of_relative_string( &info->username );
1395         size+=size_of_relative_string( &info->document );
1396         size+=size_of_relative_string( &info->datatype );
1397         size+=size_of_relative_string( &info->text_status );
1398         size+=size_of_uint32( &info->status );
1399         size+=size_of_uint32( &info->priority );
1400         size+=size_of_uint32( &info->position );
1401         size+=size_of_uint32( &info->totalpages );
1402         size+=size_of_uint32( &info->pagesprinted );
1403         size+=size_of_systemtime( &info->submitted );
1404
1405         return size;
1406 }
1407
1408 /*******************************************************************
1409 return the size required by a struct in the stream
1410 ********************************************************************/  
1411
1412 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
1413 {
1414         int size=0;
1415
1416         size+=4; /* size of sec desc ptr */
1417
1418         size+=size_of_uint32( &info->jobid );
1419         size+=size_of_relative_string( &info->printername );
1420         size+=size_of_relative_string( &info->machinename );
1421         size+=size_of_relative_string( &info->username );
1422         size+=size_of_relative_string( &info->document );
1423         size+=size_of_relative_string( &info->notifyname );
1424         size+=size_of_relative_string( &info->datatype );
1425         size+=size_of_relative_string( &info->printprocessor );
1426         size+=size_of_relative_string( &info->parameters );
1427         size+=size_of_relative_string( &info->drivername );
1428         size+=size_of_device_mode( info->devmode );
1429         size+=size_of_relative_string( &info->text_status );
1430 /*      SEC_DESC sec_desc;*/
1431         size+=size_of_uint32( &info->status );
1432         size+=size_of_uint32( &info->priority );
1433         size+=size_of_uint32( &info->position );
1434         size+=size_of_uint32( &info->starttime );
1435         size+=size_of_uint32( &info->untiltime );
1436         size+=size_of_uint32( &info->totalpages );
1437         size+=size_of_uint32( &info->size );
1438         size+=size_of_systemtime( &info->submitted );
1439         size+=size_of_uint32( &info->timeelapsed );
1440         size+=size_of_uint32( &info->pagesprinted );
1441
1442         return size;
1443 }
1444
1445 /*******************************************************************
1446 return the size required by a struct in the stream
1447 ********************************************************************/  
1448 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
1449 {
1450         uint32  size = 0; 
1451         
1452         if (!p)
1453                 return 0;
1454         
1455         /* uint32(offset) + uint32(length) + length) */
1456         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
1457         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
1458         
1459         size += size_of_uint32(&p->type);
1460                        
1461         return size;
1462 }
1463
1464 /*******************************************************************
1465  * read a structure.
1466  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
1467  ********************************************************************/
1468
1469 bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
1470 {
1471         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
1472         depth++;
1473
1474         if(!prs_align(ps))
1475                 return False;
1476         
1477         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1478                 return False;
1479         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
1480                 return False;
1481         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
1482                 return False;
1483         
1484         if(!prs_align(ps))
1485                 return False;
1486         if(!prs_uint32("level", ps, depth, &q_u->level))
1487                 return False;
1488                 
1489         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1490                 return False;
1491
1492         if(!prs_align(ps))
1493                 return False;
1494
1495         if(!prs_uint32("offered", ps, depth, &q_u->offered))
1496                 return False;
1497                 
1498         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
1499                 return False;
1500         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
1501                 return False;
1502
1503         return True;
1504 }
1505
1506 /*******************************************************************
1507  * read a structure.
1508  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
1509  ********************************************************************/
1510
1511 bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
1512 {
1513         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
1514         depth++;
1515
1516         if (!prs_align(ps))
1517                 return False;
1518                 
1519         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1520                 return False;
1521
1522         if (!prs_align(ps))
1523                 return False;
1524         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1525                 return False;
1526         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
1527                 return False;
1528         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
1529                 return False;           
1530         if (!prs_werror("status", ps, depth, &r_u->status))
1531                 return False;
1532
1533         return True;            
1534 }
1535
1536 /*******************************************************************
1537  * init a structure.
1538  ********************************************************************/
1539
1540 bool make_spoolss_q_enumprinters(
1541         SPOOL_Q_ENUMPRINTERS *q_u, 
1542         uint32 flags, 
1543         char *servername, 
1544         uint32 level, 
1545         RPC_BUFFER *buffer, 
1546         uint32 offered
1547 )
1548 {
1549         q_u->flags=flags;
1550         
1551         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
1552         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
1553
1554         q_u->level=level;
1555         q_u->buffer=buffer;
1556         q_u->offered=offered;
1557
1558         return True;
1559 }
1560
1561 /*******************************************************************
1562  * read a structure.
1563  * called from spoolss_enumprinters (srv_spoolss.c)
1564  ********************************************************************/
1565
1566 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
1567 {
1568         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
1569         depth++;
1570
1571         if (!prs_align(ps))
1572                 return False;
1573
1574         if (!prs_uint32("flags", ps, depth, &q_u->flags))
1575                 return False;
1576         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
1577                 return False;
1578
1579         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
1580                 return False;
1581                 
1582         if (!prs_align(ps))
1583                 return False;
1584         if (!prs_uint32("level", ps, depth, &q_u->level))
1585                 return False;
1586
1587         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1588                 return False;
1589
1590         if (!prs_align(ps))
1591                 return False;
1592         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1593                 return False;
1594
1595         return True;
1596 }
1597
1598 /*******************************************************************
1599  Parse a SPOOL_R_ENUMPRINTERS structure.
1600  ********************************************************************/
1601
1602 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
1603 {
1604         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
1605         depth++;
1606
1607         if (!prs_align(ps))
1608                 return False;
1609                 
1610         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1611                 return False;
1612
1613         if (!prs_align(ps))
1614                 return False;
1615                 
1616         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1617                 return False;
1618                 
1619         if (!prs_uint32("returned", ps, depth, &r_u->returned))
1620                 return False;
1621                 
1622         if (!prs_werror("status", ps, depth, &r_u->status))
1623                 return False;
1624
1625         return True;            
1626 }
1627
1628 /*******************************************************************
1629  * write a structure.
1630  * called from spoolss_r_enum_printers (srv_spoolss.c)
1631  *
1632  ********************************************************************/
1633
1634 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
1635 {       
1636         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
1637         depth++;
1638
1639         if (!prs_align(ps))
1640                 return False;
1641                 
1642         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1643                 return False;
1644
1645         if (!prs_align(ps))
1646                 return False;
1647
1648         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1649                 return False;
1650                 
1651         if (!prs_werror("status", ps, depth, &r_u->status))
1652                 return False;
1653
1654         return True;            
1655 }
1656
1657 /*******************************************************************
1658  * read a structure.
1659  * called from spoolss_getprinter (srv_spoolss.c)
1660  ********************************************************************/
1661
1662 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
1663 {
1664         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
1665         depth++;
1666
1667         if (!prs_align(ps))
1668                 return False;
1669
1670         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1671                 return False;
1672         if (!prs_uint32("level", ps, depth, &q_u->level))
1673                 return False;
1674
1675         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1676                 return False;
1677
1678         if (!prs_align(ps))
1679                 return False;
1680         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1681                 return False;
1682
1683         return True;
1684 }
1685
1686 /*******************************************************************
1687 ********************************************************************/  
1688
1689 bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
1690 {               
1691         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
1692         depth++;
1693
1694         if (!prs_align(ps))
1695                 return False;
1696                 
1697         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1698                 return False;
1699
1700         if (!prs_align(ps))
1701                 return False;
1702                 
1703         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1704                 return False;
1705                 
1706         if (!prs_uint32("returned", ps, depth, &r_u->returned))
1707                 return False;
1708                 
1709         if (!prs_werror("status", ps, depth, &r_u->status))
1710                 return False;
1711
1712         return True;            
1713 }
1714
1715 /*******************************************************************
1716 ********************************************************************/  
1717
1718 bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
1719                                 uint32 firstjob,
1720                                 uint32 numofjobs,
1721                                 uint32 level,
1722                                 RPC_BUFFER *buffer,
1723                                 uint32 offered)
1724 {
1725         if (q_u == NULL)
1726         {
1727                 return False;
1728         }
1729         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1730         q_u->firstjob = firstjob;
1731         q_u->numofjobs = numofjobs;
1732         q_u->level = level;
1733         q_u->buffer= buffer;
1734         q_u->offered = offered;
1735         return True;
1736 }
1737
1738 /*******************************************************************
1739 ********************************************************************/  
1740
1741 bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
1742 {
1743         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
1744         depth++;
1745
1746         if (!prs_align(ps))
1747                 return False;
1748
1749         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
1750                 return False;
1751                 
1752         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
1753                 return False;
1754         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
1755                 return False;
1756         if (!prs_uint32("level", ps, depth, &q_u->level))
1757                 return False;
1758
1759         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1760                 return False;   
1761
1762         if(!prs_align(ps))
1763                 return False;
1764
1765         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1766                 return False;
1767
1768         return True;
1769 }
1770
1771 /*******************************************************************
1772  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
1773 ********************************************************************/  
1774
1775 bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
1776 {
1777         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
1778         depth++;
1779
1780         if (!prs_align(ps))
1781                 return False;
1782                 
1783         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1784                 return False;
1785
1786         if (!prs_align(ps))
1787                 return False;
1788                 
1789         if (!prs_uint32("needed", ps, depth, &r_u->needed))
1790                 return False;
1791                 
1792         if (!prs_uint32("returned", ps, depth, &r_u->returned))
1793                 return False;
1794                 
1795         if (!prs_werror("status", ps, depth, &r_u->status))
1796                 return False;
1797
1798         return True;            
1799 }
1800
1801 /*******************************************************************
1802  * init a structure.
1803  ********************************************************************/
1804
1805 bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
1806                                 const char *name,
1807                                 const char *environment,
1808                                 uint32 level,
1809                                 RPC_BUFFER *buffer, uint32 offered)
1810 {
1811         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
1812         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
1813
1814         q_u->level=level;
1815         q_u->buffer=buffer;
1816         q_u->offered=offered;
1817
1818         return True;
1819 }
1820
1821 /*******************************************************************
1822  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
1823 ********************************************************************/  
1824
1825 bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
1826 {
1827
1828         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
1829         depth++;
1830
1831         if (!prs_align(ps))
1832                 return False;
1833                 
1834         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
1835                 return False;
1836         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
1837                 return False;
1838                 
1839         if (!prs_align(ps))
1840                 return False;
1841         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
1842                 return False;
1843         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
1844                 return False;
1845                 
1846         if (!prs_align(ps))
1847                 return False;
1848         if (!prs_uint32("level", ps, depth, &q_u->level))
1849                 return False;
1850                 
1851         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1852                 return False;
1853
1854         if (!prs_align(ps))
1855                 return False;
1856                 
1857         if (!prs_uint32("offered", ps, depth, &q_u->offered))
1858                 return False;
1859
1860         return True;
1861 }
1862
1863 /*******************************************************************
1864  make a BUFFER5 struct from a uint16*
1865  ******************************************************************/
1866
1867 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
1868 {
1869
1870         buf5->buf_len = len;
1871         if (src) {
1872                 if (len) {
1873                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
1874                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
1875                                 return False;
1876                         }
1877                 } else {
1878                         buf5->buffer = NULL;
1879                 }
1880         } else {
1881                 buf5->buffer=NULL;
1882         }
1883         
1884         return True;
1885 }
1886
1887 /*******************************************************************
1888 ********************************************************************/  
1889
1890 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
1891 {       
1892         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
1893         depth++;
1894
1895         if(!prs_align(ps))
1896                 return False;
1897         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
1898                 return False;
1899
1900         if (UNMARSHALLING(ps) && r_u->valuesize) {
1901                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
1902                 if (!r_u->value) {
1903                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
1904                         return False;
1905                 }
1906         }
1907
1908         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
1909                 return False;
1910
1911         if(!prs_align(ps))
1912                 return False;
1913
1914         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
1915                 return False;
1916
1917         if(!prs_uint32("type", ps, depth, &r_u->type))
1918                 return False;
1919
1920         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
1921                 return False;
1922
1923         if (UNMARSHALLING(ps) && r_u->datasize) {
1924                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
1925                 if (!r_u->data) {
1926                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
1927                         return False;
1928                 }
1929         }
1930
1931         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
1932                 return False;
1933         if(!prs_align(ps))
1934                 return False;
1935
1936         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
1937                 return False;
1938         if(!prs_werror("status", ps, depth, &r_u->status))
1939                 return False;
1940
1941         return True;
1942 }
1943
1944 /*******************************************************************
1945 ********************************************************************/  
1946
1947 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
1948 {
1949         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
1950         depth++;
1951
1952         if(!prs_align(ps))
1953                 return False;
1954         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1955                 return False;
1956         if(!prs_uint32("index", ps, depth, &q_u->index))
1957                 return False;
1958         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
1959                 return False;
1960         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
1961                 return False;
1962
1963         return True;
1964 }
1965
1966 /*******************************************************************
1967 ********************************************************************/  
1968
1969 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
1970                 const POLICY_HND *hnd,
1971                 uint32 idx, uint32 valuelen, uint32 datalen)
1972 {
1973         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1974         q_u->index=idx;
1975         q_u->valuesize=valuelen;
1976         q_u->datasize=datalen;
1977
1978         return True;
1979 }
1980
1981 /*******************************************************************
1982 ********************************************************************/  
1983
1984 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
1985                                       const POLICY_HND *hnd, const char *key,
1986                                       uint32 size)
1987 {
1988         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1989         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
1990         q_u->size = size;
1991
1992         return True;
1993 }
1994
1995 /*******************************************************************
1996 ********************************************************************/  
1997 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
1998                                    char* value, uint32 data_type, char* data, uint32 data_size)
1999 {
2000         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2001         q_u->type = data_type;
2002         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
2003
2004         q_u->max_len = q_u->real_len = data_size;
2005         q_u->data = (unsigned char *)data;
2006         
2007         return True;
2008 }
2009
2010 /*******************************************************************
2011 ********************************************************************/  
2012
2013 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
2014 {
2015         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
2016         depth++;
2017
2018         if(!prs_align(ps))
2019                 return False;
2020         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2021                 return False;
2022         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
2023                 return False;
2024
2025         if(!prs_align(ps))
2026                 return False;
2027
2028         if(!prs_uint32("type", ps, depth, &q_u->type))
2029                 return False;
2030
2031         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
2032                 return False;
2033
2034         switch (q_u->type)
2035         {
2036                 case REG_SZ:
2037                 case REG_BINARY:
2038                 case REG_DWORD:
2039                 case REG_MULTI_SZ:
2040                         if (q_u->max_len) {
2041                                 if (UNMARSHALLING(ps))
2042                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
2043                                 if(q_u->data == NULL)
2044                                         return False;
2045                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
2046                                         return False;
2047                         }
2048                         if(!prs_align(ps))
2049                                 return False;
2050                         break;
2051         }       
2052         
2053         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
2054                 return False;
2055
2056         return True;
2057 }
2058
2059 /*******************************************************************
2060 ********************************************************************/  
2061
2062 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
2063 {
2064         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
2065         depth++;
2066
2067         if(!prs_align(ps))
2068                 return False;
2069         if(!prs_werror("status",     ps, depth, &r_u->status))
2070                 return False;
2071
2072         return True;
2073 }
2074
2075 /*******************************************************************
2076  Parse a SPOOL_R_GETJOB structure.
2077 ********************************************************************/  
2078
2079 bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
2080 {               
2081         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
2082         depth++;
2083
2084         if (!prs_align(ps))
2085                 return False;
2086                 
2087         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2088                 return False;
2089
2090         if (!prs_align(ps))
2091                 return False;
2092                 
2093         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2094                 return False;
2095                 
2096         if (!prs_werror("status", ps, depth, &r_u->status))
2097                 return False;
2098
2099         return True;            
2100 }
2101
2102 /*******************************************************************
2103  Parse a SPOOL_Q_GETJOB structure.
2104 ********************************************************************/  
2105
2106 bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
2107 {
2108         prs_debug(ps, depth, desc, "");
2109         depth++;
2110
2111         if(!prs_align(ps))
2112                 return False;
2113
2114         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
2115                 return False;
2116         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
2117                 return False;
2118         if(!prs_uint32("level", ps, depth, &q_u->level))
2119                 return False;
2120         
2121         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2122                 return False;
2123
2124         if(!prs_align(ps))
2125                 return False;
2126         
2127         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2128                 return False;
2129
2130         return True;
2131 }
2132
2133 void free_devmode(DEVICEMODE *devmode)
2134 {
2135         if (devmode!=NULL) {
2136                 SAFE_FREE(devmode->dev_private);
2137                 SAFE_FREE(devmode);
2138         }
2139 }
2140
2141 void free_printer_info_1(PRINTER_INFO_1 *printer)
2142 {
2143         SAFE_FREE(printer);
2144 }
2145
2146 void free_printer_info_2(PRINTER_INFO_2 *printer)
2147 {
2148         if (printer!=NULL) {
2149                 free_devmode(printer->devmode);
2150                 printer->devmode = NULL;
2151                 SAFE_FREE(printer);
2152         }
2153 }
2154
2155 void free_printer_info_3(PRINTER_INFO_3 *printer)
2156 {
2157         SAFE_FREE(printer);
2158 }
2159
2160 void free_printer_info_4(PRINTER_INFO_4 *printer)
2161 {
2162         SAFE_FREE(printer);
2163 }
2164
2165 void free_printer_info_5(PRINTER_INFO_5 *printer)
2166 {
2167         SAFE_FREE(printer);
2168 }
2169
2170 void free_printer_info_6(PRINTER_INFO_6 *printer)
2171 {
2172         SAFE_FREE(printer);
2173 }
2174
2175 void free_printer_info_7(PRINTER_INFO_7 *printer)
2176 {
2177         SAFE_FREE(printer);
2178 }
2179
2180 void free_job_info_2(JOB_INFO_2 *job)
2181 {
2182     if (job!=NULL)
2183         free_devmode(job->devmode);
2184 }
2185
2186 /*******************************************************************
2187  * read a structure.
2188  ********************************************************************/  
2189 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
2190                                    POLICY_HND *hnd, const char *key, 
2191                                    uint32 size)
2192 {
2193         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
2194
2195         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2196         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
2197         q_u->size = size;
2198
2199         return True;
2200 }
2201
2202 /*******************************************************************
2203  * read a structure.
2204  ********************************************************************/  
2205
2206 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
2207 {
2208         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
2209         depth++;
2210
2211         if(!prs_align(ps))
2212                 return False;
2213         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2214                 return False;
2215                 
2216         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
2217                 return False;
2218
2219         if(!prs_align(ps))
2220                 return False;
2221         
2222         if(!prs_uint32("size", ps, depth, &q_u->size))
2223                 return False;
2224
2225         return True;
2226 }
2227
2228 /*******************************************************************
2229  * write a structure.
2230  ********************************************************************/  
2231
2232 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
2233 {
2234         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
2235         depth++;
2236
2237         if(!prs_align(ps))
2238                 return False;
2239
2240         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
2241                 return False;
2242         
2243         if(!prs_align(ps))
2244                 return False;
2245
2246         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
2247                 return False;
2248
2249         if(!prs_werror("status",     ps, depth, &r_u->status))
2250                 return False;
2251
2252         return True;
2253 }
2254
2255 /*******************************************************************
2256  * read a structure.
2257  ********************************************************************/  
2258
2259 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
2260 {
2261         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
2262         depth++;
2263
2264         if(!prs_align(ps))
2265                 return False;
2266         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2267                 return False;
2268                 
2269         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
2270                 return False;
2271
2272         if(!prs_align(ps))
2273                 return False;
2274         
2275         if(!prs_uint32("size", ps, depth, &q_u->size))
2276                 return False;
2277
2278         return True;
2279 }
2280
2281 /*******************************************************************
2282 ********************************************************************/  
2283
2284 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
2285                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
2286 {
2287         int     i;
2288         uint32  valuename_offset,
2289                 data_offset,
2290                 current_offset;
2291         const uint32 basic_unit = 20; /* size of static portion of enum_values */
2292
2293         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
2294         depth++;        
2295
2296         /* 
2297          * offset data begins at 20 bytes per structure * size_of_array.
2298          * Don't forget the uint32 at the beginning 
2299          * */
2300         
2301         current_offset = basic_unit * ctr->size_of_array;
2302         
2303         /* first loop to write basic enum_value information */
2304         
2305         if (UNMARSHALLING(ps) && ctr->size_of_array) {
2306                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
2307                 if (!ctr->values)
2308                         return False;
2309         }
2310
2311         for (i=0; i<ctr->size_of_array; i++) {
2312                 uint32 base_offset, return_offset;
2313
2314                 base_offset = prs_offset(ps);
2315
2316                 valuename_offset = current_offset;
2317                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
2318                         return False;
2319
2320                 /* Read or write the value. */
2321
2322                 return_offset = prs_offset(ps);
2323
2324                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
2325                         return False;
2326                 }
2327
2328                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
2329                         return False;
2330
2331                 /* And go back. */
2332                 if (!prs_set_offset(ps, return_offset))
2333                         return False;
2334
2335                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
2336                         return False;
2337         
2338                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
2339                         return False;
2340         
2341                 data_offset = ctr->values[i].value_len + valuename_offset;
2342                 
2343                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
2344                         return False;
2345
2346                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
2347                         return False;
2348                         
2349                 /* Read or write the data. */
2350
2351                 return_offset = prs_offset(ps);
2352
2353                 if (!prs_set_offset(ps, base_offset + data_offset)) {
2354                         return False;
2355                 }
2356
2357                 if ( ctr->values[i].data_len ) {
2358                         if ( UNMARSHALLING(ps) ) {
2359                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
2360                                 if (!ctr->values[i].data)
2361                                         return False;
2362                         }
2363                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
2364                                 return False;
2365                 }
2366
2367                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
2368                 /* account for 2 byte alignment */
2369                 current_offset += (current_offset % 2);
2370
2371                 /* Remember how far we got. */
2372                 data_offset = prs_offset(ps);
2373
2374                 /* And go back. */
2375                 if (!prs_set_offset(ps, return_offset))
2376                         return False;
2377
2378         }
2379
2380         /* Go to the last data offset we got to. */
2381
2382         if (!prs_set_offset(ps, data_offset))
2383                 return False;
2384
2385         /* And ensure we're 2 byte aligned. */
2386
2387         if ( !prs_align_uint16(ps) )
2388                 return False;
2389
2390         return True;    
2391 }
2392
2393 /*******************************************************************
2394  * write a structure.
2395  ********************************************************************/  
2396
2397 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
2398 {
2399         uint32 data_offset, end_offset;
2400         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
2401         depth++;
2402
2403         if(!prs_align(ps))
2404                 return False;
2405
2406         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
2407                 return False;
2408
2409         data_offset = prs_offset(ps);
2410
2411         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
2412                 return False;
2413
2414         if(!prs_align(ps))
2415                 return False;
2416
2417         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
2418                 return False;
2419
2420         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
2421                 return False;
2422
2423         if(!prs_werror("status",     ps, depth, &r_u->status))
2424                 return False;
2425
2426         r_u->ctr.size_of_array = r_u->returned;
2427
2428         end_offset = prs_offset(ps);
2429
2430         if (!prs_set_offset(ps, data_offset))
2431                 return False;
2432
2433         if (r_u->ctr.size)
2434                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
2435                         return False;
2436
2437         if (!prs_set_offset(ps, end_offset))
2438                 return False;
2439         return True;
2440 }