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