Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
[ira/wip.git] / source3 / rpc_parse / parse_spoolss.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean François Micouleau      1998-2000,
7  *  Copyright (C) Gerald Carter                2000-2002,
8  *  Copyright (C) Tim Potter                   2001-2002.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 3 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "includes.h"
25
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29
30 /*******************************************************************
31 This should be moved in a more generic lib.
32 ********************************************************************/  
33
34 bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
35 {
36         if(!prs_uint16("year", ps, depth, &systime->year))
37                 return False;
38         if(!prs_uint16("month", ps, depth, &systime->month))
39                 return False;
40         if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
41                 return False;
42         if(!prs_uint16("day", ps, depth, &systime->day))
43                 return False;
44         if(!prs_uint16("hour", ps, depth, &systime->hour))
45                 return False;
46         if(!prs_uint16("minute", ps, depth, &systime->minute))
47                 return False;
48         if(!prs_uint16("second", ps, depth, &systime->second))
49                 return False;
50         if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
51                 return False;
52
53         return True;
54 }
55
56 /*******************************************************************
57 ********************************************************************/  
58
59 bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
60 {
61         systime->year=unixtime->tm_year+1900;
62         systime->month=unixtime->tm_mon+1;
63         systime->dayofweek=unixtime->tm_wday;
64         systime->day=unixtime->tm_mday;
65         systime->hour=unixtime->tm_hour;
66         systime->minute=unixtime->tm_min;
67         systime->second=unixtime->tm_sec;
68         systime->milliseconds=0;
69
70         return True;
71 }
72
73 /*******************************************************************
74 ********************************************************************/  
75
76 bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u )
77 {
78         prs_debug(ps, depth, desc, "");
79         depth++;
80
81         if (!prs_align(ps))
82                 return False;
83
84         if (!prs_uint32("size", ps, depth, &q_u->size))
85                 return False;
86
87         if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name))
88                 return False;
89         if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name))
90                 return False;
91
92         if (!prs_uint32("build", ps, depth, &q_u->build))
93                 return False;
94         if (!prs_uint32("major", ps, depth, &q_u->major))
95                 return False;
96         if (!prs_uint32("minor", ps, depth, &q_u->minor))
97                 return False;
98         if (!prs_uint32("processor", ps, depth, &q_u->processor))
99                 return False;
100
101         if (!prs_io_unistr2("", ps, depth, q_u->client_name))
102                 return False;
103         if (!prs_align(ps))
104                 return False;
105
106         if (!prs_io_unistr2("", ps, depth, q_u->user_name))
107                 return False;
108
109         return True;
110 }
111
112 /*******************************************************************
113 ********************************************************************/  
114
115 static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
116 {
117         if (q_u==NULL)
118                 return False;
119
120         prs_debug(ps, depth, desc, "spool_io_user_level");
121         depth++;
122
123         if (!prs_align(ps))
124                 return False;
125
126         if (!prs_uint32("level", ps, depth, &q_u->level))
127                 return False;
128         
129         switch ( q_u->level ) 
130         {       
131                 case 1:
132                         if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, 
133                                 sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) 
134                         {
135                                 return False;
136                         }
137                         break;
138                 default:
139                         return False;   
140         }       
141
142         return True;
143 }
144
145 /*******************************************************************
146  * read or write a DEVICEMODE struct.
147  * on reading allocate memory for the private member
148  ********************************************************************/
149
150 #define DM_NUM_OPTIONAL_FIELDS          8
151
152 bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
153 {
154         int available_space;            /* size of the device mode left to parse */
155                                         /* only important on unmarshalling       */
156         int i = 0;
157         uint16 *unistr_buffer;
158         int j;
159                                         
160         struct optional_fields {
161                 fstring         name;
162                 uint32*         field;
163         } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
164                 { "icmmethod",          NULL },
165                 { "icmintent",          NULL },
166                 { "mediatype",          NULL },
167                 { "dithertype",         NULL },
168                 { "reserved1",          NULL },
169                 { "reserved2",          NULL },
170                 { "panningwidth",       NULL },
171                 { "panningheight",      NULL }
172         };
173
174         /* assign at run time to keep non-gcc compilers happy */
175
176         opt_fields[0].field = &devmode->icmmethod;
177         opt_fields[1].field = &devmode->icmintent;
178         opt_fields[2].field = &devmode->mediatype;
179         opt_fields[3].field = &devmode->dithertype;
180         opt_fields[4].field = &devmode->reserved1;
181         opt_fields[5].field = &devmode->reserved2;
182         opt_fields[6].field = &devmode->panningwidth;
183         opt_fields[7].field = &devmode->panningheight;
184                 
185         
186         prs_debug(ps, depth, desc, "spoolss_io_devmode");
187         depth++;
188
189         if (UNMARSHALLING(ps)) {
190                 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
191                 if (devmode->devicename.buffer == NULL)
192                         return False;
193                 unistr_buffer = devmode->devicename.buffer;
194         }
195         else {
196                 /* devicename is a static sized string but the buffer we set is not */
197                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
198                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
199                 for ( j=0; devmode->devicename.buffer[j]; j++ )
200                         unistr_buffer[j] = devmode->devicename.buffer[j];
201         }
202                 
203         if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
204                 return False;
205         
206         if (!prs_uint16("specversion",      ps, depth, &devmode->specversion))
207                 return False;
208                 
209         if (!prs_uint16("driverversion",    ps, depth, &devmode->driverversion))
210                 return False;
211         if (!prs_uint16("size",             ps, depth, &devmode->size))
212                 return False;
213         if (!prs_uint16("driverextra",      ps, depth, &devmode->driverextra))
214                 return False;
215         if (!prs_uint32("fields",           ps, depth, &devmode->fields))
216                 return False;
217         if (!prs_uint16("orientation",      ps, depth, &devmode->orientation))
218                 return False;
219         if (!prs_uint16("papersize",        ps, depth, &devmode->papersize))
220                 return False;
221         if (!prs_uint16("paperlength",      ps, depth, &devmode->paperlength))
222                 return False;
223         if (!prs_uint16("paperwidth",       ps, depth, &devmode->paperwidth))
224                 return False;
225         if (!prs_uint16("scale",            ps, depth, &devmode->scale))
226                 return False;
227         if (!prs_uint16("copies",           ps, depth, &devmode->copies))
228                 return False;
229         if (!prs_uint16("defaultsource",    ps, depth, &devmode->defaultsource))
230                 return False;
231         if (!prs_uint16("printquality",     ps, depth, &devmode->printquality))
232                 return False;
233         if (!prs_uint16("color",            ps, depth, &devmode->color))
234                 return False;
235         if (!prs_uint16("duplex",           ps, depth, &devmode->duplex))
236                 return False;
237         if (!prs_uint16("yresolution",      ps, depth, &devmode->yresolution))
238                 return False;
239         if (!prs_uint16("ttoption",         ps, depth, &devmode->ttoption))
240                 return False;
241         if (!prs_uint16("collate",          ps, depth, &devmode->collate))
242                 return False;
243
244         if (UNMARSHALLING(ps)) {
245                 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
246                 if (devmode->formname.buffer == NULL)
247                         return False;
248                 unistr_buffer = devmode->formname.buffer;
249         }
250         else {
251                 /* devicename is a static sized string but the buffer we set is not */
252                 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
253                 memset( unistr_buffer, 0x0, MAXDEVICENAME );
254                 for ( j=0; devmode->formname.buffer[j]; j++ )
255                         unistr_buffer[j] = devmode->formname.buffer[j];
256         }
257         
258         if (!prs_uint16uni(True, "formname",  ps, depth, unistr_buffer, MAXDEVICENAME))
259                 return False;
260         if (!prs_uint16("logpixels",        ps, depth, &devmode->logpixels))
261                 return False;
262         if (!prs_uint32("bitsperpel",       ps, depth, &devmode->bitsperpel))
263                 return False;
264         if (!prs_uint32("pelswidth",        ps, depth, &devmode->pelswidth))
265                 return False;
266         if (!prs_uint32("pelsheight",       ps, depth, &devmode->pelsheight))
267                 return False;
268         if (!prs_uint32("displayflags",     ps, depth, &devmode->displayflags))
269                 return False;
270         if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
271                 return False;
272         /* 
273          * every device mode I've ever seen on the wire at least has up 
274          * to the displayfrequency field.   --jerry (05-09-2002)
275          */
276          
277         /* add uint32's + uint16's + two UNICODE strings */
278          
279         available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
280         
281         /* Sanity check - we only have uint32's left tp parse */
282         
283         if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
284                 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
285                         available_space, devmode->size));
286                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
287                 return False;
288         }
289
290         /* 
291          * Conditional parsing.  Assume that the DeviceMode has been 
292          * zero'd by the caller. 
293          */
294         
295         while ((available_space > 0)  && (i < DM_NUM_OPTIONAL_FIELDS))
296         {
297                 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
298                 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
299                         return False;
300                 available_space -= sizeof(uint32);
301                 i++;
302         }        
303         
304         /* Sanity Check - we should no available space at this point unless 
305            MS changes the device mode structure */
306                 
307         if (available_space) {
308                 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
309                 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
310                         available_space, devmode->size));
311                 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
312                 return False;
313         }
314
315
316         if (devmode->driverextra!=0) {
317                 if (UNMARSHALLING(ps)) {
318                         devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
319                         if(devmode->dev_private == NULL)
320                                 return False;
321                         DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra)); 
322                 }
323                         
324                 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
325                 if (!prs_uint8s(False, "dev_private",  ps, depth,
326                                 devmode->dev_private, devmode->driverextra))
327                         return False;
328         }
329
330         return True;
331 }
332
333 /*******************************************************************
334  Read or write a DEVICEMODE container
335 ********************************************************************/  
336
337 static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
338 {
339         if (dm_c==NULL)
340                 return False;
341
342         prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
343         depth++;
344
345         if(!prs_align(ps))
346                 return False;
347         
348         if (!prs_uint32("size", ps, depth, &dm_c->size))
349                 return False;
350
351         if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
352                 return False;
353
354         if (dm_c->size==0 || dm_c->devmode_ptr==0) {
355                 if (UNMARSHALLING(ps))
356                         /* if while reading there is no DEVMODE ... */
357                         dm_c->devmode=NULL;
358                 return True;
359         }
360         
361         /* so we have a DEVICEMODE to follow */         
362         if (UNMARSHALLING(ps)) {
363                 DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
364                 dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1);
365                 if(dm_c->devmode == NULL)
366                         return False;
367         }
368         
369         /* this is bad code, shouldn't be there */
370         if (!prs_uint32("size", ps, depth, &dm_c->size))
371                 return False;
372                 
373         if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
374                 return False;
375
376         return True;
377 }
378
379 /*******************************************************************
380  * init a structure.
381  ********************************************************************/
382
383 bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, 
384         const char *srv_name, const char* clientname, const char* user_name,
385         uint32 level, PRINTER_INFO_CTR *ctr)
386 {
387         DEBUG(5,("make_spoolss_q_addprinterex\n"));
388         
389         if (!ctr || !ctr->printers_2) 
390                 return False;
391
392         ZERO_STRUCTP(q_u);
393
394         q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 );
395         if (!q_u->server_name) {
396                 return False;
397         }
398         init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE);
399
400         q_u->level = level;
401         
402         q_u->info.level = level;
403         q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0;
404         switch (level) {
405                 case 2:
406                         /* init q_u->info.info2 from *info */
407                         if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) {
408                                 DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
409                                 return False;
410                         }
411                         break;
412                 default :
413                         break;
414         }
415
416         q_u->user_switch=1;
417
418         q_u->user_ctr.level                 = 1;
419         q_u->user_ctr.user.user1            = TALLOC_P( talloc_tos(), SPOOL_USER_1 );
420         if (!q_u->user_ctr.user.user1) {
421                 return False;
422         }
423         q_u->user_ctr.user.user1->build     = 1381;
424         q_u->user_ctr.user.user1->major     = 2; 
425         q_u->user_ctr.user.user1->minor     = 0;
426         q_u->user_ctr.user.user1->processor = 0;
427
428         q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 );
429         if (!q_u->user_ctr.user.user1->client_name) {
430                 return False;
431         }
432         q_u->user_ctr.user.user1->user_name   = TALLOC_P( mem_ctx, UNISTR2 );
433         if (!q_u->user_ctr.user.user1->user_name) {
434                 return False;
435         }
436         init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE);
437         init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE);
438
439         q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len +
440                                    q_u->user_ctr.user.user1->client_name->uni_str_len + 2;
441         
442         return True;
443 }
444         
445 /*******************************************************************
446 create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
447 *******************************************************************/
448
449 bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, 
450                                 PRINTER_INFO_2 *info)
451 {
452
453         SPOOL_PRINTER_INFO_LEVEL_2 *inf;
454
455         /* allocate the necessary memory */
456         if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) {
457                 DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
458                 return False;
459         }
460
461         inf->servername_ptr     = (info->servername.buffer!=NULL)?1:0;
462         inf->printername_ptr    = (info->printername.buffer!=NULL)?1:0;
463         inf->sharename_ptr      = (info->sharename.buffer!=NULL)?1:0;
464         inf->portname_ptr       = (info->portname.buffer!=NULL)?1:0;
465         inf->drivername_ptr     = (info->drivername.buffer!=NULL)?1:0;
466         inf->comment_ptr        = (info->comment.buffer!=NULL)?1:0;
467         inf->location_ptr       = (info->location.buffer!=NULL)?1:0;
468         inf->devmode_ptr        = (info->devmode!=NULL)?1:0;
469         inf->sepfile_ptr        = (info->sepfile.buffer!=NULL)?1:0;
470         inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
471         inf->datatype_ptr       = (info->datatype.buffer!=NULL)?1:0;
472         inf->parameters_ptr     = (info->parameters.buffer!=NULL)?1:0;
473         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
474         inf->attributes         = info->attributes;
475         inf->priority           = info->priority;
476         inf->default_priority   = info->defaultpriority;
477         inf->starttime          = info->starttime;
478         inf->untiltime          = info->untiltime;
479         inf->cjobs              = info->cjobs;
480         inf->averageppm = info->averageppm;
481         init_unistr2_from_unistr(inf, &inf->servername, &info->servername);
482         init_unistr2_from_unistr(inf, &inf->printername, &info->printername);
483         init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename);
484         init_unistr2_from_unistr(inf, &inf->portname, &info->portname);
485         init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername);
486         init_unistr2_from_unistr(inf, &inf->comment, &info->comment);
487         init_unistr2_from_unistr(inf, &inf->location, &info->location);
488         init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile);
489         init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor);
490         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
491         init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters);
492         init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype);
493
494         *spool_info2 = inf;
495
496         return True;
497 }
498
499 /*******************************************************************
500 create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct
501 *******************************************************************/
502
503 bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, 
504                                 PRINTER_INFO_3 *info)
505 {
506
507         SPOOL_PRINTER_INFO_LEVEL_3 *inf;
508
509         /* allocate the necessary memory */
510         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) {
511                 DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n"));
512                 return False;
513         }
514         
515         inf->secdesc_ptr        = (info->secdesc!=NULL)?1:0;
516
517         *spool_info3 = inf;
518
519         return True;
520 }
521
522 /*******************************************************************
523 create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct
524 *******************************************************************/
525
526 bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, 
527                                 PRINTER_INFO_7 *info)
528 {
529
530         SPOOL_PRINTER_INFO_LEVEL_7 *inf;
531
532         /* allocate the necessary memory */
533         if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) {
534                 DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n"));
535                 return False;
536         }
537
538         inf->guid_ptr = (info->guid.buffer!=NULL)?1:0;
539         inf->action = info->action;
540         init_unistr2_from_unistr(inf, &inf->guid, &info->guid);
541
542         *spool_info7 = inf;
543
544         return True;
545 }
546
547 /*******************************************************************
548  * make a structure.
549  ********************************************************************/
550
551 bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
552                                    const POLICY_HND *handle,
553                                    const char *valuename, uint32 size)
554 {
555         if (q_u == NULL) return False;
556
557         DEBUG(5,("make_spoolss_q_getprinterdata\n"));
558
559         q_u->handle = *handle;
560         init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
561         q_u->size = size;
562
563         return True;
564 }
565
566 /*******************************************************************
567  * read a structure.
568  * called from spoolss_q_getprinterdata (srv_spoolss.c)
569  ********************************************************************/
570
571 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
572 {
573         if (q_u == NULL)
574                 return False;
575
576         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
577         depth++;
578
579         if (!prs_align(ps))
580                 return False;
581         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
582                 return False;
583         if (!prs_align(ps))
584                 return False;
585         if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
586                 return False;
587         if (!prs_align(ps))
588                 return False;
589         if (!prs_uint32("size", ps, depth, &q_u->size))
590                 return False;
591
592         return True;
593 }
594
595 /*******************************************************************
596  * write a structure.
597  * called from spoolss_r_getprinterdata (srv_spoolss.c)
598  ********************************************************************/
599
600 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
601 {
602         if (r_u == NULL)
603                 return False;
604
605         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
606         depth++;
607
608         if (!prs_align(ps))
609                 return False;
610         if (!prs_uint32("type", ps, depth, &r_u->type))
611                 return False;
612         if (!prs_uint32("size", ps, depth, &r_u->size))
613                 return False;
614         
615         if (UNMARSHALLING(ps) && r_u->size) {
616                 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
617                 if(!r_u->data)
618                         return False;
619         }
620
621         if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
622                 return False;
623                 
624         if (!prs_align(ps))
625                 return False;
626         
627         if (!prs_uint32("needed", ps, depth, &r_u->needed))
628                 return False;
629         if (!prs_werror("status", ps, depth, &r_u->status))
630                 return False;
631                 
632         return True;
633 }
634
635 /*******************************************************************
636  * return the length of a uint16 (obvious, but the code is clean)
637  ********************************************************************/
638
639 static uint32 size_of_uint16(uint16 *value)
640 {
641         return (sizeof(*value));
642 }
643
644 /*******************************************************************
645  * return the length of a uint32 (obvious, but the code is clean)
646  ********************************************************************/
647
648 static uint32 size_of_uint32(uint32 *value)
649 {
650         return (sizeof(*value));
651 }
652
653 /*******************************************************************
654  * return the length of a NTTIME (obvious, but the code is clean)
655  ********************************************************************/
656
657 static uint32 size_of_nttime(NTTIME *value)
658 {
659         return (sizeof(*value));
660 }
661
662 /*******************************************************************
663  * return the length of a uint32 (obvious, but the code is clean)
664  ********************************************************************/
665
666 static uint32 size_of_device_mode(DEVICEMODE *devmode)
667 {
668         if (devmode==NULL)
669                 return (4);
670         else 
671                 return (4+devmode->size+devmode->driverextra);
672 }
673
674 /*******************************************************************
675  * return the length of a uint32 (obvious, but the code is clean)
676  ********************************************************************/
677
678 static uint32 size_of_systemtime(SYSTEMTIME *systime)
679 {
680         if (systime==NULL)
681                 return (4);
682         else 
683                 return (sizeof(SYSTEMTIME) +4);
684 }
685
686 /*******************************************************************
687  Parse a DEVMODE structure and its relative pointer.
688 ********************************************************************/
689
690 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
691 {
692         prs_struct *ps=&buffer->prs;
693
694         prs_debug(ps, depth, desc, "smb_io_reldevmode");
695         depth++;
696
697         if (MARSHALLING(ps)) {
698                 uint32 struct_offset = prs_offset(ps);
699                 uint32 relative_offset;
700                 
701                 if (*devmode == NULL) {
702                         relative_offset=0;
703                         if (!prs_uint32("offset", ps, depth, &relative_offset))
704                                 return False;
705                         DEBUG(8, ("boing, the devmode was NULL\n"));
706                         
707                         return True;
708                 }
709                 
710                 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
711
712                 /* mz:  we have to align the device mode for VISTA */
713                 if (buffer->string_at_end % 4) {
714                         buffer->string_at_end += 4 - (buffer->string_at_end % 4);
715                 }
716
717                 if(!prs_set_offset(ps, buffer->string_at_end))
718                         return False;
719                 
720                 /* write the DEVMODE */
721                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
722                         return False;
723
724                 if(!prs_set_offset(ps, struct_offset))
725                         return False;
726                 
727                 relative_offset=buffer->string_at_end - buffer->struct_start;
728                 /* write its offset */
729                 if (!prs_uint32("offset", ps, depth, &relative_offset))
730                         return False;
731         }
732         else {
733                 uint32 old_offset;
734                 
735                 /* read the offset */
736                 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
737                         return False;
738                 if (buffer->string_at_end == 0) {
739                         *devmode = NULL;
740                         return True;
741                 }
742
743                 old_offset = prs_offset(ps);
744                 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
745                         return False;
746
747                 /* read the string */
748                 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
749                         return False;
750                 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
751                         return False;
752
753                 if(!prs_set_offset(ps, old_offset))
754                         return False;
755         }
756         return True;
757 }
758
759 /*******************************************************************
760  Parse a PRINTER_INFO_0 structure.
761 ********************************************************************/  
762
763 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
764 {
765         prs_struct *ps=&buffer->prs;
766
767         prs_debug(ps, depth, desc, "smb_io_printer_info_0");
768         depth++;        
769         
770         buffer->struct_start=prs_offset(ps);
771
772         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
773                 return False;
774         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
775                 return False;
776         
777         if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
778                 return False;
779         if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
780                 return False;
781         if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
782                 return False;
783
784         if(!prs_uint16("year", ps, depth, &info->year))
785                 return False;
786         if(!prs_uint16("month", ps, depth, &info->month))
787                 return False;
788         if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
789                 return False;
790         if(!prs_uint16("day", ps, depth, &info->day))
791                 return False;
792         if(!prs_uint16("hour", ps, depth, &info->hour))
793                 return False;
794         if(!prs_uint16("minute", ps, depth, &info->minute))
795                 return False;
796         if(!prs_uint16("second", ps, depth, &info->second))
797                 return False;
798         if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
799                 return False;
800
801         if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
802                 return False;
803         if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
804                 return False;
805
806         if(!prs_uint16("major_version", ps, depth, &info->major_version))
807                 return False;
808         if(!prs_uint16("build_version", ps, depth, &info->build_version))
809                 return False;
810         if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
811                 return False;
812         if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
813                 return False;
814         if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
815                 return False;
816         if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
817                 return False;
818         if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
819                 return False;
820         if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
821                 return False;
822         if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
823                 return False;
824         if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
825                 return False;
826         if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
827                 return False;
828         if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
829                 return False;
830         if(!prs_uint32("change_id", ps, depth, &info->change_id))
831                 return False;
832         if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
833                 return False;
834         if(!prs_uint32("status"   , ps, depth, &info->status))
835                 return False;
836         if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
837                 return False;
838         if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
839                 return False;
840         if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
841                 return False;
842         if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
843                 return False;
844         if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
845                 return False;
846         if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
847                 return False;
848         if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
849                 return False;
850         if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
851                 return False;
852         if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
853                 return False;
854         if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
855                 return False;
856
857         return True;
858 }
859
860 /*******************************************************************
861  Parse a PRINTER_INFO_1 structure.
862 ********************************************************************/  
863
864 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
865 {
866         prs_struct *ps=&buffer->prs;
867
868         prs_debug(ps, depth, desc, "smb_io_printer_info_1");
869         depth++;        
870         
871         buffer->struct_start=prs_offset(ps);
872
873         if (!prs_uint32("flags", ps, depth, &info->flags))
874                 return False;
875         if (!smb_io_relstr("description", buffer, depth, &info->description))
876                 return False;
877         if (!smb_io_relstr("name", buffer, depth, &info->name))
878                 return False;
879         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
880                 return False;   
881
882         return True;
883 }
884
885 /*******************************************************************
886  Parse a PRINTER_INFO_2 structure.
887 ********************************************************************/  
888
889 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
890 {
891         prs_struct *ps=&buffer->prs;
892         uint32 dm_offset, sd_offset, current_offset;
893         uint32 dummy_value = 0, has_secdesc = 0;
894
895         prs_debug(ps, depth, desc, "smb_io_printer_info_2");
896         depth++;        
897         
898         buffer->struct_start=prs_offset(ps);
899         
900         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
901                 return False;
902         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
903                 return False;
904         if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
905                 return False;
906         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
907                 return False;
908         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
909                 return False;
910         if (!smb_io_relstr("comment", buffer, depth, &info->comment))
911                 return False;
912         if (!smb_io_relstr("location", buffer, depth, &info->location))
913                 return False;
914
915         /* save current offset and wind forwared by a uint32 */
916         dm_offset = prs_offset(ps);
917         if (!prs_uint32("devmode", ps, depth, &dummy_value))
918                 return False;
919         
920         if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
921                 return False;
922         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
923                 return False;
924         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
925                 return False;
926         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
927                 return False;
928
929         /* save current offset for the sec_desc */
930         sd_offset = prs_offset(ps);
931         if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
932                 return False;
933
934         
935         /* save current location so we can pick back up here */
936         current_offset = prs_offset(ps);
937         
938         /* parse the devmode */
939         if (!prs_set_offset(ps, dm_offset))
940                 return False;
941         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
942                 return False;
943         
944         /* parse the sec_desc */
945         if (info->secdesc) {
946                 if (!prs_set_offset(ps, sd_offset))
947                         return False;
948                 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
949                         return False;
950         }
951
952         /* pick up where we left off */
953         if (!prs_set_offset(ps, current_offset))
954                 return False;
955
956         if (!prs_uint32("attributes", ps, depth, &info->attributes))
957                 return False;
958         if (!prs_uint32("priority", ps, depth, &info->priority))
959                 return False;
960         if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
961                 return False;
962         if (!prs_uint32("starttime", ps, depth, &info->starttime))
963                 return False;
964         if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
965                 return False;
966         if (!prs_uint32("status", ps, depth, &info->status))
967                 return False;
968         if (!prs_uint32("jobs", ps, depth, &info->cjobs))
969                 return False;
970         if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
971                 return False;
972
973         return True;
974 }
975
976 /*******************************************************************
977  Parse a PRINTER_INFO_3 structure.
978 ********************************************************************/  
979
980 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
981 {
982         uint32 offset = 0;
983         prs_struct *ps=&buffer->prs;
984
985         prs_debug(ps, depth, desc, "smb_io_printer_info_3");
986         depth++;        
987         
988         buffer->struct_start=prs_offset(ps);
989         
990         if (MARSHALLING(ps)) {
991                 /* Ensure the SD is 8 byte aligned in the buffer. */
992                 uint32 start = prs_offset(ps); /* Remember the start position. */
993                 uint32 off_val = 0;
994
995                 /* Write a dummy value. */
996                 if (!prs_uint32("offset", ps, depth, &off_val))
997                         return False;
998
999                 /* 8 byte align. */
1000                 if (!prs_align_uint64(ps))
1001                         return False;
1002
1003                 /* Remember where we must seek back to write the SD. */
1004                 offset = prs_offset(ps);
1005
1006                 /* Calculate the real offset for the SD. */
1007
1008                 off_val = offset - start;
1009
1010                 /* Seek back to where we store the SD offset & store. */
1011                 prs_set_offset(ps, start);
1012                 if (!prs_uint32("offset", ps, depth, &off_val))
1013                         return False;
1014
1015                 /* Return to after the 8 byte align. */
1016                 prs_set_offset(ps, offset);
1017
1018         } else {
1019                 if (!prs_uint32("offset", ps, depth, &offset))
1020                         return False;
1021                 /* Seek within the buffer. */
1022                 if (!prs_set_offset(ps, offset))
1023                         return False;
1024         }
1025         if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
1026                 return False;
1027
1028         return True;
1029 }
1030
1031 /*******************************************************************
1032  Parse a PRINTER_INFO_4 structure.
1033 ********************************************************************/  
1034
1035 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
1036 {
1037         prs_struct *ps=&buffer->prs;
1038
1039         prs_debug(ps, depth, desc, "smb_io_printer_info_4");
1040         depth++;        
1041         
1042         buffer->struct_start=prs_offset(ps);
1043         
1044         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1045                 return False;
1046         if (!smb_io_relstr("servername", buffer, depth, &info->servername))
1047                 return False;
1048         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1049                 return False;
1050         return True;
1051 }
1052
1053 /*******************************************************************
1054  Parse a PRINTER_INFO_5 structure.
1055 ********************************************************************/  
1056
1057 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
1058 {
1059         prs_struct *ps=&buffer->prs;
1060
1061         prs_debug(ps, depth, desc, "smb_io_printer_info_5");
1062         depth++;        
1063         
1064         buffer->struct_start=prs_offset(ps);
1065         
1066         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1067                 return False;
1068         if (!smb_io_relstr("portname", buffer, depth, &info->portname))
1069                 return False;
1070         if (!prs_uint32("attributes", ps, depth, &info->attributes))
1071                 return False;
1072         if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
1073                 return False;
1074         if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
1075                 return False;
1076         return True;
1077 }
1078
1079 /*******************************************************************
1080  Parse a PRINTER_INFO_6 structure.
1081 ********************************************************************/  
1082
1083 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
1084                            PRINTER_INFO_6 *info, int depth)
1085 {
1086         prs_struct *ps=&buffer->prs;
1087
1088         prs_debug(ps, depth, desc, "smb_io_printer_info_6");
1089         depth++;        
1090         
1091         if (!prs_uint32("status", ps, depth, &info->status))
1092                 return False;
1093
1094         return True;
1095 }
1096
1097 /*******************************************************************
1098  Parse a PRINTER_INFO_7 structure.
1099 ********************************************************************/  
1100
1101 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
1102 {
1103         prs_struct *ps=&buffer->prs;
1104
1105         prs_debug(ps, depth, desc, "smb_io_printer_info_7");
1106         depth++;        
1107         
1108         buffer->struct_start=prs_offset(ps);
1109         
1110         if (!smb_io_relstr("guid", buffer, depth, &info->guid))
1111                 return False;
1112         if (!prs_uint32("action", ps, depth, &info->action))
1113                 return False;
1114         return True;
1115 }
1116
1117 /*******************************************************************
1118  Parse a PORT_INFO_1 structure.
1119 ********************************************************************/  
1120
1121 bool smb_io_port_info_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
1122 {
1123         prs_struct *ps=&buffer->prs;
1124
1125         prs_debug(ps, depth, desc, "smb_io_port_info_1");
1126         depth++;        
1127         
1128         buffer->struct_start=prs_offset(ps);
1129         
1130         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1131                 return False;
1132
1133         return True;
1134 }
1135
1136 /*******************************************************************
1137  Parse a PORT_INFO_2 structure.
1138 ********************************************************************/  
1139
1140 bool smb_io_port_info_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
1141 {
1142         prs_struct *ps=&buffer->prs;
1143
1144         prs_debug(ps, depth, desc, "smb_io_port_info_2");
1145         depth++;        
1146         
1147         buffer->struct_start=prs_offset(ps);
1148         
1149         if (!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1150                 return False;
1151         if (!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
1152                 return False;
1153         if (!smb_io_relstr("description", buffer, depth, &info->description))
1154                 return False;
1155         if (!prs_uint32("port_type", ps, depth, &info->port_type))
1156                 return False;
1157         if (!prs_uint32("reserved", ps, depth, &info->reserved))
1158                 return False;
1159
1160         return True;
1161 }
1162
1163 /*******************************************************************
1164  Parse a DRIVER_INFO_1 structure.
1165 ********************************************************************/
1166
1167 bool smb_io_printer_driver_info_1(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) 
1168 {
1169         prs_struct *ps=&buffer->prs;
1170
1171         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
1172         depth++;        
1173         
1174         buffer->struct_start=prs_offset(ps);
1175
1176         if (!smb_io_relstr("name", buffer, depth, &info->name))
1177                 return False;
1178
1179         return True;
1180 }
1181
1182 /*******************************************************************
1183  Parse a DRIVER_INFO_2 structure.
1184 ********************************************************************/
1185
1186 bool smb_io_printer_driver_info_2(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) 
1187 {
1188         prs_struct *ps=&buffer->prs;
1189
1190         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_2");
1191         depth++;        
1192         
1193         buffer->struct_start=prs_offset(ps);
1194
1195         if (!prs_uint32("version", ps, depth, &info->version))
1196                 return False;
1197         if (!smb_io_relstr("name", buffer, depth, &info->name))
1198                 return False;
1199         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1200                 return False;
1201         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1202                 return False;
1203         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1204                 return False;
1205         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1206                 return False;
1207
1208         return True;
1209 }
1210
1211 /*******************************************************************
1212  Parse a DRIVER_INFO_3 structure.
1213 ********************************************************************/
1214
1215 bool smb_io_printer_driver_info_3(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
1216 {
1217         prs_struct *ps=&buffer->prs;
1218
1219         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
1220         depth++;        
1221         
1222         buffer->struct_start=prs_offset(ps);
1223
1224         if (!prs_uint32("version", ps, depth, &info->version))
1225                 return False;
1226         if (!smb_io_relstr("name", buffer, depth, &info->name))
1227                 return False;
1228         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1229                 return False;
1230         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1231                 return False;
1232         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1233                 return False;
1234         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1235                 return False;
1236         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1237                 return False;
1238
1239         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1240                 return False;
1241
1242         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1243                 return False;
1244         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1245                 return False;
1246
1247         return True;
1248 }
1249
1250 /*******************************************************************
1251  Parse a DRIVER_INFO_6 structure.
1252 ********************************************************************/
1253
1254 bool smb_io_printer_driver_info_6(const char *desc, RPC_BUFFER *buffer, DRIVER_INFO_6 *info, int depth)
1255 {
1256         prs_struct *ps=&buffer->prs;
1257
1258         prs_debug(ps, depth, desc, "smb_io_printer_driver_info_6");
1259         depth++;        
1260         
1261         buffer->struct_start=prs_offset(ps);
1262
1263         if (!prs_uint32("version", ps, depth, &info->version))
1264                 return False;
1265         if (!smb_io_relstr("name", buffer, depth, &info->name))
1266                 return False;
1267         if (!smb_io_relstr("architecture", buffer, depth, &info->architecture))
1268                 return False;
1269         if (!smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
1270                 return False;
1271         if (!smb_io_relstr("datafile", buffer, depth, &info->datafile))
1272                 return False;
1273         if (!smb_io_relstr("configfile", buffer, depth, &info->configfile))
1274                 return False;
1275         if (!smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
1276                 return False;
1277
1278         if (!smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
1279                 return False;
1280
1281         if (!smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
1282                 return False;
1283         if (!smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
1284                 return False;
1285
1286         if (!smb_io_relarraystr("previousdrivernames", buffer, depth, &info->previousdrivernames))
1287                 return False;
1288
1289         if (!prs_uint64("date", ps, depth, &info->driver_date))
1290                 return False;
1291
1292         if (!prs_uint32("padding", ps, depth, &info->padding))
1293                 return False;
1294
1295         if (!prs_uint32("driver_version_low", ps, depth, &info->driver_version_low))
1296                 return False;
1297
1298         if (!prs_uint32("driver_version_high", ps, depth, &info->driver_version_high))
1299                 return False;
1300
1301         if (!smb_io_relstr("mfgname", buffer, depth, &info->mfgname))
1302                 return False;
1303         if (!smb_io_relstr("oem_url", buffer, depth, &info->oem_url))
1304                 return False;
1305         if (!smb_io_relstr("hardware_id", buffer, depth, &info->hardware_id))
1306                 return False;
1307         if (!smb_io_relstr("provider", buffer, depth, &info->provider))
1308                 return False;
1309         
1310         return True;
1311 }
1312
1313 /*******************************************************************
1314  Parse a JOB_INFO_1 structure.
1315 ********************************************************************/  
1316
1317 bool smb_io_job_info_1(const char *desc, RPC_BUFFER *buffer, JOB_INFO_1 *info, int depth)
1318 {
1319         prs_struct *ps=&buffer->prs;
1320
1321         prs_debug(ps, depth, desc, "smb_io_job_info_1");
1322         depth++;        
1323         
1324         buffer->struct_start=prs_offset(ps);
1325
1326         if (!prs_uint32("jobid", ps, depth, &info->jobid))
1327                 return False;
1328         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1329                 return False;
1330         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
1331                 return False;
1332         if (!smb_io_relstr("username", buffer, depth, &info->username))
1333                 return False;
1334         if (!smb_io_relstr("document", buffer, depth, &info->document))
1335                 return False;
1336         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1337                 return False;
1338         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
1339                 return False;
1340         if (!prs_uint32("status", ps, depth, &info->status))
1341                 return False;
1342         if (!prs_uint32("priority", ps, depth, &info->priority))
1343                 return False;
1344         if (!prs_uint32("position", ps, depth, &info->position))
1345                 return False;
1346         if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
1347                 return False;
1348         if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
1349                 return False;
1350         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
1351                 return False;
1352
1353         return True;
1354 }
1355
1356 /*******************************************************************
1357  Parse a JOB_INFO_2 structure.
1358 ********************************************************************/  
1359
1360 bool smb_io_job_info_2(const char *desc, RPC_BUFFER *buffer, JOB_INFO_2 *info, int depth)
1361 {       
1362         uint32 pipo=0;
1363         prs_struct *ps=&buffer->prs;
1364         
1365         prs_debug(ps, depth, desc, "smb_io_job_info_2");
1366         depth++;        
1367
1368         buffer->struct_start=prs_offset(ps);
1369         
1370         if (!prs_uint32("jobid",ps, depth, &info->jobid))
1371                 return False;
1372         if (!smb_io_relstr("printername", buffer, depth, &info->printername))
1373                 return False;
1374         if (!smb_io_relstr("machinename", buffer, depth, &info->machinename))
1375                 return False;
1376         if (!smb_io_relstr("username", buffer, depth, &info->username))
1377                 return False;
1378         if (!smb_io_relstr("document", buffer, depth, &info->document))
1379                 return False;
1380         if (!smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
1381                 return False;
1382         if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
1383                 return False;
1384
1385         if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
1386                 return False;
1387         if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
1388                 return False;
1389         if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
1390                 return False;
1391         if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
1392                 return False;
1393         if (!smb_io_relstr("text_status", buffer, depth, &info->text_status))
1394                 return False;
1395
1396 /*      SEC_DESC sec_desc;*/
1397         if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
1398                 return False;
1399
1400         if (!prs_uint32("status",ps, depth, &info->status))
1401                 return False;
1402         if (!prs_uint32("priority",ps, depth, &info->priority))
1403                 return False;
1404         if (!prs_uint32("position",ps, depth, &info->position)) 
1405                 return False;
1406         if (!prs_uint32("starttime",ps, depth, &info->starttime))
1407                 return False;
1408         if (!prs_uint32("untiltime",ps, depth, &info->untiltime))       
1409                 return False;
1410         if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
1411                 return False;
1412         if (!prs_uint32("size",ps, depth, &info->size))
1413                 return False;
1414         if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
1415                 return False;
1416         if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
1417                 return False;
1418         if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
1419                 return False;
1420
1421         return True;
1422 }
1423
1424 /*******************************************************************
1425 ********************************************************************/  
1426
1427 bool smb_io_form_1(const char *desc, RPC_BUFFER *buffer, FORM_1 *info, int depth)
1428 {
1429         prs_struct *ps=&buffer->prs;
1430         
1431         prs_debug(ps, depth, desc, "smb_io_form_1");
1432         depth++;
1433                 
1434         buffer->struct_start=prs_offset(ps);
1435         
1436         if (!prs_uint32("flag", ps, depth, &info->flag))
1437                 return False;
1438                 
1439         if (!smb_io_relstr("name", buffer, depth, &info->name))
1440                 return False;
1441
1442         if (!prs_uint32("width", ps, depth, &info->width))
1443                 return False;
1444         if (!prs_uint32("length", ps, depth, &info->length))
1445                 return False;
1446         if (!prs_uint32("left", ps, depth, &info->left))
1447                 return False;
1448         if (!prs_uint32("top", ps, depth, &info->top))
1449                 return False;
1450         if (!prs_uint32("right", ps, depth, &info->right))
1451                 return False;
1452         if (!prs_uint32("bottom", ps, depth, &info->bottom))
1453                 return False;
1454
1455         return True;
1456 }
1457
1458 /*******************************************************************
1459  Parse a PORT_INFO_1 structure.
1460 ********************************************************************/  
1461
1462 bool smb_io_port_1(const char *desc, RPC_BUFFER *buffer, PORT_INFO_1 *info, int depth)
1463 {
1464         prs_struct *ps=&buffer->prs;
1465
1466         prs_debug(ps, depth, desc, "smb_io_port_1");
1467         depth++;
1468
1469         buffer->struct_start=prs_offset(ps);
1470
1471         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1472                 return False;
1473
1474         return True;
1475 }
1476
1477 /*******************************************************************
1478  Parse a PORT_INFO_2 structure.
1479 ********************************************************************/  
1480
1481 bool smb_io_port_2(const char *desc, RPC_BUFFER *buffer, PORT_INFO_2 *info, int depth)
1482 {
1483         prs_struct *ps=&buffer->prs;
1484
1485         prs_debug(ps, depth, desc, "smb_io_port_2");
1486         depth++;
1487
1488         buffer->struct_start=prs_offset(ps);
1489
1490         if(!smb_io_relstr("port_name", buffer, depth, &info->port_name))
1491                 return False;
1492         if(!smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
1493                 return False;
1494         if(!smb_io_relstr("description", buffer, depth, &info->description))
1495                 return False;
1496         if(!prs_uint32("port_type", ps, depth, &info->port_type))
1497                 return False;
1498         if(!prs_uint32("reserved", ps, depth, &info->reserved))
1499                 return False;
1500
1501         return True;
1502 }
1503
1504 /*******************************************************************
1505 ********************************************************************/  
1506
1507 bool smb_io_printprocessor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
1508 {
1509         prs_struct *ps=&buffer->prs;
1510
1511         prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
1512         depth++;        
1513
1514         buffer->struct_start=prs_offset(ps);
1515         
1516         if (smb_io_relstr("name", buffer, depth, &info->name))
1517                 return False;
1518
1519         return True;
1520 }
1521
1522 /*******************************************************************
1523 ********************************************************************/  
1524
1525 bool smb_io_printprocdatatype_info_1(const char *desc, RPC_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
1526 {
1527         prs_struct *ps=&buffer->prs;
1528
1529         prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
1530         depth++;        
1531
1532         buffer->struct_start=prs_offset(ps);
1533         
1534         if (smb_io_relstr("name", buffer, depth, &info->name))
1535                 return False;
1536
1537         return True;
1538 }
1539
1540 /*******************************************************************
1541 ********************************************************************/  
1542
1543 bool smb_io_printmonitor_info_1(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
1544 {
1545         prs_struct *ps=&buffer->prs;
1546
1547         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
1548         depth++;        
1549
1550         buffer->struct_start=prs_offset(ps);
1551
1552         if (!smb_io_relstr("name", buffer, depth, &info->name))
1553                 return False;
1554
1555         return True;
1556 }
1557
1558 /*******************************************************************
1559 ********************************************************************/  
1560
1561 bool smb_io_printmonitor_info_2(const char *desc, RPC_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
1562 {
1563         prs_struct *ps=&buffer->prs;
1564
1565         prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
1566         depth++;        
1567
1568         buffer->struct_start=prs_offset(ps);
1569
1570         if (!smb_io_relstr("name", buffer, depth, &info->name))
1571                 return False;
1572         if (!smb_io_relstr("environment", buffer, depth, &info->environment))
1573                 return False;
1574         if (!smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
1575                 return False;
1576
1577         return True;
1578 }
1579
1580 /*******************************************************************
1581 return the size required by a struct in the stream
1582 ********************************************************************/  
1583
1584 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
1585 {
1586         int size=0;
1587         
1588         size+=size_of_relative_string( &info->printername );
1589         size+=size_of_relative_string( &info->servername );
1590
1591         size+=size_of_uint32( &info->cjobs);
1592         size+=size_of_uint32( &info->total_jobs);
1593         size+=size_of_uint32( &info->total_bytes);
1594
1595         size+=size_of_uint16( &info->year);
1596         size+=size_of_uint16( &info->month);
1597         size+=size_of_uint16( &info->dayofweek);
1598         size+=size_of_uint16( &info->day);
1599         size+=size_of_uint16( &info->hour);
1600         size+=size_of_uint16( &info->minute);
1601         size+=size_of_uint16( &info->second);
1602         size+=size_of_uint16( &info->milliseconds);
1603
1604         size+=size_of_uint32( &info->global_counter);
1605         size+=size_of_uint32( &info->total_pages);
1606
1607         size+=size_of_uint16( &info->major_version);
1608         size+=size_of_uint16( &info->build_version);
1609
1610         size+=size_of_uint32( &info->unknown7);
1611         size+=size_of_uint32( &info->unknown8);
1612         size+=size_of_uint32( &info->unknown9);
1613         size+=size_of_uint32( &info->session_counter);
1614         size+=size_of_uint32( &info->unknown11);
1615         size+=size_of_uint32( &info->printer_errors);
1616         size+=size_of_uint32( &info->unknown13);
1617         size+=size_of_uint32( &info->unknown14);
1618         size+=size_of_uint32( &info->unknown15);
1619         size+=size_of_uint32( &info->unknown16);
1620         size+=size_of_uint32( &info->change_id);
1621         size+=size_of_uint32( &info->unknown18);
1622         size+=size_of_uint32( &info->status);
1623         size+=size_of_uint32( &info->unknown20);
1624         size+=size_of_uint32( &info->c_setprinter);
1625         
1626         size+=size_of_uint16( &info->unknown22);
1627         size+=size_of_uint16( &info->unknown23);
1628         size+=size_of_uint16( &info->unknown24);
1629         size+=size_of_uint16( &info->unknown25);
1630         size+=size_of_uint16( &info->unknown26);
1631         size+=size_of_uint16( &info->unknown27);
1632         size+=size_of_uint16( &info->unknown28);
1633         size+=size_of_uint16( &info->unknown29);
1634         
1635         return size;
1636 }
1637
1638 /*******************************************************************
1639 return the size required by a struct in the stream
1640 ********************************************************************/  
1641
1642 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
1643 {
1644         int size=0;
1645                 
1646         size+=size_of_uint32( &info->flags );   
1647         size+=size_of_relative_string( &info->description );
1648         size+=size_of_relative_string( &info->name );
1649         size+=size_of_relative_string( &info->comment );
1650
1651         return size;
1652 }
1653
1654 /*******************************************************************
1655 return the size required by a struct in the stream
1656 ********************************************************************/
1657
1658 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
1659 {
1660         uint32 size=0;
1661                 
1662         size += 4;
1663         
1664         size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
1665
1666         size+=size_of_device_mode( info->devmode );
1667         
1668         size+=size_of_relative_string( &info->servername );
1669         size+=size_of_relative_string( &info->printername );
1670         size+=size_of_relative_string( &info->sharename );
1671         size+=size_of_relative_string( &info->portname );
1672         size+=size_of_relative_string( &info->drivername );
1673         size+=size_of_relative_string( &info->comment );
1674         size+=size_of_relative_string( &info->location );
1675         
1676         size+=size_of_relative_string( &info->sepfile );
1677         size+=size_of_relative_string( &info->printprocessor );
1678         size+=size_of_relative_string( &info->datatype );
1679         size+=size_of_relative_string( &info->parameters );
1680
1681         size+=size_of_uint32( &info->attributes );
1682         size+=size_of_uint32( &info->priority );
1683         size+=size_of_uint32( &info->defaultpriority );
1684         size+=size_of_uint32( &info->starttime );
1685         size+=size_of_uint32( &info->untiltime );
1686         size+=size_of_uint32( &info->status );
1687         size+=size_of_uint32( &info->cjobs );
1688         size+=size_of_uint32( &info->averageppm );      
1689                 
1690         /* 
1691          * add any adjustments for alignment.  This is
1692          * not optimal since we could be calling this
1693          * function from a loop (e.g. enumprinters), but 
1694          * it is easier to maintain the calculation here and
1695          * not place the burden on the caller to remember.   --jerry
1696          */
1697         if ((size % 4) != 0)
1698                 size += 4 - (size % 4);
1699         
1700         return size;
1701 }
1702
1703 /*******************************************************************
1704 return the size required by a struct in the stream
1705 ********************************************************************/
1706
1707 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
1708 {
1709         uint32 size=0;
1710                 
1711         size+=size_of_relative_string( &info->printername );
1712         size+=size_of_relative_string( &info->servername );
1713
1714         size+=size_of_uint32( &info->attributes );
1715         return size;
1716 }
1717
1718 /*******************************************************************
1719 return the size required by a struct in the stream
1720 ********************************************************************/
1721
1722 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
1723 {
1724         uint32 size=0;
1725                 
1726         size+=size_of_relative_string( &info->printername );
1727         size+=size_of_relative_string( &info->portname );
1728
1729         size+=size_of_uint32( &info->attributes );
1730         size+=size_of_uint32( &info->device_not_selected_timeout );
1731         size+=size_of_uint32( &info->transmission_retry_timeout );
1732         return size;
1733 }
1734
1735 /*******************************************************************
1736 return the size required by a struct in the stream
1737 ********************************************************************/
1738
1739 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
1740 {
1741         return sizeof(uint32);
1742 }
1743
1744 /*******************************************************************
1745 return the size required by a struct in the stream
1746 ********************************************************************/
1747
1748 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
1749 {
1750         /* The 8 is for the self relative pointer - 8 byte aligned.. */
1751         return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
1752 }
1753
1754 /*******************************************************************
1755 return the size required by a struct in the stream
1756 ********************************************************************/
1757
1758 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
1759 {
1760         uint32 size=0;
1761                 
1762         size+=size_of_relative_string( &info->guid );
1763         size+=size_of_uint32( &info->action );
1764         return size;
1765 }
1766
1767 /*******************************************************************
1768 return the size required by a struct in the stream
1769 ********************************************************************/
1770
1771 uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
1772 {
1773         int size=0;
1774         size+=size_of_relative_string( &info->name );
1775
1776         return size;
1777 }
1778
1779 /*******************************************************************
1780 return the size required by a struct in the stream
1781 ********************************************************************/
1782
1783 uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
1784 {
1785         int size=0;
1786         size+=size_of_uint32( &info->version ); 
1787         size+=size_of_relative_string( &info->name );
1788         size+=size_of_relative_string( &info->architecture );
1789         size+=size_of_relative_string( &info->driverpath );
1790         size+=size_of_relative_string( &info->datafile );
1791         size+=size_of_relative_string( &info->configfile );
1792
1793         return size;
1794 }
1795
1796 /*******************************************************************
1797 return the size required by a string array.
1798 ********************************************************************/
1799
1800 uint32 spoolss_size_string_array(uint16 *string)
1801 {
1802         uint32 i = 0;
1803
1804         if (string) {
1805                 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
1806         }
1807         i=i+2; /* to count all chars including the leading zero */
1808         i=2*i; /* because we need the value in bytes */
1809         i=i+4; /* the offset pointer size */
1810
1811         return i;
1812 }
1813
1814 /*******************************************************************
1815 return the size required by a struct in the stream
1816 ********************************************************************/
1817
1818 uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
1819 {
1820         int size=0;
1821
1822         size+=size_of_uint32( &info->version ); 
1823         size+=size_of_relative_string( &info->name );
1824         size+=size_of_relative_string( &info->architecture );
1825         size+=size_of_relative_string( &info->driverpath );
1826         size+=size_of_relative_string( &info->datafile );
1827         size+=size_of_relative_string( &info->configfile );
1828         size+=size_of_relative_string( &info->helpfile );
1829         size+=size_of_relative_string( &info->monitorname );
1830         size+=size_of_relative_string( &info->defaultdatatype );
1831         
1832         size+=spoolss_size_string_array(info->dependentfiles);
1833
1834         return size;
1835 }
1836
1837 /*******************************************************************
1838 return the size required by a struct in the stream
1839 ********************************************************************/
1840
1841 uint32 spoolss_size_printer_driver_info_6(DRIVER_INFO_6 *info)
1842 {
1843         uint32 size=0;
1844
1845         size+=size_of_uint32( &info->version ); 
1846         size+=size_of_relative_string( &info->name );
1847         size+=size_of_relative_string( &info->architecture );
1848         size+=size_of_relative_string( &info->driverpath );
1849         size+=size_of_relative_string( &info->datafile );
1850         size+=size_of_relative_string( &info->configfile );
1851         size+=size_of_relative_string( &info->helpfile );
1852
1853         size+=spoolss_size_string_array(info->dependentfiles);
1854
1855         size+=size_of_relative_string( &info->monitorname );
1856         size+=size_of_relative_string( &info->defaultdatatype );
1857         
1858         size+=spoolss_size_string_array(info->previousdrivernames);
1859
1860         size+=size_of_nttime(&info->driver_date);
1861         size+=size_of_uint32( &info->padding ); 
1862         size+=size_of_uint32( &info->driver_version_low );      
1863         size+=size_of_uint32( &info->driver_version_high );     
1864         size+=size_of_relative_string( &info->mfgname );
1865         size+=size_of_relative_string( &info->oem_url );
1866         size+=size_of_relative_string( &info->hardware_id );
1867         size+=size_of_relative_string( &info->provider );
1868
1869         return size;
1870 }
1871
1872 /*******************************************************************
1873 return the size required by a struct in the stream
1874 ********************************************************************/  
1875
1876 uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
1877 {
1878         int size=0;
1879         size+=size_of_uint32( &info->jobid );
1880         size+=size_of_relative_string( &info->printername );
1881         size+=size_of_relative_string( &info->machinename );
1882         size+=size_of_relative_string( &info->username );
1883         size+=size_of_relative_string( &info->document );
1884         size+=size_of_relative_string( &info->datatype );
1885         size+=size_of_relative_string( &info->text_status );
1886         size+=size_of_uint32( &info->status );
1887         size+=size_of_uint32( &info->priority );
1888         size+=size_of_uint32( &info->position );
1889         size+=size_of_uint32( &info->totalpages );
1890         size+=size_of_uint32( &info->pagesprinted );
1891         size+=size_of_systemtime( &info->submitted );
1892
1893         return size;
1894 }
1895
1896 /*******************************************************************
1897 return the size required by a struct in the stream
1898 ********************************************************************/  
1899
1900 uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
1901 {
1902         int size=0;
1903
1904         size+=4; /* size of sec desc ptr */
1905
1906         size+=size_of_uint32( &info->jobid );
1907         size+=size_of_relative_string( &info->printername );
1908         size+=size_of_relative_string( &info->machinename );
1909         size+=size_of_relative_string( &info->username );
1910         size+=size_of_relative_string( &info->document );
1911         size+=size_of_relative_string( &info->notifyname );
1912         size+=size_of_relative_string( &info->datatype );
1913         size+=size_of_relative_string( &info->printprocessor );
1914         size+=size_of_relative_string( &info->parameters );
1915         size+=size_of_relative_string( &info->drivername );
1916         size+=size_of_device_mode( info->devmode );
1917         size+=size_of_relative_string( &info->text_status );
1918 /*      SEC_DESC sec_desc;*/
1919         size+=size_of_uint32( &info->status );
1920         size+=size_of_uint32( &info->priority );
1921         size+=size_of_uint32( &info->position );
1922         size+=size_of_uint32( &info->starttime );
1923         size+=size_of_uint32( &info->untiltime );
1924         size+=size_of_uint32( &info->totalpages );
1925         size+=size_of_uint32( &info->size );
1926         size+=size_of_systemtime( &info->submitted );
1927         size+=size_of_uint32( &info->timeelapsed );
1928         size+=size_of_uint32( &info->pagesprinted );
1929
1930         return size;
1931 }
1932
1933 /*******************************************************************
1934 return the size required by a struct in the stream
1935 ********************************************************************/
1936
1937 uint32 spoolss_size_form_1(FORM_1 *info)
1938 {
1939         int size=0;
1940
1941         size+=size_of_uint32( &info->flag );
1942         size+=size_of_relative_string( &info->name );
1943         size+=size_of_uint32( &info->width );
1944         size+=size_of_uint32( &info->length );
1945         size+=size_of_uint32( &info->left );
1946         size+=size_of_uint32( &info->top );
1947         size+=size_of_uint32( &info->right );
1948         size+=size_of_uint32( &info->bottom );
1949
1950         return size;
1951 }
1952
1953 /*******************************************************************
1954 return the size required by a struct in the stream
1955 ********************************************************************/  
1956
1957 uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
1958 {
1959         int size=0;
1960
1961         size+=size_of_relative_string( &info->port_name );
1962
1963         return size;
1964 }
1965
1966 /*******************************************************************
1967 return the size required by a struct in the stream
1968 ********************************************************************/  
1969
1970 uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
1971 {
1972         int size=0;
1973
1974         size+=size_of_relative_string( &info->port_name );
1975         size+=size_of_relative_string( &info->monitor_name );
1976         size+=size_of_relative_string( &info->description );
1977
1978         size+=size_of_uint32( &info->port_type );
1979         size+=size_of_uint32( &info->reserved );
1980
1981         return size;
1982 }
1983
1984 /*******************************************************************
1985 return the size required by a struct in the stream
1986 ********************************************************************/  
1987
1988 uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
1989 {
1990         int size=0;
1991         size+=size_of_relative_string( &info->name );
1992
1993         return size;
1994 }
1995
1996 /*******************************************************************
1997 return the size required by a struct in the stream
1998 ********************************************************************/  
1999
2000 uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
2001 {
2002         int size=0;
2003         size+=size_of_relative_string( &info->name );
2004
2005         return size;
2006 }
2007
2008 /*******************************************************************
2009 return the size required by a struct in the stream
2010 ********************************************************************/  
2011 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
2012 {
2013         uint32  size = 0; 
2014         
2015         if (!p)
2016                 return 0;
2017         
2018         /* uint32(offset) + uint32(length) + length) */
2019         size += (size_of_uint32(&p->value_len)*2) + p->value_len;
2020         size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
2021         
2022         size += size_of_uint32(&p->type);
2023                        
2024         return size;
2025 }
2026
2027 /*******************************************************************
2028 return the size required by a struct in the stream
2029 ********************************************************************/  
2030
2031 uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
2032 {
2033         int size=0;
2034         size+=size_of_relative_string( &info->name );
2035
2036         return size;
2037 }
2038
2039 /*******************************************************************
2040 return the size required by a struct in the stream
2041 ********************************************************************/  
2042
2043 uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
2044 {
2045         int size=0;
2046         size+=size_of_relative_string( &info->name);
2047         size+=size_of_relative_string( &info->environment);
2048         size+=size_of_relative_string( &info->dll_name);
2049
2050         return size;
2051 }
2052
2053 /*******************************************************************
2054  * read a structure.
2055  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2056  ********************************************************************/
2057
2058 bool spoolss_io_q_getprinterdriver2(const char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
2059 {
2060         prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
2061         depth++;
2062
2063         if(!prs_align(ps))
2064                 return False;
2065         
2066         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2067                 return False;
2068         if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
2069                 return False;
2070         if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
2071                 return False;
2072         
2073         if(!prs_align(ps))
2074                 return False;
2075         if(!prs_uint32("level", ps, depth, &q_u->level))
2076                 return False;
2077                 
2078         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2079                 return False;
2080
2081         if(!prs_align(ps))
2082                 return False;
2083
2084         if(!prs_uint32("offered", ps, depth, &q_u->offered))
2085                 return False;
2086                 
2087         if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion))
2088                 return False;
2089         if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion))
2090                 return False;
2091
2092         return True;
2093 }
2094
2095 /*******************************************************************
2096  * read a structure.
2097  * called from spoolss_getprinterdriver2 (srv_spoolss.c)
2098  ********************************************************************/
2099
2100 bool spoolss_io_r_getprinterdriver2(const char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
2101 {
2102         prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
2103         depth++;
2104
2105         if (!prs_align(ps))
2106                 return False;
2107                 
2108         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2109                 return False;
2110
2111         if (!prs_align(ps))
2112                 return False;
2113         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2114                 return False;
2115         if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion))
2116                 return False;
2117         if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion))
2118                 return False;           
2119         if (!prs_werror("status", ps, depth, &r_u->status))
2120                 return False;
2121
2122         return True;            
2123 }
2124
2125 /*******************************************************************
2126  * init a structure.
2127  ********************************************************************/
2128
2129 bool make_spoolss_q_enumprinters(
2130         SPOOL_Q_ENUMPRINTERS *q_u, 
2131         uint32 flags, 
2132         char *servername, 
2133         uint32 level, 
2134         RPC_BUFFER *buffer, 
2135         uint32 offered
2136 )
2137 {
2138         q_u->flags=flags;
2139         
2140         q_u->servername_ptr = (servername != NULL) ? 1 : 0;
2141         init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
2142
2143         q_u->level=level;
2144         q_u->buffer=buffer;
2145         q_u->offered=offered;
2146
2147         return True;
2148 }
2149
2150 /*******************************************************************
2151  * init a structure.
2152  ********************************************************************/
2153
2154 bool make_spoolss_q_enumports(SPOOL_Q_ENUMPORTS *q_u, 
2155                                 fstring servername, uint32 level, 
2156                                 RPC_BUFFER *buffer, uint32 offered)
2157 {
2158         q_u->name_ptr = (servername != NULL) ? 1 : 0;
2159         init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
2160
2161         q_u->level=level;
2162         q_u->buffer=buffer;
2163         q_u->offered=offered;
2164
2165         return True;
2166 }
2167
2168 /*******************************************************************
2169  * read a structure.
2170  * called from spoolss_enumprinters (srv_spoolss.c)
2171  ********************************************************************/
2172
2173 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
2174 {
2175         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
2176         depth++;
2177
2178         if (!prs_align(ps))
2179                 return False;
2180
2181         if (!prs_uint32("flags", ps, depth, &q_u->flags))
2182                 return False;
2183         if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
2184                 return False;
2185
2186         if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
2187                 return False;
2188                 
2189         if (!prs_align(ps))
2190                 return False;
2191         if (!prs_uint32("level", ps, depth, &q_u->level))
2192                 return False;
2193
2194         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2195                 return False;
2196
2197         if (!prs_align(ps))
2198                 return False;
2199         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2200                 return False;
2201
2202         return True;
2203 }
2204
2205 /*******************************************************************
2206  Parse a SPOOL_R_ENUMPRINTERS structure.
2207  ********************************************************************/
2208
2209 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
2210 {
2211         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
2212         depth++;
2213
2214         if (!prs_align(ps))
2215                 return False;
2216                 
2217         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2218                 return False;
2219
2220         if (!prs_align(ps))
2221                 return False;
2222                 
2223         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2224                 return False;
2225                 
2226         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2227                 return False;
2228                 
2229         if (!prs_werror("status", ps, depth, &r_u->status))
2230                 return False;
2231
2232         return True;            
2233 }
2234
2235 /*******************************************************************
2236  * write a structure.
2237  * called from spoolss_r_enum_printers (srv_spoolss.c)
2238  *
2239  ********************************************************************/
2240
2241 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
2242 {       
2243         prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
2244         depth++;
2245
2246         if (!prs_align(ps))
2247                 return False;
2248                 
2249         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2250                 return False;
2251
2252         if (!prs_align(ps))
2253                 return False;
2254
2255         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2256                 return False;
2257                 
2258         if (!prs_werror("status", ps, depth, &r_u->status))
2259                 return False;
2260
2261         return True;            
2262 }
2263
2264 /*******************************************************************
2265  * read a structure.
2266  * called from spoolss_getprinter (srv_spoolss.c)
2267  ********************************************************************/
2268
2269 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
2270 {
2271         prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
2272         depth++;
2273
2274         if (!prs_align(ps))
2275                 return False;
2276
2277         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
2278                 return False;
2279         if (!prs_uint32("level", ps, depth, &q_u->level))
2280                 return False;
2281
2282         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2283                 return False;
2284
2285         if (!prs_align(ps))
2286                 return False;
2287         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2288                 return False;
2289
2290         return True;
2291 }
2292
2293 /*******************************************************************
2294  * init a structure.
2295  ********************************************************************/
2296
2297 bool make_spoolss_q_getprinter(
2298         TALLOC_CTX *mem_ctx,
2299         SPOOL_Q_GETPRINTER *q_u, 
2300         const POLICY_HND *hnd, 
2301         uint32 level, 
2302         RPC_BUFFER *buffer, 
2303         uint32 offered
2304 )
2305 {
2306         if (q_u == NULL)
2307         {
2308                 return False;
2309         }
2310         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2311
2312         q_u->level=level;
2313         q_u->buffer=buffer;
2314         q_u->offered=offered;
2315
2316         return True;
2317 }
2318
2319 /*******************************************************************
2320  * init a structure.
2321  ********************************************************************/
2322 bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, 
2323                                 const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, 
2324                                 uint32 command)
2325 {
2326         SEC_DESC *secdesc;
2327         DEVICEMODE *devmode;
2328
2329         if (!q_u || !info)
2330                 return False;
2331         
2332         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2333
2334         q_u->level = level;
2335         q_u->info.level = level;
2336         q_u->info.info_ptr = 1; /* Info is != NULL, see above */
2337         switch (level) {
2338
2339           /* There's no such thing as a setprinter level 1 */
2340
2341         case 2:
2342                 secdesc = info->printers_2->secdesc;
2343                 devmode = info->printers_2->devmode;
2344                 
2345                 make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2);
2346 #if 1   /* JERRY TEST */
2347                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
2348                 if (!q_u->secdesc_ctr)
2349                         return False;
2350                 q_u->secdesc_ctr->sd = secdesc;
2351                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
2352
2353                 q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0;
2354                 q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0;
2355                 q_u->devmode_ctr.devmode = devmode;
2356 #else
2357                 q_u->secdesc_ctr = NULL;
2358         
2359                 q_u->devmode_ctr.devmode_ptr = 0;
2360                 q_u->devmode_ctr.size = 0;
2361                 q_u->devmode_ctr.devmode = NULL;
2362 #endif
2363                 break;
2364         case 3:
2365                 secdesc = info->printers_3->secdesc;
2366                 
2367                 make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3);
2368                 
2369                 q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF);
2370                 if (!q_u->secdesc_ctr)
2371                         return False;
2372                 q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0;
2373                 q_u->secdesc_ctr->sd = secdesc;
2374
2375                 break;
2376         case 7:
2377                 make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7);
2378                 break;
2379
2380         default: 
2381                 DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level));
2382                         break;
2383         }
2384
2385         
2386         q_u->command = command;
2387
2388         return True;
2389 }
2390
2391
2392 /*******************************************************************
2393 ********************************************************************/  
2394
2395 bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth)
2396 {               
2397         prs_debug(ps, depth, desc, "spoolss_io_r_setprinter");
2398         depth++;
2399
2400         if(!prs_align(ps))
2401                 return False;
2402         
2403         if(!prs_werror("status", ps, depth, &r_u->status))
2404                 return False;
2405
2406         return True;
2407 }
2408
2409 /*******************************************************************
2410  Marshall/unmarshall a SPOOL_Q_SETPRINTER struct.
2411 ********************************************************************/  
2412
2413 bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
2414 {
2415         uint32 ptr_sec_desc = 0;
2416
2417         prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
2418         depth++;
2419
2420         if(!prs_align(ps))
2421                 return False;
2422
2423         if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth))
2424                 return False;
2425         if(!prs_uint32("level", ps, depth, &q_u->level))
2426                 return False;
2427         
2428         /* check for supported levels and structures we know about */
2429                 
2430         switch ( q_u->level ) {
2431                 case 0:
2432                 case 2:
2433                 case 3:
2434                 case 7:
2435                         /* supported levels */
2436                         break;
2437                 default:
2438                         DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", 
2439                                 q_u->level));
2440                         return True;
2441         }
2442                         
2443
2444         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
2445                 return False;
2446
2447         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
2448                 return False;
2449         
2450         if(!prs_align(ps))
2451                 return False;
2452
2453         switch (q_u->level)
2454         {
2455                 case 2:
2456                 {
2457                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
2458                         break;
2459                 }
2460                 case 3:
2461                 {
2462                         /* FIXME ! Our parsing here is wrong I think,
2463                          * but for a level3 it makes no sense for
2464                          * ptr_sec_desc to be NULL. JRA. Based on
2465                          * a Vista sniff from Martin Zielinski <mz@seh.de>.
2466                          */
2467                         if (UNMARSHALLING(ps)) {
2468                                 ptr_sec_desc = 1;
2469                         } else {
2470                                 ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
2471                         }
2472                         break;
2473                 }
2474         }
2475         if (ptr_sec_desc)
2476         {
2477                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
2478                         return False;
2479         } else {
2480                 uint32 dummy = 0;
2481
2482                 /* Parse a NULL security descriptor.  This should really
2483                    happen inside the sec_io_desc_buf() function. */
2484
2485                 prs_debug(ps, depth, "", "sec_io_desc_buf");
2486                 if (!prs_uint32("size", ps, depth + 1, &dummy))
2487                         return False;
2488                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
2489                         return False;
2490         }
2491         
2492         if(!prs_uint32("command", ps, depth, &q_u->command))
2493                 return False;
2494
2495         return True;
2496 }
2497
2498 /*******************************************************************
2499 ********************************************************************/  
2500
2501 bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
2502 {               
2503         prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
2504         depth++;
2505
2506         if (!prs_align(ps))
2507                 return False;
2508                 
2509         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2510                 return False;
2511
2512         if (!prs_align(ps))
2513                 return False;
2514                 
2515         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2516                 return False;
2517                 
2518         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2519                 return False;
2520                 
2521         if (!prs_werror("status", ps, depth, &r_u->status))
2522                 return False;
2523
2524         return True;            
2525 }
2526
2527 /*******************************************************************
2528 ********************************************************************/  
2529
2530 bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
2531                                 uint32 firstjob,
2532                                 uint32 numofjobs,
2533                                 uint32 level,
2534                                 RPC_BUFFER *buffer,
2535                                 uint32 offered)
2536 {
2537         if (q_u == NULL)
2538         {
2539                 return False;
2540         }
2541         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2542         q_u->firstjob = firstjob;
2543         q_u->numofjobs = numofjobs;
2544         q_u->level = level;
2545         q_u->buffer= buffer;
2546         q_u->offered = offered;
2547         return True;
2548 }
2549
2550 /*******************************************************************
2551 ********************************************************************/  
2552
2553 bool spoolss_io_q_enumjobs(const char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
2554 {
2555         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
2556         depth++;
2557
2558         if (!prs_align(ps))
2559                 return False;
2560
2561         if (!smb_io_pol_hnd("printer handle",&q_u->handle, ps, depth))
2562                 return False;
2563                 
2564         if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
2565                 return False;
2566         if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
2567                 return False;
2568         if (!prs_uint32("level", ps, depth, &q_u->level))
2569                 return False;
2570
2571         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2572                 return False;   
2573
2574         if(!prs_align(ps))
2575                 return False;
2576
2577         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2578                 return False;
2579
2580         return True;
2581 }
2582
2583 /*******************************************************************
2584  Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
2585 ********************************************************************/  
2586
2587 bool spoolss_io_r_enumprinterdrivers(const char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
2588 {
2589         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdrivers");
2590         depth++;
2591
2592         if (!prs_align(ps))
2593                 return False;
2594                 
2595         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2596                 return False;
2597
2598         if (!prs_align(ps))
2599                 return False;
2600                 
2601         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2602                 return False;
2603                 
2604         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2605                 return False;
2606                 
2607         if (!prs_werror("status", ps, depth, &r_u->status))
2608                 return False;
2609
2610         return True;            
2611 }
2612
2613 /*******************************************************************
2614  * init a structure.
2615  ********************************************************************/
2616
2617 bool make_spoolss_q_enumprinterdrivers(SPOOL_Q_ENUMPRINTERDRIVERS *q_u,
2618                                 const char *name,
2619                                 const char *environment,
2620                                 uint32 level,
2621                                 RPC_BUFFER *buffer, uint32 offered)
2622 {
2623         init_buf_unistr2(&q_u->name, &q_u->name_ptr, name);
2624         init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, environment);
2625
2626         q_u->level=level;
2627         q_u->buffer=buffer;
2628         q_u->offered=offered;
2629
2630         return True;
2631 }
2632
2633 /*******************************************************************
2634  Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
2635 ********************************************************************/  
2636
2637 bool spoolss_io_q_enumprinterdrivers(const char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
2638 {
2639
2640         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
2641         depth++;
2642
2643         if (!prs_align(ps))
2644                 return False;
2645                 
2646         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
2647                 return False;
2648         if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
2649                 return False;
2650                 
2651         if (!prs_align(ps))
2652                 return False;
2653         if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
2654                 return False;
2655         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
2656                 return False;
2657                 
2658         if (!prs_align(ps))
2659                 return False;
2660         if (!prs_uint32("level", ps, depth, &q_u->level))
2661                 return False;
2662                 
2663         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2664                 return False;
2665
2666         if (!prs_align(ps))
2667                 return False;
2668                 
2669         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2670                 return False;
2671
2672         return True;
2673 }
2674
2675 /*******************************************************************
2676 ********************************************************************/  
2677
2678 bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
2679 {
2680
2681         prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
2682         depth++;
2683
2684         if (!prs_align(ps))
2685                 return False;                   
2686         if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
2687                 return False;           
2688         if (!prs_uint32("level", ps, depth, &q_u->level))
2689                 return False;   
2690         
2691         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2692                 return False;
2693
2694         if (!prs_align(ps))
2695                 return False;
2696         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2697                 return False;
2698
2699         return True;
2700 }
2701
2702 /*******************************************************************
2703 ********************************************************************/  
2704
2705 bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
2706 {
2707         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
2708         depth++;
2709
2710         if (!prs_align(ps))
2711                 return False;
2712                 
2713         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2714                 return False;
2715
2716         if (!prs_align(ps))
2717                 return False;
2718                 
2719         if (!prs_uint32("size of buffer needed", ps, depth, &r_u->needed))
2720                 return False;
2721                 
2722         if (!prs_uint32("numofforms", ps, depth, &r_u->numofforms))
2723                 return False;
2724                 
2725         if (!prs_werror("status", ps, depth, &r_u->status))
2726                 return False;
2727
2728         return True;
2729 }
2730
2731 /*******************************************************************
2732  Parse a SPOOL_R_ENUMPORTS structure.
2733 ********************************************************************/  
2734
2735 bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
2736 {
2737         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
2738         depth++;
2739
2740         if (!prs_align(ps))
2741                 return False;
2742                 
2743         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
2744                 return False;
2745
2746         if (!prs_align(ps))
2747                 return False;
2748                 
2749         if (!prs_uint32("needed", ps, depth, &r_u->needed))
2750                 return False;
2751                 
2752         if (!prs_uint32("returned", ps, depth, &r_u->returned))
2753                 return False;
2754                 
2755         if (!prs_werror("status", ps, depth, &r_u->status))
2756                 return False;
2757
2758         return True;            
2759 }
2760
2761 /*******************************************************************
2762 ********************************************************************/  
2763
2764 bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
2765 {
2766         prs_debug(ps, depth, desc, "");
2767         depth++;
2768
2769         if (!prs_align(ps))
2770                 return False;
2771
2772         if (!prs_uint32("", ps, depth, &q_u->name_ptr))
2773                 return False;
2774         if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
2775                 return False;
2776
2777         if (!prs_align(ps))
2778                 return False;
2779         if (!prs_uint32("level", ps, depth, &q_u->level))
2780                 return False;
2781                 
2782         if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
2783                 return False;
2784
2785         if (!prs_align(ps))
2786                 return False;
2787         if (!prs_uint32("offered", ps, depth, &q_u->offered))
2788                 return False;
2789
2790         return True;
2791 }
2792
2793 /*******************************************************************
2794  Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure.
2795 ********************************************************************/  
2796
2797 bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth)
2798 {       
2799         prs_debug(ps, depth, desc, "spool_io_printer_info_level_1");
2800         depth++;
2801                 
2802         if(!prs_align(ps))
2803                 return False;
2804
2805         if(!prs_uint32("flags", ps, depth, &il->flags))
2806                 return False;
2807         if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr))
2808                 return False;
2809         if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
2810                 return False;
2811         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
2812                 return False;
2813                 
2814         if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth))
2815                 return False;
2816         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
2817                 return False;
2818         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
2819                 return False;
2820
2821         return True;
2822 }
2823
2824 /*******************************************************************
2825  Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure.
2826 ********************************************************************/  
2827
2828 bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth)
2829 {       
2830         prs_debug(ps, depth, desc, "spool_io_printer_info_level_3");
2831         depth++;
2832                 
2833         if(!prs_align(ps))
2834                 return False;
2835
2836         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
2837                 return False;
2838
2839         return True;
2840 }
2841
2842 /*******************************************************************
2843  Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
2844 ********************************************************************/  
2845
2846 bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
2847 {       
2848         prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
2849         depth++;
2850                 
2851         if(!prs_align(ps))
2852                 return False;
2853
2854         if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
2855                 return False;
2856         if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
2857                 return False;
2858         if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
2859                 return False;
2860         if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
2861                 return False;
2862
2863         if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
2864                 return False;
2865         if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
2866                 return False;
2867         if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
2868                 return False;
2869         if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
2870                 return False;
2871         if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
2872                 return False;
2873         if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
2874                 return False;
2875         if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
2876                 return False;
2877         if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
2878                 return False;
2879         if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
2880                 return False;
2881
2882         if(!prs_uint32("attributes", ps, depth, &il->attributes))
2883                 return False;
2884         if(!prs_uint32("priority", ps, depth, &il->priority))
2885                 return False;
2886         if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
2887                 return False;
2888         if(!prs_uint32("starttime", ps, depth, &il->starttime))
2889                 return False;
2890         if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
2891                 return False;
2892         if(!prs_uint32("status", ps, depth, &il->status))
2893                 return False;
2894         if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
2895                 return False;
2896         if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
2897                 return False;
2898
2899         if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
2900                 return False;
2901         if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
2902                 return False;
2903         if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
2904                 return False;
2905         if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
2906                 return False;
2907         if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
2908                 return False;
2909         if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
2910                 return False;
2911         if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
2912                 return False;
2913         if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
2914                 return False;
2915         if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
2916                 return False;
2917         if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
2918                 return False;
2919         if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
2920                 return False;
2921
2922         return True;
2923 }
2924
2925 bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth)
2926 {       
2927         prs_debug(ps, depth, desc, "spool_io_printer_info_level_7");
2928         depth++;
2929                 
2930         if(!prs_align(ps))
2931                 return False;
2932
2933         if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr))
2934                 return False;
2935         if(!prs_uint32("action", ps, depth, &il->action))
2936                 return False;
2937
2938         if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth))
2939                 return False;
2940         return True;
2941 }
2942
2943 /*******************************************************************
2944 ********************************************************************/  
2945
2946 bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
2947 {
2948         prs_debug(ps, depth, desc, "spool_io_printer_info_level");
2949         depth++;
2950
2951         if(!prs_align(ps))
2952                 return False;
2953         if(!prs_uint32("level", ps, depth, &il->level))
2954                 return False;
2955         if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
2956                 return False;
2957         
2958         /* if no struct inside just return */
2959         if (il->info_ptr==0) {
2960                 if (UNMARSHALLING(ps)) {
2961                         il->info_1=NULL;
2962                         il->info_2=NULL;
2963                 }
2964                 return True;
2965         }
2966                         
2967         switch (il->level) {
2968                 /*
2969                  * level 0 is used by setprinter when managing the queue
2970                  * (hold, stop, start a queue)
2971                  */
2972                 case 0:
2973                         break;
2974                 /* DOCUMENT ME!!! What is level 1 used for? */
2975                 case 1:
2976                 {
2977                         if (UNMARSHALLING(ps)) {
2978                                 if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL)
2979                                         return False;
2980                         }
2981                         if (!spool_io_printer_info_level_1("", il->info_1, ps, depth))
2982                                 return False;
2983                         break;          
2984                 }
2985                 /* 
2986                  * level 2 is used by addprinter
2987                  * and by setprinter when updating printer's info
2988                  */     
2989                 case 2:
2990                         if (UNMARSHALLING(ps)) {
2991                                 if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL)
2992                                         return False;
2993                         }
2994                         if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
2995                                 return False;
2996                         break;          
2997                 /* DOCUMENT ME!!! What is level 3 used for? */
2998                 case 3:
2999                 {
3000                         if (UNMARSHALLING(ps)) {
3001                                 if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL)
3002                                         return False;
3003                         }
3004                         if (!spool_io_printer_info_level_3("", il->info_3, ps, depth))
3005                                 return False;
3006                         break;          
3007                 }
3008                 case 7:
3009                         if (UNMARSHALLING(ps))
3010                                 if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL)
3011                                         return False;
3012                         if (!spool_io_printer_info_level_7("", il->info_7, ps, depth))
3013                                 return False;
3014                         break;
3015         }
3016
3017         return True;
3018 }
3019
3020 /*******************************************************************
3021 ********************************************************************/  
3022
3023 bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
3024 {
3025         uint32 ptr_sec_desc = 0;
3026
3027         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
3028         depth++;
3029
3030         if(!prs_align(ps))
3031                 return False;
3032
3033         if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name))
3034                 return False;
3035         if (!prs_io_unistr2("servername", ps, depth, q_u->server_name))
3036                 return False;
3037
3038         if(!prs_align(ps))
3039                 return False;
3040
3041         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3042                 return False;
3043         
3044         if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
3045                 return False;
3046         
3047         if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
3048                 return False;
3049
3050         if(!prs_align(ps))
3051                 return False;
3052
3053         switch (q_u->level) {
3054                 case 2:
3055                         ptr_sec_desc = q_u->info.info_2->secdesc_ptr;
3056                         break;
3057                 case 3:
3058                         ptr_sec_desc = q_u->info.info_3->secdesc_ptr;
3059                         break;
3060         }
3061         if (ptr_sec_desc) {
3062                 if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth))
3063                         return False;
3064         } else {
3065                 uint32 dummy = 0;
3066
3067                 /* Parse a NULL security descriptor.  This should really
3068                         happen inside the sec_io_desc_buf() function. */
3069
3070                 prs_debug(ps, depth, "", "sec_io_desc_buf");
3071                 if (!prs_uint32("size", ps, depth + 1, &dummy))
3072                         return False;
3073                 if (!prs_uint32("ptr", ps, depth + 1, &dummy))
3074                         return False;
3075         }
3076
3077         if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
3078                 return False;
3079         if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
3080                 return False;
3081
3082         return True;
3083 }
3084
3085 /*******************************************************************
3086 ********************************************************************/  
3087
3088 bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, 
3089                                prs_struct *ps, int depth)
3090 {
3091         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
3092         depth++;
3093         
3094         if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth))
3095                 return False;
3096
3097         if(!prs_werror("status", ps, depth, &r_u->status))
3098                 return False;
3099
3100         return True;
3101 }
3102
3103 /*******************************************************************
3104 ********************************************************************/  
3105
3106 bool spool_io_printer_driver_info_level_3(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, 
3107                                           prs_struct *ps, int depth)
3108 {       
3109         SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
3110         
3111         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
3112         depth++;
3113                 
3114         /* reading */
3115         if (UNMARSHALLING(ps)) {
3116                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_3,1);
3117                 if(il == NULL)
3118                         return False;
3119                 *q_u=il;
3120         }
3121         else {
3122                 il=*q_u;
3123         }
3124         
3125         if(!prs_align(ps))
3126                 return False;
3127
3128         if(!prs_uint32("cversion", ps, depth, &il->cversion))
3129                 return False;
3130         if(!prs_uint32("name", ps, depth, &il->name_ptr))
3131                 return False;
3132         if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
3133                 return False;
3134         if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
3135                 return False;
3136         if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
3137                 return False;
3138         if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
3139                 return False;
3140         if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
3141                 return False;
3142         if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
3143                 return False;
3144         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3145                 return False;
3146         if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
3147                 return False;
3148         if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
3149                 return False;
3150
3151         if(!prs_align(ps))
3152                 return False;
3153         
3154         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3155                 return False;
3156         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3157                 return False;
3158         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3159                 return False;
3160         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3161                 return False;
3162         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3163                 return False;
3164         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3165                 return False;
3166         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3167                 return False;
3168         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3169                 return False;
3170
3171         if(!prs_align(ps))
3172                 return False;
3173                 
3174         if (il->dependentfiles_ptr)
3175                 smb_io_buffer5("", &il->dependentfiles, ps, depth);
3176
3177         return True;
3178 }
3179
3180 /*******************************************************************
3181 parse a SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 structure
3182 ********************************************************************/  
3183
3184 bool spool_io_printer_driver_info_level_6(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 **q_u, 
3185                                           prs_struct *ps, int depth)
3186 {       
3187         SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *il;
3188         
3189         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_6");
3190         depth++;
3191                 
3192         /* reading */
3193         if (UNMARSHALLING(ps)) {
3194                 il=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_DRIVER_INFO_LEVEL_6,1);
3195                 if(il == NULL)
3196                         return False;
3197                 *q_u=il;
3198         }
3199         else {
3200                 il=*q_u;
3201         }
3202         
3203         if(!prs_align(ps))
3204                 return False;
3205
3206         /* 
3207          * I know this seems weird, but I have no other explanation.
3208          * This is observed behavior on both NT4 and 2K servers.
3209          * --jerry
3210          */
3211          
3212         if (!prs_align_uint64(ps))
3213                 return False;
3214
3215         /* parse the main elements the packet */
3216
3217         if(!prs_uint32("cversion       ", ps, depth, &il->version))
3218                 return False;
3219         if(!prs_uint32("name           ", ps, depth, &il->name_ptr))
3220                 return False;
3221         if(!prs_uint32("environment    ", ps, depth, &il->environment_ptr))
3222                 return False;
3223         if(!prs_uint32("driverpath     ", ps, depth, &il->driverpath_ptr))
3224                 return False;
3225         if(!prs_uint32("datafile       ", ps, depth, &il->datafile_ptr))
3226                 return False;
3227         if(!prs_uint32("configfile     ", ps, depth, &il->configfile_ptr))
3228                 return False;
3229         if(!prs_uint32("helpfile       ", ps, depth, &il->helpfile_ptr))
3230                 return False;
3231         if(!prs_uint32("monitorname    ", ps, depth, &il->monitorname_ptr))
3232                 return False;
3233         if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
3234                 return False;
3235         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_len))
3236                 return False;
3237         if(!prs_uint32("dependentfiles ", ps, depth, &il->dependentfiles_ptr))
3238                 return False;
3239         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_len))
3240                 return False;
3241         if(!prs_uint32("previousnames  ", ps, depth, &il->previousnames_ptr))
3242                 return False;
3243         if(!smb_io_time("driverdate    ", &il->driverdate, ps, depth))
3244                 return False;
3245         if(!prs_uint32("dummy4         ", ps, depth, &il->dummy4))
3246                 return False;
3247         if(!prs_uint64("driverversion  ", ps, depth, &il->driverversion))
3248                 return False;
3249         if(!prs_uint32("mfgname        ", ps, depth, &il->mfgname_ptr))
3250                 return False;
3251         if(!prs_uint32("oemurl         ", ps, depth, &il->oemurl_ptr))
3252                 return False;
3253         if(!prs_uint32("hardwareid     ", ps, depth, &il->hardwareid_ptr))
3254                 return False;
3255         if(!prs_uint32("provider       ", ps, depth, &il->provider_ptr))
3256                 return False;
3257
3258         /* parse the structures in the packet */
3259
3260         if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
3261                 return False;
3262         if(!prs_align(ps))
3263                 return False;
3264
3265         if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
3266                 return False;
3267         if(!prs_align(ps))
3268                 return False;
3269
3270         if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
3271                 return False;
3272         if(!prs_align(ps))
3273                 return False;
3274
3275         if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
3276                 return False;
3277         if(!prs_align(ps))
3278                 return False;
3279
3280         if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
3281                 return False;
3282         if(!prs_align(ps))
3283                 return False;
3284
3285         if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
3286                 return False;
3287         if(!prs_align(ps))
3288                 return False;
3289
3290         if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
3291                 return False;
3292         if(!prs_align(ps))
3293                 return False;
3294
3295         if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
3296                 return False;
3297         if(!prs_align(ps))
3298                 return False;
3299         if (il->dependentfiles_ptr) {
3300                 if(!smb_io_buffer5("dependentfiles", &il->dependentfiles, ps, depth))
3301                         return False;
3302                 if(!prs_align(ps))
3303                         return False;
3304         }
3305         if (il->previousnames_ptr) {
3306                 if(!smb_io_buffer5("previousnames", &il->previousnames, ps, depth))
3307                         return False;
3308                 if(!prs_align(ps))
3309                         return False;
3310         }
3311         if(!smb_io_unistr2("mfgname", &il->mfgname, il->mfgname_ptr, ps, depth))
3312                 return False;
3313         if(!prs_align(ps))
3314                 return False;
3315         if(!smb_io_unistr2("oemurl", &il->oemurl, il->oemurl_ptr, ps, depth))
3316                 return False;
3317         if(!prs_align(ps))
3318                 return False;
3319         if(!smb_io_unistr2("hardwareid", &il->hardwareid, il->hardwareid_ptr, ps, depth))
3320                 return False;
3321         if(!prs_align(ps))
3322                 return False;
3323         if(!smb_io_unistr2("provider", &il->provider, il->provider_ptr, ps, depth))
3324                 return False;
3325
3326         return True;
3327 }
3328
3329 /*******************************************************************
3330  read a UNICODE array with null terminated strings 
3331  and null terminated array 
3332  and size of array at beginning
3333 ********************************************************************/  
3334
3335 bool smb_io_unibuffer(const char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
3336 {
3337         if (buffer==NULL) return False;
3338
3339         buffer->offset=0;
3340         buffer->uni_str_len=buffer->uni_max_len;
3341         
3342         if(!prs_uint32("buffer_size", ps, depth, &buffer->uni_max_len))
3343                 return False;
3344
3345         if(!prs_unistr2(True, "buffer     ", ps, depth, buffer))
3346                 return False;
3347
3348         return True;
3349 }
3350
3351 /*******************************************************************
3352 ********************************************************************/  
3353
3354 bool spool_io_printer_driver_info_level(const char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
3355 {
3356         prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
3357         depth++;
3358
3359         if(!prs_align(ps))
3360                 return False;
3361         if(!prs_uint32("level", ps, depth, &il->level))
3362                 return False;
3363         if(!prs_uint32("ptr", ps, depth, &il->ptr))
3364                 return False;
3365
3366         if (il->ptr==0)
3367                 return True;
3368                 
3369         switch (il->level) {
3370                 case 3:
3371                         if(!spool_io_printer_driver_info_level_3("", &il->info_3, ps, depth))
3372                                 return False;
3373                         break;          
3374                 case 6:
3375                         if(!spool_io_printer_driver_info_level_6("", &il->info_6, ps, depth))
3376                                 return False;
3377                         break;          
3378         default:
3379                 return False;
3380         }
3381
3382         return True;
3383 }
3384
3385 /*******************************************************************
3386  make a BUFFER5 struct from a uint16*
3387  ******************************************************************/
3388
3389 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
3390 {
3391
3392         buf5->buf_len = len;
3393         if (src) {
3394                 if (len) {
3395                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
3396                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
3397                                 return False;
3398                         }
3399                 } else {
3400                         buf5->buffer = NULL;
3401                 }
3402         } else {
3403                 buf5->buffer=NULL;
3404         }
3405         
3406         return True;
3407 }
3408
3409 /*******************************************************************
3410  fill in the prs_struct for a ADDPRINTERDRIVER request PDU
3411  ********************************************************************/  
3412
3413 bool spoolss_io_q_addprinterdriver(const char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
3414 {
3415         prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
3416         depth++;
3417
3418         if(!prs_align(ps))
3419                 return False;
3420
3421         if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
3422                 return False;
3423         if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
3424                 return False;
3425                 
3426         if(!prs_align(ps))
3427                 return False;
3428         if(!prs_uint32("info_level", ps, depth, &q_u->level))
3429                 return False;
3430
3431         if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
3432                 return False;
3433
3434         return True;
3435 }
3436
3437 /*******************************************************************
3438 ********************************************************************/  
3439
3440 bool spoolss_io_r_addprinterdriver(const char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
3441 {
3442         prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
3443         depth++;
3444
3445         if(!prs_werror("status", ps, depth, &q_u->status))
3446                 return False;
3447
3448         return True;
3449 }
3450
3451 /*******************************************************************
3452  ********************************************************************/  
3453
3454 bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
3455                               NT_PRINTER_INFO_LEVEL_2  *d)
3456 {
3457         DEBUG(7,("Converting from UNICODE to ASCII\n"));
3458         
3459         d->attributes=uni->attributes;
3460         d->priority=uni->priority;
3461         d->default_priority=uni->default_priority;
3462         d->starttime=uni->starttime;
3463         d->untiltime=uni->untiltime;
3464         d->status=uni->status;
3465         d->cjobs=uni->cjobs;
3466         
3467         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername));
3468         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername));
3469         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename));
3470         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname));
3471         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername));
3472         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment));
3473         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location));
3474         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile));
3475         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor));
3476         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype));
3477         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters));
3478
3479         return True;
3480 }
3481
3482 /*******************************************************************
3483 ********************************************************************/  
3484
3485 bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
3486 {               
3487         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
3488         depth++;
3489
3490         if (!prs_align(ps))
3491                 return False;
3492                 
3493         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3494                 return False;
3495
3496         if (!prs_align(ps))
3497                 return False;
3498                 
3499         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3500                 return False;
3501                 
3502         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3503                 return False;
3504                 
3505         if (!prs_werror("status", ps, depth, &r_u->status))
3506                 return False;
3507
3508         return True;            
3509 }
3510
3511 /*******************************************************************
3512 ********************************************************************/  
3513
3514 bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
3515 {
3516         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
3517         depth++;
3518
3519         if (!prs_align(ps))
3520                 return False;
3521                 
3522         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3523                 return False;
3524         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3525                 return False;
3526                 
3527         if (!prs_align(ps))
3528                 return False;
3529                 
3530         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
3531                 return False;
3532         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3533                 return False;
3534         
3535         if (!prs_align(ps))
3536                 return False;
3537                 
3538         if (!prs_uint32("level", ps, depth, &q_u->level))
3539                 return False;
3540                 
3541         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3542                 return False;
3543
3544         if (!prs_align(ps))
3545                 return False;
3546
3547         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3548                 return False;
3549
3550         return True;
3551 }
3552
3553 /*******************************************************************
3554 ********************************************************************/  
3555
3556 bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
3557 {               
3558         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
3559         depth++;
3560
3561         if (!prs_align(ps))
3562                 return False;
3563                 
3564         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3565                 return False;
3566
3567         if (!prs_align(ps))
3568                 return False;
3569                 
3570         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3571                 return False;
3572                 
3573         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3574                 return False;
3575                 
3576         if (!prs_werror("status", ps, depth, &r_u->status))
3577                 return False;
3578
3579         return True;            
3580 }
3581
3582 /*******************************************************************
3583 ********************************************************************/  
3584
3585 bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
3586 {
3587         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
3588         depth++;
3589
3590         if (!prs_align(ps))
3591                 return False;
3592                 
3593         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3594                 return False;
3595         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3596                 return False;
3597                 
3598         if (!prs_align(ps))
3599                 return False;
3600                 
3601         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
3602                 return False;
3603         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
3604                 return False;
3605         
3606         if (!prs_align(ps))
3607                 return False;
3608                 
3609         if (!prs_uint32("level", ps, depth, &q_u->level))
3610                 return False;
3611                 
3612         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
3613                 return False;
3614
3615         if (!prs_align(ps))
3616                 return False;
3617
3618         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3619                 return False;
3620
3621         return True;
3622 }
3623
3624 /*******************************************************************
3625  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
3626 ********************************************************************/  
3627
3628 bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
3629 {
3630         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
3631         depth++;
3632
3633         if (!prs_align(ps))
3634                 return False;
3635                 
3636         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3637                 return False;
3638         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3639                 return False;
3640                 
3641         if (!prs_align(ps))
3642                 return False;
3643                                 
3644         if (!prs_uint32("level", ps, depth, &q_u->level))
3645                 return False;
3646                 
3647         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3648                 return False;
3649
3650         if (!prs_align(ps))
3651                 return False;
3652
3653         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3654                 return False;
3655
3656         return True;
3657 }
3658
3659 /*******************************************************************
3660 ********************************************************************/  
3661
3662 bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
3663 {               
3664         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
3665         depth++;
3666
3667         if (!prs_align(ps))
3668                 return False;
3669                 
3670         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3671                 return False;
3672
3673         if (!prs_align(ps))
3674                 return False;
3675                 
3676         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3677                 return False;
3678                 
3679         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3680                 return False;
3681                 
3682         if (!prs_werror("status", ps, depth, &r_u->status))
3683                 return False;
3684
3685         return True;            
3686 }
3687
3688 /*******************************************************************
3689 ********************************************************************/  
3690
3691 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
3692 {       
3693         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
3694         depth++;
3695
3696         if(!prs_align(ps))
3697                 return False;
3698         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
3699                 return False;
3700
3701         if (UNMARSHALLING(ps) && r_u->valuesize) {
3702                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
3703                 if (!r_u->value) {
3704                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
3705                         return False;
3706                 }
3707         }
3708
3709         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
3710                 return False;
3711
3712         if(!prs_align(ps))
3713                 return False;
3714
3715         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
3716                 return False;
3717
3718         if(!prs_uint32("type", ps, depth, &r_u->type))
3719                 return False;
3720
3721         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
3722                 return False;
3723
3724         if (UNMARSHALLING(ps) && r_u->datasize) {
3725                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
3726                 if (!r_u->data) {
3727                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
3728                         return False;
3729                 }
3730         }
3731
3732         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
3733                 return False;
3734         if(!prs_align(ps))
3735                 return False;
3736
3737         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
3738                 return False;
3739         if(!prs_werror("status", ps, depth, &r_u->status))
3740                 return False;
3741
3742         return True;
3743 }
3744
3745 /*******************************************************************
3746 ********************************************************************/  
3747
3748 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
3749 {
3750         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
3751         depth++;
3752
3753         if(!prs_align(ps))
3754                 return False;
3755         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3756                 return False;
3757         if(!prs_uint32("index", ps, depth, &q_u->index))
3758                 return False;
3759         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
3760                 return False;
3761         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
3762                 return False;
3763
3764         return True;
3765 }
3766
3767 /*******************************************************************
3768 ********************************************************************/  
3769
3770 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
3771                 const POLICY_HND *hnd,
3772                 uint32 idx, uint32 valuelen, uint32 datalen)
3773 {
3774         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3775         q_u->index=idx;
3776         q_u->valuesize=valuelen;
3777         q_u->datasize=datalen;
3778
3779         return True;
3780 }
3781
3782 /*******************************************************************
3783 ********************************************************************/  
3784
3785 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
3786                                       const POLICY_HND *hnd, const char *key,
3787                                       uint32 size)
3788 {
3789         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3790         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
3791         q_u->size = size;
3792
3793         return True;
3794 }
3795
3796 /*******************************************************************
3797 ********************************************************************/  
3798 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
3799                                    char* value, uint32 data_type, char* data, uint32 data_size)
3800 {
3801         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3802         q_u->type = data_type;
3803         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
3804
3805         q_u->max_len = q_u->real_len = data_size;
3806         q_u->data = (unsigned char *)data;
3807         
3808         return True;
3809 }
3810
3811 /*******************************************************************
3812 ********************************************************************/  
3813
3814 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
3815 {
3816         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
3817         depth++;
3818
3819         if(!prs_align(ps))
3820                 return False;
3821         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3822                 return False;
3823         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
3824                 return False;
3825
3826         if(!prs_align(ps))
3827                 return False;
3828
3829         if(!prs_uint32("type", ps, depth, &q_u->type))
3830                 return False;
3831
3832         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
3833                 return False;
3834
3835         switch (q_u->type)
3836         {
3837                 case REG_SZ:
3838                 case REG_BINARY:
3839                 case REG_DWORD:
3840                 case REG_MULTI_SZ:
3841                         if (q_u->max_len) {
3842                                 if (UNMARSHALLING(ps))
3843                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
3844                                 if(q_u->data == NULL)
3845                                         return False;
3846                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
3847                                         return False;
3848                         }
3849                         if(!prs_align(ps))
3850                                 return False;
3851                         break;
3852         }       
3853         
3854         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
3855                 return False;
3856
3857         return True;
3858 }
3859
3860 /*******************************************************************
3861 ********************************************************************/  
3862
3863 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
3864 {
3865         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
3866         depth++;
3867
3868         if(!prs_align(ps))
3869                 return False;
3870         if(!prs_werror("status",     ps, depth, &r_u->status))
3871                 return False;
3872
3873         return True;
3874 }
3875
3876 /*******************************************************************
3877  Parse a SPOOL_R_GETJOB structure.
3878 ********************************************************************/  
3879
3880 bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
3881 {               
3882         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
3883         depth++;
3884
3885         if (!prs_align(ps))
3886                 return False;
3887                 
3888         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3889                 return False;
3890
3891         if (!prs_align(ps))
3892                 return False;
3893                 
3894         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3895                 return False;
3896                 
3897         if (!prs_werror("status", ps, depth, &r_u->status))
3898                 return False;
3899
3900         return True;            
3901 }
3902
3903 /*******************************************************************
3904  Parse a SPOOL_Q_GETJOB structure.
3905 ********************************************************************/  
3906
3907 bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
3908 {
3909         prs_debug(ps, depth, desc, "");
3910         depth++;
3911
3912         if(!prs_align(ps))
3913                 return False;
3914
3915         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3916                 return False;
3917         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
3918                 return False;
3919         if(!prs_uint32("level", ps, depth, &q_u->level))
3920                 return False;
3921         
3922         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3923                 return False;
3924
3925         if(!prs_align(ps))
3926                 return False;
3927         
3928         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3929                 return False;
3930
3931         return True;
3932 }
3933
3934 void free_devmode(DEVICEMODE *devmode)
3935 {
3936         if (devmode!=NULL) {
3937                 SAFE_FREE(devmode->dev_private);
3938                 SAFE_FREE(devmode);
3939         }
3940 }
3941
3942 void free_printer_info_1(PRINTER_INFO_1 *printer)
3943 {
3944         SAFE_FREE(printer);
3945 }
3946
3947 void free_printer_info_2(PRINTER_INFO_2 *printer)
3948 {
3949         if (printer!=NULL) {
3950                 free_devmode(printer->devmode);
3951                 printer->devmode = NULL;
3952                 SAFE_FREE(printer);
3953         }
3954 }
3955
3956 void free_printer_info_3(PRINTER_INFO_3 *printer)
3957 {
3958         SAFE_FREE(printer);
3959 }
3960
3961 void free_printer_info_4(PRINTER_INFO_4 *printer)
3962 {
3963         SAFE_FREE(printer);
3964 }
3965
3966 void free_printer_info_5(PRINTER_INFO_5 *printer)
3967 {
3968         SAFE_FREE(printer);
3969 }
3970
3971 void free_printer_info_6(PRINTER_INFO_6 *printer)
3972 {
3973         SAFE_FREE(printer);
3974 }
3975
3976 void free_printer_info_7(PRINTER_INFO_7 *printer)
3977 {
3978         SAFE_FREE(printer);
3979 }
3980
3981 void free_job_info_2(JOB_INFO_2 *job)
3982 {
3983     if (job!=NULL)
3984         free_devmode(job->devmode);
3985 }
3986
3987 /*******************************************************************
3988  * read a structure.
3989  ********************************************************************/  
3990 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
3991                                    POLICY_HND *hnd, const char *key, 
3992                                    uint32 size)
3993 {
3994         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
3995
3996         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3997         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
3998         q_u->size = size;
3999
4000         return True;
4001 }
4002
4003 /*******************************************************************
4004  * read a structure.
4005  ********************************************************************/  
4006
4007 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
4008 {
4009         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
4010         depth++;
4011
4012         if(!prs_align(ps))
4013                 return False;
4014         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4015                 return False;
4016                 
4017         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
4018                 return False;
4019
4020         if(!prs_align(ps))
4021                 return False;
4022         
4023         if(!prs_uint32("size", ps, depth, &q_u->size))
4024                 return False;
4025
4026         return True;
4027 }
4028
4029 /*******************************************************************
4030  * write a structure.
4031  ********************************************************************/  
4032
4033 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
4034 {
4035         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
4036         depth++;
4037
4038         if(!prs_align(ps))
4039                 return False;
4040
4041         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
4042                 return False;
4043         
4044         if(!prs_align(ps))
4045                 return False;
4046
4047         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
4048                 return False;
4049
4050         if(!prs_werror("status",     ps, depth, &r_u->status))
4051                 return False;
4052
4053         return True;
4054 }
4055
4056 /*******************************************************************
4057  * read a structure.
4058  ********************************************************************/  
4059
4060 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
4061 {
4062         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
4063         depth++;
4064
4065         if(!prs_align(ps))
4066                 return False;
4067         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
4068                 return False;
4069                 
4070         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
4071                 return False;
4072
4073         if(!prs_align(ps))
4074                 return False;
4075         
4076         if(!prs_uint32("size", ps, depth, &q_u->size))
4077                 return False;
4078
4079         return True;
4080 }
4081
4082 /*******************************************************************
4083 ********************************************************************/  
4084
4085 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
4086                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
4087 {
4088         int     i;
4089         uint32  valuename_offset,
4090                 data_offset,
4091                 current_offset;
4092         const uint32 basic_unit = 20; /* size of static portion of enum_values */
4093
4094         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
4095         depth++;        
4096
4097         /* 
4098          * offset data begins at 20 bytes per structure * size_of_array.
4099          * Don't forget the uint32 at the beginning 
4100          * */
4101         
4102         current_offset = basic_unit * ctr->size_of_array;
4103         
4104         /* first loop to write basic enum_value information */
4105         
4106         if (UNMARSHALLING(ps) && ctr->size_of_array) {
4107                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
4108                 if (!ctr->values)
4109                         return False;
4110         }
4111
4112         for (i=0; i<ctr->size_of_array; i++) {
4113                 uint32 base_offset, return_offset;
4114
4115                 base_offset = prs_offset(ps);
4116
4117                 valuename_offset = current_offset;
4118                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
4119                         return False;
4120
4121                 /* Read or write the value. */
4122
4123                 return_offset = prs_offset(ps);
4124
4125                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
4126                         return False;
4127                 }
4128
4129                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
4130                         return False;
4131
4132                 /* And go back. */
4133                 if (!prs_set_offset(ps, return_offset))
4134                         return False;
4135
4136                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
4137                         return False;
4138         
4139                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
4140                         return False;
4141         
4142                 data_offset = ctr->values[i].value_len + valuename_offset;
4143                 
4144                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
4145                         return False;
4146
4147                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
4148                         return False;
4149                         
4150                 /* Read or write the data. */
4151
4152                 return_offset = prs_offset(ps);
4153
4154                 if (!prs_set_offset(ps, base_offset + data_offset)) {
4155                         return False;
4156                 }
4157
4158                 if ( ctr->values[i].data_len ) {
4159                         if ( UNMARSHALLING(ps) ) {
4160                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
4161                                 if (!ctr->values[i].data)
4162                                         return False;
4163                         }
4164                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
4165                                 return False;
4166                 }
4167
4168                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
4169                 /* account for 2 byte alignment */
4170                 current_offset += (current_offset % 2);
4171
4172                 /* Remember how far we got. */
4173                 data_offset = prs_offset(ps);
4174
4175                 /* And go back. */
4176                 if (!prs_set_offset(ps, return_offset))
4177                         return False;
4178
4179         }
4180
4181         /* Go to the last data offset we got to. */
4182
4183         if (!prs_set_offset(ps, data_offset))
4184                 return False;
4185
4186         /* And ensure we're 2 byte aligned. */
4187
4188         if ( !prs_align_uint16(ps) )
4189                 return False;
4190
4191         return True;    
4192 }
4193
4194 /*******************************************************************
4195  * write a structure.
4196  ********************************************************************/  
4197
4198 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
4199 {
4200         uint32 data_offset, end_offset;
4201         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
4202         depth++;
4203
4204         if(!prs_align(ps))
4205                 return False;
4206
4207         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
4208                 return False;
4209
4210         data_offset = prs_offset(ps);
4211
4212         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
4213                 return False;
4214
4215         if(!prs_align(ps))
4216                 return False;
4217
4218         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
4219                 return False;
4220
4221         if(!prs_uint32("returned",   ps, depth, &r_u->returned))
4222                 return False;
4223
4224         if(!prs_werror("status",     ps, depth, &r_u->status))
4225                 return False;
4226
4227         r_u->ctr.size_of_array = r_u->returned;
4228
4229         end_offset = prs_offset(ps);
4230
4231         if (!prs_set_offset(ps, data_offset))
4232                 return False;
4233
4234         if (r_u->ctr.size)
4235                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
4236                         return False;
4237
4238         if (!prs_set_offset(ps, end_offset))
4239                 return False;
4240         return True;
4241 }
4242
4243 /*******************************************************************
4244  * init a structure.
4245  ********************************************************************/
4246
4247 bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
4248                               uint32 level, RPC_BUFFER *buffer,
4249                               uint32 offered)
4250 {
4251         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
4252         q_u->level = level;
4253         q_u->buffer=buffer;
4254         q_u->offered=offered;
4255
4256         return True;
4257 }
4258
4259 /*******************************************************************
4260  * init a structure.
4261  ********************************************************************/
4262
4263 bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
4264                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
4265                            uint32 offered)
4266 {
4267         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
4268         q_u->jobid = jobid;
4269         q_u->level = level;
4270         q_u->buffer = buffer;
4271         q_u->offered = offered;
4272
4273         return True;
4274 }