debugging rpcclient spoolenum and spooljobs commands. oh, did i forget
[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                 const char *printername,
422                 uint32 cbbuf, uint32 devmod, uint32 des_access,
423                 const char *station,
424                 const 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 *)Realloc(NULL, 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         uint32 tmp_ct = 0;
2026
2027         PRINTER_INFO_1 *info1;
2028         PRINTER_INFO_2 *info2;
2029
2030         prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
2031         depth++;
2032         prs_align(ps);
2033         prs_uint32("pointer", ps, depth, &useless_ptr);
2034
2035         if (!ps->io)
2036         {
2037                 /* writing */
2038                 for(i=0;i<r_u->returned;i++)
2039                 {
2040                         switch (r_u->level)
2041                         {
2042                                 case 1:
2043                                         info1 = r_u->printer.printers_1[i];
2044                                         bufsize_required += spoolss_size_printer_info_1(info1); 
2045                                         break;
2046                                 case 2:
2047                                         info2 = r_u->printer.printers_2[i];
2048                                         bufsize_required += spoolss_size_printer_info_2(info2); 
2049                                         break;
2050                         }
2051                 }
2052
2053                 DEBUG(4,("spoolss_io_r_enumprinters, size needed: %d\n",bufsize_required));
2054                 DEBUG(4,("spoolss_io_r_enumprinters, size offered: %d\n",r_u->offered));
2055
2056                 if (r_u->offered<bufsize_required)
2057                 {       
2058                         /* 
2059                          * so the buffer is too small to handle datas
2060                          * reply the minimum size required in the status
2061                          * make the buffer equal 0
2062                          * and reply no printers in buffer
2063                          */
2064                         r_u->status=ERROR_INSUFFICIENT_BUFFER;
2065                         r_u->offered=0;
2066                         /*r_u->returned=0;*/
2067                         
2068                         DEBUG(4,("spoolss_io_r_enumprinters, buffer too small\n"));
2069
2070                         prs_uint32("size of buffer", ps, depth, &(r_u->offered));
2071                         prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
2072                         prs_uint32("count", ps, depth, &(r_u->returned));
2073                         prs_uint32("status", ps, depth, &(r_u->status));
2074                         return False;
2075                 }       
2076                 
2077                 mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
2078                 
2079                 DEBUG(4,("spoolss_io_r_enumprinters, buffer large enough\n"));
2080         }
2081         
2082         prs_uint32("size of buffer", ps, depth, &(r_u->offered));
2083
2084         /* have to skip to end of buffer when reading, and have to record
2085          * size of buffer when writing.  *shudder*.
2086          */
2087
2088         beginning = ps->offset;
2089         start_offset = ps->offset;
2090         end_offset = start_offset + r_u->offered;
2091                 
2092         if (ps->io)
2093         {
2094                 /* reading */
2095                 ps->offset = beginning + r_u->offered;
2096
2097                 prs_align(ps);
2098                 prs_uint32("buffer size", ps, depth, &(bufsize_required));
2099                 prs_uint32("count", ps, depth, &(r_u->returned));
2100
2101                 ps->offset = beginning;
2102         }
2103         
2104         for(i=0;i<r_u->returned;i++)
2105         {
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 = 0;
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         if (!ps->io)
2554         {
2555                 /* writing */
2556                 switch (r_u->level)
2557                 {
2558                         case 1:
2559                         {
2560                                 for (i=0; i<r_u->numofjobs; i++)
2561                                 {
2562                                         JOB_INFO_1 *info;
2563                                         info=r_u->job.job_info_1[i];
2564                                         bufsize_required += spoolss_size_job_info_1(&(info[i]));
2565                                 }
2566                                 break;
2567                         }
2568                         case 2:
2569                         {
2570                                 for (i=0; i<r_u->numofjobs; i++)
2571                                 {
2572                                         JOB_INFO_2 *info;
2573                                         info=r_u->job.job_info_2[i];
2574                                 
2575                                         bufsize_required += spoolss_size_job_info_2(&(info[i]));
2576                                 }
2577                                 break;
2578                         }       
2579                 }
2580
2581                 DEBUG(4,("spoolss_io_r_enumjobs, size needed: %d\n",bufsize_required));
2582                 DEBUG(4,("spoolss_io_r_enumjobs, size offered: %d\n",r_u->offered));
2583
2584                 /* check if the buffer is big enough for the datas */
2585                 if (r_u->offered<bufsize_required)
2586                 {       
2587                         /* it's too small */
2588                         r_u->status = ERROR_INSUFFICIENT_BUFFER; /* say so */
2589                         r_u->offered = bufsize_required;
2590                         useless_ptr = 0;
2591                         
2592                         DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n"));
2593
2594                 }
2595                 else
2596                 {
2597                         useless_ptr = 1;
2598                 }
2599                 mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
2600         }
2601
2602         prs_uint32("pointer", ps, depth, &useless_ptr);
2603         prs_uint32("size of buffer", ps, depth, &(r_u->offered));
2604
2605         if (useless_ptr != 0)
2606         {
2607                 beginning=ps->offset;
2608                 start_offset=ps->offset;
2609                 end_offset=start_offset+r_u->offered;
2610                 
2611                 tmp_ct = 0;
2612
2613                 if (ps->io)
2614                 {
2615                         /* reading */
2616                         ps->offset = beginning + r_u->offered;
2617
2618                         prs_align(ps);
2619                         prs_uint32("buffer size", ps, depth, &(bufsize_required));
2620                         prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs));
2621
2622                         ps->offset = beginning;
2623                 }
2624                 
2625                 switch (r_u->level)
2626                 {
2627                         case 1:
2628                         {
2629                                 JOB_INFO_1 *info;
2630                                 for (i=0; i<r_u->numofjobs; i++)
2631                                 {
2632                                         if (ps->io)
2633                                         {
2634                                                 /* reading */
2635                                                 r_u->job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->job.job_info_1, NULL);
2636                                         }
2637                                         info = r_u->job.job_info_1[i];
2638                                         smb_io_job_info_1(desc, 
2639                                                           info, 
2640                                                           ps, 
2641                                                           depth, 
2642                                                           &start_offset, 
2643                                                           &end_offset);
2644                                 }
2645                                 break;
2646                         }
2647                         case 2:
2648                         {
2649                                 JOB_INFO_2 *info;
2650                                 for (i=0; i<r_u->numofjobs; i++)
2651                                 {
2652                                         if (ps->io)
2653                                         {
2654                                                 /* reading */
2655                                                 r_u->job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->job.job_info_2, NULL);
2656                                         }
2657                                         info = r_u->job.job_info_2[i];
2658                                         smb_io_job_info_2(desc, 
2659                                                           info, 
2660                                                           ps, 
2661                                                           depth, 
2662                                                           &start_offset, 
2663                                                           &end_offset);
2664                                 }
2665                                 break;
2666                         }
2667                 
2668                 }               
2669                 ps->offset=beginning+r_u->offered;
2670                 prs_align(ps);
2671                 
2672                 /*
2673                  * if the buffer was too small, send the minimum required size
2674                  * if it was too large, send the real needed size
2675                  */
2676                         
2677                 prs_uint32("buffer size", ps, depth, &(bufsize_required));
2678         }
2679
2680         prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs));  
2681         prs_uint32("status", ps, depth, &(r_u->status));
2682
2683         if (!ps->io)
2684         {
2685                 /* writing */
2686                 free_r_enumjobs(r_u);
2687         }
2688
2689         return True;
2690 }
2691
2692 /*******************************************************************
2693 ********************************************************************/  
2694 BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const PRINTER_HND *hnd,
2695                                 uint32 firstjob,
2696                                 uint32 numofjobs,
2697                                 uint32 level,
2698                                 uint32 buf_size)
2699 {
2700         if (q_u == NULL)
2701         {
2702                 return False;
2703         }
2704         memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
2705         q_u->firstjob = firstjob;
2706         q_u->numofjobs = numofjobs;
2707         q_u->level = level;
2708         
2709         if (!make_spoolss_buffer(&q_u->buffer, buf_size))
2710         {
2711                 return False;
2712         }
2713         q_u->buf_size = buf_size;
2714
2715         return True;
2716 }
2717
2718 /*******************************************************************
2719 ********************************************************************/  
2720 BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth)
2721 {
2722         prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
2723         depth++;
2724
2725         prs_align(ps);
2726
2727         smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
2728         prs_uint32("firstjob", ps, depth, &(q_u->firstjob));
2729         prs_uint32("numofjobs", ps, depth, &(q_u->numofjobs));
2730         prs_uint32("level", ps, depth, &(q_u->level));
2731         
2732         spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
2733
2734         prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
2735
2736         return True;
2737 }
2738
2739 /*******************************************************************
2740 ********************************************************************/  
2741 BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth)
2742 {               
2743         prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob");
2744         depth++;
2745
2746         prs_align(ps);
2747         
2748         prs_uint32("status", ps, depth, &(r_u->status));        
2749
2750         return True;
2751 }
2752
2753 /*******************************************************************
2754 ********************************************************************/  
2755 BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth)
2756 {
2757         prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob");
2758         depth++;
2759
2760         prs_align(ps);
2761
2762         smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
2763         prs_uint32("jobid", ps, depth, &(q_u->jobid));
2764
2765         return True;
2766 }
2767
2768 /*******************************************************************
2769 ********************************************************************/  
2770 BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth)
2771 {               
2772         prs_debug(ps, depth, desc, "spoolss_io_r_setjob");
2773         depth++;
2774
2775         prs_align(ps);
2776         
2777         prs_uint32("status", ps, depth, &(r_u->status));        
2778
2779         return True;
2780 }
2781
2782 /*******************************************************************
2783 ********************************************************************/  
2784 BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth)
2785 {
2786         prs_debug(ps, depth, desc, "spoolss_io_q_setjob");
2787         depth++;
2788
2789         prs_align(ps);
2790
2791         smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
2792         prs_uint32("jobid", ps, depth, &(q_u->jobid));
2793         /* 
2794          * level is usually 0. If (level!=0) then I'm in trouble !
2795          * I will try to generate setjob command with level!=0, one day.
2796          */
2797         prs_uint32("level", ps, depth, &(q_u->level));
2798         prs_uint32("command", ps, depth, &(q_u->command));
2799
2800         return True;
2801 }
2802
2803 /*******************************************************************
2804 ********************************************************************/  
2805 BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
2806 {               
2807         uint32 useless_ptr=0xADDE0FF0;
2808         uint32 start_offset, end_offset, beginning;
2809         uint32 bufsize_required=0;
2810         int i;
2811         
2812         prs_debug(ps, depth, desc, "spoolss_io_r_enumdrivers");
2813         depth++;
2814
2815         prs_align(ps);  
2816         prs_uint32("pointer", ps, depth, &useless_ptr);
2817
2818         DEBUG(7,("Level [%d], number [%d]\n", r_u->level, r_u->numofdrivers));
2819         switch (r_u->level)
2820         {
2821                 case 1:
2822                 {
2823                         DRIVER_INFO_1 *driver_info_1;
2824                         driver_info_1=r_u->driver.driver_info_1;
2825                         
2826                         for (i=0; i<r_u->numofdrivers; i++)
2827                         {
2828                                 bufsize_required += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
2829                         }
2830                         break;
2831                 }
2832                 case 2:
2833                 {
2834                         DRIVER_INFO_2 *driver_info_2;
2835                         driver_info_2=r_u->driver.driver_info_2;
2836                         
2837                         for (i=0; i<r_u->numofdrivers; i++)
2838                         {
2839                                 bufsize_required += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
2840                         }
2841                         break;
2842                 }
2843                 case 3:
2844                 {
2845                         DRIVER_INFO_3 *driver_info_3;
2846                         driver_info_3=r_u->driver.driver_info_3;
2847                         
2848                         for (i=0; i<r_u->numofdrivers; i++)
2849                         {
2850                                 bufsize_required += spoolss_size_printer_driver_info_3(&(driver_info_3[i]));
2851                         }
2852                         break;
2853                 }
2854         }
2855         
2856         DEBUGADD(7,("size needed: %d\n",bufsize_required));
2857         DEBUGADD(7,("size offered: %d\n",r_u->offered));
2858
2859         /* check if the buffer is big enough for the datas */
2860
2861         if (r_u->offered<bufsize_required)
2862         {       
2863
2864                 /* it's too small */
2865                 r_u->status=ERROR_INSUFFICIENT_BUFFER;  /* say so */
2866                 r_u->offered=0;                         /* don't send back the buffer */        
2867                 DEBUGADD(8,("buffer too small\n"));
2868
2869                 prs_uint32("size of buffer", ps, depth, &(r_u->offered));
2870         }
2871         else
2872         {       
2873                 mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
2874         
2875                 DEBUGADD(8,("buffer large enough\n"));
2876         
2877                 prs_uint32("size of buffer", ps, depth, &(r_u->offered));
2878                 beginning=ps->offset;
2879                 start_offset=ps->offset;
2880                 end_offset=start_offset+r_u->offered;
2881                 
2882                 switch (r_u->level)
2883                 {
2884                         case 1:
2885                         {
2886                                 DRIVER_INFO_1 *info;
2887                                 for (i=0; i<r_u->numofdrivers; i++)
2888                                 {
2889                                         info = &(r_u->driver.driver_info_1[i]);
2890                                         smb_io_printer_driver_info_1(desc, info, ps, depth, &start_offset, &end_offset);
2891                                 }
2892                                 break;
2893                         }               
2894                         case 2:
2895                         {
2896                                 DRIVER_INFO_2 *info;
2897                                 for (i=0; i<r_u->numofdrivers; i++)
2898                                 {
2899                                         info = &(r_u->driver.driver_info_2[i]);
2900                                         smb_io_printer_driver_info_2(desc, info, ps, depth, &start_offset, &end_offset);
2901                                 }
2902                                 break;
2903                         }               
2904                         case 3:
2905                         {
2906                                 DRIVER_INFO_3 *info;
2907                                 for (i=0; i<r_u->numofdrivers; i++)
2908                                 {
2909                                         info = &(r_u->driver.driver_info_3[i]);
2910                                         smb_io_printer_driver_info_3(desc, info, ps, depth, &start_offset, &end_offset);
2911                                 }
2912                                 break;
2913                         }               
2914                 }               
2915                 ps->offset=beginning+r_u->offered;
2916                 prs_align(ps);
2917         }
2918         
2919         /*
2920          * if the buffer was too small, send the minimum required size
2921          * if it was too large, send the real needed size
2922          */
2923                 
2924         prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
2925         prs_uint32("numofdrivers", ps, depth, &(r_u->numofdrivers));    
2926         prs_uint32("status", ps, depth, &(r_u->status));
2927
2928         return True;
2929 }
2930
2931 /*******************************************************************
2932 ********************************************************************/  
2933 BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
2934 {
2935
2936         uint32 useless_ptr=0xADDE0FF0;
2937         prs_debug(ps, depth, desc, "");
2938         depth++;
2939
2940         prs_align(ps);
2941         prs_uint32("pointer", ps, depth, &useless_ptr);
2942         smb_io_unistr2("", &(q_u->name),True,ps,depth); 
2943         prs_align(ps);
2944         prs_uint32("pointer", ps, depth, &useless_ptr);
2945         smb_io_unistr2("", &(q_u->environment),True,ps,depth);
2946         prs_align(ps);
2947         prs_uint32("level", ps, depth, &(q_u->level));
2948         spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
2949         prs_align(ps);
2950         prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
2951
2952         return True;
2953 }
2954
2955 /*******************************************************************
2956 ********************************************************************/  
2957 BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
2958 {               
2959         uint32 useless_ptr=0xADDE0FF0;
2960         uint32 start_offset, end_offset, beginning;
2961         uint32 bufsize_required=0;
2962         int i;
2963         
2964         prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
2965         depth++;
2966
2967         prs_align(ps);  
2968         prs_uint32("pointer", ps, depth, &useless_ptr);
2969         switch (r_u->level)
2970         {
2971                 case 1:
2972                 {
2973                         FORM_1 *forms_1;
2974                         forms_1=r_u->forms_1;
2975                         
2976                         for (i=0; i<r_u->numofforms; i++)
2977                         {
2978                                 bufsize_required += spoolss_size_form_1(&(forms_1[i]));
2979                         }
2980                         break;
2981                 }
2982         }
2983         
2984         DEBUG(4,("spoolss_io_r_enumforms, size needed: %d\n",bufsize_required));
2985         DEBUG(4,("spoolss_io_r_enumforms, size offered: %d\n",r_u->offered));
2986
2987         /* check if the buffer is big enough for the datas */
2988
2989         if (r_u->offered<bufsize_required)
2990         {       
2991
2992                 /* it's too small */
2993                 r_u->status=ERROR_INSUFFICIENT_BUFFER;  /* say so */
2994                 r_u->offered=0;                         /* don't send back the buffer */
2995                 
2996                 DEBUG(4,("spoolss_io_r_enumforms, buffer too small\n"));
2997
2998                 prs_uint32("size of buffer", ps, depth, &(r_u->offered));
2999         }
3000         else
3001         {       
3002                 mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
3003         
3004                 DEBUG(4,("spoolss_io_r_enumforms, buffer large enough\n"));
3005         
3006                 prs_uint32("size of buffer", ps, depth, &(r_u->offered));
3007                 
3008                 if (r_u->offered!=0)
3009                 {
3010                         beginning=ps->offset;
3011                         start_offset=ps->offset;
3012                         end_offset=start_offset+r_u->offered;
3013                 
3014                         switch (r_u->level)
3015                         {
3016                                 case 1:
3017                                 {
3018                                         FORM_1 *info;
3019                                         for (i=0; i<r_u->numofforms; i++)
3020                                         {
3021                                                 info = &(r_u->forms_1[i]);
3022                                                 smb_io_form_1(desc, info, ps, depth, &start_offset, &end_offset);
3023                                         }
3024                                         break;
3025                                 }               
3026                         }               
3027                         ps->offset=beginning+r_u->offered;
3028                         prs_align(ps);
3029                 }
3030         }
3031         
3032         /*
3033          * if the buffer was too small, send the minimum required size
3034          * if it was too large, send the real needed size
3035          */
3036                 
3037         prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
3038         prs_uint32("numofforms", ps, depth, &(r_u->numofforms));        
3039         prs_uint32("status", ps, depth, &(r_u->status));
3040
3041         return True;
3042 }
3043
3044 /*******************************************************************
3045 ********************************************************************/  
3046 BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
3047 {
3048
3049         prs_debug(ps, depth, desc, "");
3050         depth++;
3051
3052         prs_align(ps);
3053         smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
3054         prs_uint32("level", ps, depth, &(q_u->level));
3055         spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
3056         prs_align(ps);
3057         prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
3058
3059         return True;
3060 }
3061
3062 /*******************************************************************
3063 ********************************************************************/  
3064 BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
3065 {               
3066         uint32 useless_ptr=0xADDE0FF0;
3067         uint32 start_offset, end_offset, beginning;
3068         uint32 bufsize_required=0;
3069         int i;
3070         
3071         prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
3072         depth++;
3073
3074         prs_align(ps);  
3075         prs_uint32("pointer", ps, depth, &useless_ptr);
3076         switch (r_u->level)
3077         {
3078                 case 2:
3079                 {
3080                         PORT_INFO_2 *port_2;
3081                         port_2=r_u->port.port_info_2;
3082                         
3083                         for (i=0; i<r_u->numofports; i++)
3084                         {
3085                                 bufsize_required += spoolss_size_port_info_2(&(port_2[i]));
3086                         }
3087                         break;
3088                 }
3089         }
3090         
3091         DEBUG(4,("size needed: %d\n",bufsize_required));
3092         DEBUG(4,("size offered: %d\n",r_u->offered));
3093
3094         /* check if the buffer is big enough for the datas */
3095         if (r_u->offered<bufsize_required)
3096         {       
3097
3098                 /* it's too small */
3099                 r_u->status=ERROR_INSUFFICIENT_BUFFER;  /* say so */
3100                 r_u->offered=0;                         /* don't send back the buffer */
3101                 
3102                 DEBUG(4,("buffer too small\n"));
3103
3104                 prs_uint32("size of buffer", ps, depth, &(r_u->offered));
3105         }
3106         else
3107         {       
3108                 mem_grow_data(&(ps->data), ps->io, r_u->offered, 0);
3109         
3110                 DEBUG(4,("buffer large enough\n"));
3111         
3112                 prs_uint32("size of buffer", ps, depth, &(r_u->offered));
3113                 beginning=ps->offset;
3114                 start_offset=ps->offset;
3115                 end_offset=start_offset+r_u->offered;
3116                 
3117                 switch (r_u->level)
3118                 {
3119                         case 2:
3120                         {
3121                                 PORT_INFO_2 *info;
3122                                 for (i=0; i<r_u->numofports; i++)
3123                                 {
3124                                         info = &(r_u->port.port_info_2[i]);
3125                                         smb_io_port_2(desc, info, ps, depth, &start_offset, &end_offset);
3126                                 }
3127                                 break;
3128                         }               
3129                 }               
3130                 ps->offset=beginning+r_u->offered;
3131                 prs_align(ps);
3132         }
3133         
3134         /*
3135          * if the buffer was too small, send the minimum required size
3136          * if it was too large, send the real needed size
3137          */
3138                 
3139         prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
3140         prs_uint32("numofports", ps, depth, &(r_u->numofports));        
3141         prs_uint32("status", ps, depth, &(r_u->status));
3142
3143         return True;
3144 }
3145
3146 /*******************************************************************
3147 ********************************************************************/  
3148 BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
3149 {
3150         uint32 useless;
3151         prs_debug(ps, depth, desc, "");
3152         depth++;
3153
3154         prs_align(ps);
3155         prs_uint32("useless", ps, depth, &useless);
3156         smb_io_unistr2("", &(q_u->name),True,ps,depth);
3157         prs_align(ps);
3158         prs_uint32("level", ps, depth, &(q_u->level));
3159         spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
3160         prs_align(ps);
3161         prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
3162
3163         return True;
3164 }
3165
3166
3167 /*******************************************************************
3168 ********************************************************************/  
3169 BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth)
3170 {       
3171         SPOOL_PRINTER_INFO_LEVEL_2 *il;
3172         
3173         prs_debug(ps, depth, desc, "");
3174         depth++;
3175
3176         /* reading */
3177         if (ps->io)
3178         {
3179                 il=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
3180                 ZERO_STRUCTP(il);
3181                 *q_u=il;
3182                 DEBUG(7,("lecture: memoire ok\n"));
3183         }
3184         else
3185         {