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