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