s3-spoolss: remove some left-over hand marshalling code and structs.
[ab/samba.git/.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  make a BUFFER5 struct from a uint16*
3105  ******************************************************************/
3106
3107 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
3108 {
3109
3110         buf5->buf_len = len;
3111         if (src) {
3112                 if (len) {
3113                         if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
3114                                 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
3115                                 return False;
3116                         }
3117                 } else {
3118                         buf5->buffer = NULL;
3119                 }
3120         } else {
3121                 buf5->buffer=NULL;
3122         }
3123         
3124         return True;
3125 }
3126
3127 /*******************************************************************
3128  ********************************************************************/  
3129
3130 bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
3131                               NT_PRINTER_INFO_LEVEL_2  *d)
3132 {
3133         DEBUG(7,("Converting from UNICODE to ASCII\n"));
3134         
3135         d->attributes=uni->attributes;
3136         d->priority=uni->priority;
3137         d->default_priority=uni->default_priority;
3138         d->starttime=uni->starttime;
3139         d->untiltime=uni->untiltime;
3140         d->status=uni->status;
3141         d->cjobs=uni->cjobs;
3142         
3143         unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername));
3144         unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername));
3145         unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename));
3146         unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname));
3147         unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername));
3148         unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment));
3149         unistr2_to_ascii(d->location, &uni->location, sizeof(d->location));
3150         unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile));
3151         unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor));
3152         unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype));
3153         unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters));
3154
3155         return True;
3156 }
3157
3158 /*******************************************************************
3159 ********************************************************************/  
3160
3161 bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
3162 {               
3163         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
3164         depth++;
3165
3166         if (!prs_align(ps))
3167                 return False;
3168                 
3169         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3170                 return False;
3171
3172         if (!prs_align(ps))
3173                 return False;
3174                 
3175         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3176                 return False;
3177                 
3178         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3179                 return False;
3180                 
3181         if (!prs_werror("status", ps, depth, &r_u->status))
3182                 return False;
3183
3184         return True;            
3185 }
3186
3187 /*******************************************************************
3188 ********************************************************************/  
3189
3190 bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth)
3191 {
3192         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
3193         depth++;
3194
3195         if (!prs_align(ps))
3196                 return False;
3197                 
3198         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3199                 return False;
3200         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3201                 return False;
3202                 
3203         if (!prs_align(ps))
3204                 return False;
3205                 
3206         if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
3207                 return False;
3208         if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
3209                 return False;
3210         
3211         if (!prs_align(ps))
3212                 return False;
3213                 
3214         if (!prs_uint32("level", ps, depth, &q_u->level))
3215                 return False;
3216                 
3217         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3218                 return False;
3219
3220         if (!prs_align(ps))
3221                 return False;
3222
3223         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3224                 return False;
3225
3226         return True;
3227 }
3228
3229 /*******************************************************************
3230 ********************************************************************/  
3231
3232 bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
3233 {               
3234         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
3235         depth++;
3236
3237         if (!prs_align(ps))
3238                 return False;
3239                 
3240         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3241                 return False;
3242
3243         if (!prs_align(ps))
3244                 return False;
3245                 
3246         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3247                 return False;
3248                 
3249         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3250                 return False;
3251                 
3252         if (!prs_werror("status", ps, depth, &r_u->status))
3253                 return False;
3254
3255         return True;            
3256 }
3257
3258 /*******************************************************************
3259 ********************************************************************/  
3260
3261 bool spoolss_io_q_enumprintprocdatatypes(const char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
3262 {
3263         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
3264         depth++;
3265
3266         if (!prs_align(ps))
3267                 return False;
3268                 
3269         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3270                 return False;
3271         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3272                 return False;
3273                 
3274         if (!prs_align(ps))
3275                 return False;
3276                 
3277         if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
3278                 return False;
3279         if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
3280                 return False;
3281         
3282         if (!prs_align(ps))
3283                 return False;
3284                 
3285         if (!prs_uint32("level", ps, depth, &q_u->level))
3286                 return False;
3287                 
3288         if(!prs_rpcbuffer_p("buffer", ps, depth, &q_u->buffer))
3289                 return False;
3290
3291         if (!prs_align(ps))
3292                 return False;
3293
3294         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3295                 return False;
3296
3297         return True;
3298 }
3299
3300 /*******************************************************************
3301  Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
3302 ********************************************************************/  
3303
3304 bool spoolss_io_q_enumprintmonitors(const char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
3305 {
3306         prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
3307         depth++;
3308
3309         if (!prs_align(ps))
3310                 return False;
3311                 
3312         if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
3313                 return False;
3314         if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
3315                 return False;
3316                 
3317         if (!prs_align(ps))
3318                 return False;
3319                                 
3320         if (!prs_uint32("level", ps, depth, &q_u->level))
3321                 return False;
3322                 
3323         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3324                 return False;
3325
3326         if (!prs_align(ps))
3327                 return False;
3328
3329         if (!prs_uint32("offered", ps, depth, &q_u->offered))
3330                 return False;
3331
3332         return True;
3333 }
3334
3335 /*******************************************************************
3336 ********************************************************************/  
3337
3338 bool spoolss_io_r_enumprintmonitors(const char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
3339 {               
3340         prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
3341         depth++;
3342
3343         if (!prs_align(ps))
3344                 return False;
3345                 
3346         if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
3347                 return False;
3348
3349         if (!prs_align(ps))
3350                 return False;
3351                 
3352         if (!prs_uint32("needed", ps, depth, &r_u->needed))
3353                 return False;
3354                 
3355         if (!prs_uint32("returned", ps, depth, &r_u->returned))
3356                 return False;
3357                 
3358         if (!prs_werror("status", ps, depth, &r_u->status))
3359                 return False;
3360
3361         return True;            
3362 }
3363
3364 /*******************************************************************
3365 ********************************************************************/  
3366
3367 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
3368 {       
3369         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
3370         depth++;
3371
3372         if(!prs_align(ps))
3373                 return False;
3374         if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
3375                 return False;
3376
3377         if (UNMARSHALLING(ps) && r_u->valuesize) {
3378                 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
3379                 if (!r_u->value) {
3380                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
3381                         return False;
3382                 }
3383         }
3384
3385         if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
3386                 return False;
3387
3388         if(!prs_align(ps))
3389                 return False;
3390
3391         if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
3392                 return False;
3393
3394         if(!prs_uint32("type", ps, depth, &r_u->type))
3395                 return False;
3396
3397         if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
3398                 return False;
3399
3400         if (UNMARSHALLING(ps) && r_u->datasize) {
3401                 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
3402                 if (!r_u->data) {
3403                         DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
3404                         return False;
3405                 }
3406         }
3407
3408         if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
3409                 return False;
3410         if(!prs_align(ps))
3411                 return False;
3412
3413         if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
3414                 return False;
3415         if(!prs_werror("status", ps, depth, &r_u->status))
3416                 return False;
3417
3418         return True;
3419 }
3420
3421 /*******************************************************************
3422 ********************************************************************/  
3423
3424 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
3425 {
3426         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
3427         depth++;
3428
3429         if(!prs_align(ps))
3430                 return False;
3431         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3432                 return False;
3433         if(!prs_uint32("index", ps, depth, &q_u->index))
3434                 return False;
3435         if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
3436                 return False;
3437         if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
3438                 return False;
3439
3440         return True;
3441 }
3442
3443 /*******************************************************************
3444 ********************************************************************/  
3445
3446 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
3447                 const POLICY_HND *hnd,
3448                 uint32 idx, uint32 valuelen, uint32 datalen)
3449 {
3450         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3451         q_u->index=idx;
3452         q_u->valuesize=valuelen;
3453         q_u->datasize=datalen;
3454
3455         return True;
3456 }
3457
3458 /*******************************************************************
3459 ********************************************************************/  
3460
3461 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
3462                                       const POLICY_HND *hnd, const char *key,
3463                                       uint32 size)
3464 {
3465         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3466         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
3467         q_u->size = size;
3468
3469         return True;
3470 }
3471
3472 /*******************************************************************
3473 ********************************************************************/  
3474 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
3475                                    char* value, uint32 data_type, char* data, uint32 data_size)
3476 {
3477         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3478         q_u->type = data_type;
3479         init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
3480
3481         q_u->max_len = q_u->real_len = data_size;
3482         q_u->data = (unsigned char *)data;
3483         
3484         return True;
3485 }
3486
3487 /*******************************************************************
3488 ********************************************************************/  
3489
3490 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
3491 {
3492         prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
3493         depth++;
3494
3495         if(!prs_align(ps))
3496                 return False;
3497         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3498                 return False;
3499         if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
3500                 return False;
3501
3502         if(!prs_align(ps))
3503                 return False;
3504
3505         if(!prs_uint32("type", ps, depth, &q_u->type))
3506                 return False;
3507
3508         if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
3509                 return False;
3510
3511         switch (q_u->type)
3512         {
3513                 case REG_SZ:
3514                 case REG_BINARY:
3515                 case REG_DWORD:
3516                 case REG_MULTI_SZ:
3517                         if (q_u->max_len) {
3518                                 if (UNMARSHALLING(ps))
3519                                         q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
3520                                 if(q_u->data == NULL)
3521                                         return False;
3522                                 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
3523                                         return False;
3524                         }
3525                         if(!prs_align(ps))
3526                                 return False;
3527                         break;
3528         }       
3529         
3530         if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
3531                 return False;
3532
3533         return True;
3534 }
3535
3536 /*******************************************************************
3537 ********************************************************************/  
3538
3539 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
3540 {
3541         prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
3542         depth++;
3543
3544         if(!prs_align(ps))
3545                 return False;
3546         if(!prs_werror("status",     ps, depth, &r_u->status))
3547                 return False;
3548
3549         return True;
3550 }
3551
3552 /*******************************************************************
3553  Parse a SPOOL_R_GETJOB structure.
3554 ********************************************************************/  
3555
3556 bool spoolss_io_r_getjob(const char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
3557 {               
3558         prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
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_werror("status", ps, depth, &r_u->status))
3574                 return False;
3575
3576         return True;            
3577 }
3578
3579 /*******************************************************************
3580  Parse a SPOOL_Q_GETJOB structure.
3581 ********************************************************************/  
3582
3583 bool spoolss_io_q_getjob(const char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
3584 {
3585         prs_debug(ps, depth, desc, "");
3586         depth++;
3587
3588         if(!prs_align(ps))
3589                 return False;
3590
3591         if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
3592                 return False;
3593         if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
3594                 return False;
3595         if(!prs_uint32("level", ps, depth, &q_u->level))
3596                 return False;
3597         
3598         if(!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
3599                 return False;
3600
3601         if(!prs_align(ps))
3602                 return False;
3603         
3604         if(!prs_uint32("offered", ps, depth, &q_u->offered))
3605                 return False;
3606
3607         return True;
3608 }
3609
3610 void free_devmode(DEVICEMODE *devmode)
3611 {
3612         if (devmode!=NULL) {
3613                 SAFE_FREE(devmode->dev_private);
3614                 SAFE_FREE(devmode);
3615         }
3616 }
3617
3618 void free_printer_info_1(PRINTER_INFO_1 *printer)
3619 {
3620         SAFE_FREE(printer);
3621 }
3622
3623 void free_printer_info_2(PRINTER_INFO_2 *printer)
3624 {
3625         if (printer!=NULL) {
3626                 free_devmode(printer->devmode);
3627                 printer->devmode = NULL;
3628                 SAFE_FREE(printer);
3629         }
3630 }
3631
3632 void free_printer_info_3(PRINTER_INFO_3 *printer)
3633 {
3634         SAFE_FREE(printer);
3635 }
3636
3637 void free_printer_info_4(PRINTER_INFO_4 *printer)
3638 {
3639         SAFE_FREE(printer);
3640 }
3641
3642 void free_printer_info_5(PRINTER_INFO_5 *printer)
3643 {
3644         SAFE_FREE(printer);
3645 }
3646
3647 void free_printer_info_6(PRINTER_INFO_6 *printer)
3648 {
3649         SAFE_FREE(printer);
3650 }
3651
3652 void free_printer_info_7(PRINTER_INFO_7 *printer)
3653 {
3654         SAFE_FREE(printer);
3655 }
3656
3657 void free_job_info_2(JOB_INFO_2 *job)
3658 {
3659     if (job!=NULL)
3660         free_devmode(job->devmode);
3661 }
3662
3663 /*******************************************************************
3664  * read a structure.
3665  ********************************************************************/  
3666 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u, 
3667                                    POLICY_HND *hnd, const char *key, 
3668                                    uint32 size)
3669 {
3670         DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
3671
3672         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
3673         init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
3674         q_u->size = size;
3675
3676         return True;
3677 }
3678
3679 /*******************************************************************
3680  * read a structure.
3681  ********************************************************************/  
3682
3683 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
3684 {
3685         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
3686         depth++;
3687
3688         if(!prs_align(ps))
3689                 return False;
3690         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3691                 return False;
3692                 
3693         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
3694                 return False;
3695
3696         if(!prs_align(ps))
3697                 return False;
3698         
3699         if(!prs_uint32("size", ps, depth, &q_u->size))
3700                 return False;
3701
3702         return True;
3703 }
3704
3705 /*******************************************************************
3706  * write a structure.
3707  ********************************************************************/  
3708
3709 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
3710 {
3711         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
3712         depth++;
3713
3714         if(!prs_align(ps))
3715                 return False;
3716
3717         if (!smb_io_buffer5("", &r_u->keys, ps, depth))
3718                 return False;
3719         
3720         if(!prs_align(ps))
3721                 return False;
3722
3723         if(!prs_uint32("needed",     ps, depth, &r_u->needed))
3724                 return False;
3725
3726         if(!prs_werror("status",     ps, depth, &r_u->status))
3727                 return False;
3728
3729         return True;
3730 }
3731
3732 /*******************************************************************
3733  * read a structure.
3734  ********************************************************************/  
3735
3736 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
3737 {
3738         prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
3739         depth++;
3740
3741         if(!prs_align(ps))
3742                 return False;
3743         if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
3744                 return False;
3745                 
3746         if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
3747                 return False;
3748
3749         if(!prs_align(ps))
3750                 return False;
3751         
3752         if(!prs_uint32("size", ps, depth, &q_u->size))
3753                 return False;
3754
3755         return True;
3756 }
3757
3758 /*******************************************************************
3759 ********************************************************************/  
3760
3761 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, 
3762                                 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
3763 {
3764         int     i;
3765         uint32  valuename_offset,
3766                 data_offset,
3767                 current_offset;
3768         const uint32 basic_unit = 20; /* size of static portion of enum_values */
3769
3770         prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
3771         depth++;        
3772
3773         /* 
3774          * offset data begins at 20 bytes per structure * size_of_array.
3775          * Don't forget the uint32 at the beginning 
3776          * */
3777         
3778         current_offset = basic_unit * ctr->size_of_array;
3779         
3780         /* first loop to write basic enum_value information */
3781         
3782         if (UNMARSHALLING(ps) && ctr->size_of_array) {
3783                 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
3784                 if (!ctr->values)
3785                         return False;
3786         }
3787
3788         for (i=0; i<ctr->size_of_array; i++) {
3789                 uint32 base_offset, return_offset;
3790
3791                 base_offset = prs_offset(ps);
3792
3793                 valuename_offset = current_offset;
3794                 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
3795                         return False;
3796
3797                 /* Read or write the value. */
3798
3799                 return_offset = prs_offset(ps);
3800
3801                 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
3802                         return False;
3803                 }
3804
3805                 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
3806                         return False;
3807
3808                 /* And go back. */
3809                 if (!prs_set_offset(ps, return_offset))
3810                         return False;
3811
3812                 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
3813                         return False;
3814         
3815                 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
3816                         return False;
3817         
3818                 data_offset = ctr->values[i].value_len + valuename_offset;
3819                 
3820                 if (!prs_uint32("data_offset", ps, depth, &data_offset))
3821                         return False;
3822
3823                 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
3824                         return False;
3825                         
3826                 /* Read or write the data. */
3827
3828                 return_offset = prs_offset(ps);
3829
3830                 if (!prs_set_offset(ps, base_offset + data_offset)) {
3831                         return False;
3832                 }
3833
3834                 if ( ctr->values[i].data_len ) {
3835                         if ( UNMARSHALLING(ps) ) {
3836                                 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
3837                                 if (!ctr->values[i].data)
3838                                         return False;
3839                         }
3840                         if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
3841                                 return False;
3842                 }
3843
3844                 current_offset  = data_offset + ctr->values[i].data_len - basic_unit;
3845                 /* account for 2 byte alignment */
3846                 current_offset += (current_offset % 2);
3847
3848                 /* Remember how far we got. */
3849                 data_offset = prs_offset(ps);
3850
3851                 /* And go back. */
3852                 if (!prs_set_offset(ps, return_offset))
3853                         return False;
3854
3855         }
3856
3857         /* Go to the last data offset we got to. */
3858
3859         if (!prs_set_offset(ps, data_offset))
3860                 return False;
3861
3862         /* And ensure we're 2 byte aligned. */
3863
3864         if ( !prs_align_uint16(ps) )
3865                 return False;
3866
3867         return True;    
3868 }
3869
3870 /*******************************************************************
3871  * write a structure.
3872  ********************************************************************/  
3873
3874 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
3875 {
3876         uint32 data_offset, end_offset;
3877         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
3878         depth++;
3879
3880         if(!prs_align(ps))
3881                 return False;
3882
3883         if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
3884                 return False;
3885
3886         data_offset = prs_offset(ps);
3887
3888         if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
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_uint32("returned",   ps, depth, &r_u->returned))
3898                 return False;
3899
3900         if(!prs_werror("status",     ps, depth, &r_u->status))
3901                 return False;
3902
3903         r_u->ctr.size_of_array = r_u->returned;
3904
3905         end_offset = prs_offset(ps);
3906
3907         if (!prs_set_offset(ps, data_offset))
3908                 return False;
3909
3910         if (r_u->ctr.size)
3911                 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
3912                         return False;
3913
3914         if (!prs_set_offset(ps, end_offset))
3915                 return False;
3916         return True;
3917 }
3918
3919 /*******************************************************************
3920  * init a structure.
3921  ********************************************************************/
3922
3923 bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, 
3924                               uint32 level, RPC_BUFFER *buffer,
3925                               uint32 offered)
3926 {
3927         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
3928         q_u->level = level;
3929         q_u->buffer=buffer;
3930         q_u->offered=offered;
3931
3932         return True;
3933 }
3934
3935 /*******************************************************************
3936  * init a structure.
3937  ********************************************************************/
3938
3939 bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, 
3940                            uint32 jobid, uint32 level, RPC_BUFFER *buffer,
3941                            uint32 offered)
3942 {
3943         memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
3944         q_u->jobid = jobid;
3945         q_u->level = level;
3946         q_u->buffer = buffer;
3947         q_u->offered = offered;
3948
3949         return True;
3950 }