s3-spoolss: remove old spoolss_GetPrinterDriver2.
[Samba.git] / source3 / rpc_parse / parse_spoolss.c
blobd77199d62481d1271dd8af38ab32cc88337fb776
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Gerald Carter 2000-2002,
8 * Copyright (C) Tim Potter 2001-2002.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
26 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
30 /*******************************************************************
31 This should be moved in a more generic lib.
32 ********************************************************************/
34 bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime)
36 if(!prs_uint16("year", ps, depth, &systime->year))
37 return False;
38 if(!prs_uint16("month", ps, depth, &systime->month))
39 return False;
40 if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek))
41 return False;
42 if(!prs_uint16("day", ps, depth, &systime->day))
43 return False;
44 if(!prs_uint16("hour", ps, depth, &systime->hour))
45 return False;
46 if(!prs_uint16("minute", ps, depth, &systime->minute))
47 return False;
48 if(!prs_uint16("second", ps, depth, &systime->second))
49 return False;
50 if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds))
51 return False;
53 return True;
56 /*******************************************************************
57 ********************************************************************/
59 bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime)
61 systime->year=unixtime->tm_year+1900;
62 systime->month=unixtime->tm_mon+1;
63 systime->dayofweek=unixtime->tm_wday;
64 systime->day=unixtime->tm_mday;
65 systime->hour=unixtime->tm_hour;
66 systime->minute=unixtime->tm_min;
67 systime->second=unixtime->tm_sec;
68 systime->milliseconds=0;
70 return True;
73 /*******************************************************************
74 * read or write a DEVICEMODE struct.
75 * on reading allocate memory for the private member
76 ********************************************************************/
78 #define DM_NUM_OPTIONAL_FIELDS 8
80 bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
82 int available_space; /* size of the device mode left to parse */
83 /* only important on unmarshalling */
84 int i = 0;
85 uint16 *unistr_buffer;
86 int j;
88 struct optional_fields {
89 fstring name;
90 uint32* field;
91 } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
92 { "icmmethod", NULL },
93 { "icmintent", NULL },
94 { "mediatype", NULL },
95 { "dithertype", NULL },
96 { "reserved1", NULL },
97 { "reserved2", NULL },
98 { "panningwidth", NULL },
99 { "panningheight", NULL }
102 /* assign at run time to keep non-gcc compilers happy */
104 opt_fields[0].field = &devmode->icmmethod;
105 opt_fields[1].field = &devmode->icmintent;
106 opt_fields[2].field = &devmode->mediatype;
107 opt_fields[3].field = &devmode->dithertype;
108 opt_fields[4].field = &devmode->reserved1;
109 opt_fields[5].field = &devmode->reserved2;
110 opt_fields[6].field = &devmode->panningwidth;
111 opt_fields[7].field = &devmode->panningheight;
114 prs_debug(ps, depth, desc, "spoolss_io_devmode");
115 depth++;
117 if (UNMARSHALLING(ps)) {
118 devmode->devicename.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
119 if (devmode->devicename.buffer == NULL)
120 return False;
121 unistr_buffer = devmode->devicename.buffer;
123 else {
124 /* devicename is a static sized string but the buffer we set is not */
125 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
126 memset( unistr_buffer, 0x0, MAXDEVICENAME );
127 for ( j=0; devmode->devicename.buffer[j]; j++ )
128 unistr_buffer[j] = devmode->devicename.buffer[j];
131 if (!prs_uint16uni(True,"devicename", ps, depth, unistr_buffer, MAXDEVICENAME))
132 return False;
134 if (!prs_uint16("specversion", ps, depth, &devmode->specversion))
135 return False;
137 if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion))
138 return False;
139 if (!prs_uint16("size", ps, depth, &devmode->size))
140 return False;
141 if (!prs_uint16("driverextra", ps, depth, &devmode->driverextra))
142 return False;
143 if (!prs_uint32("fields", ps, depth, &devmode->fields))
144 return False;
145 if (!prs_uint16("orientation", ps, depth, &devmode->orientation))
146 return False;
147 if (!prs_uint16("papersize", ps, depth, &devmode->papersize))
148 return False;
149 if (!prs_uint16("paperlength", ps, depth, &devmode->paperlength))
150 return False;
151 if (!prs_uint16("paperwidth", ps, depth, &devmode->paperwidth))
152 return False;
153 if (!prs_uint16("scale", ps, depth, &devmode->scale))
154 return False;
155 if (!prs_uint16("copies", ps, depth, &devmode->copies))
156 return False;
157 if (!prs_uint16("defaultsource", ps, depth, &devmode->defaultsource))
158 return False;
159 if (!prs_uint16("printquality", ps, depth, &devmode->printquality))
160 return False;
161 if (!prs_uint16("color", ps, depth, &devmode->color))
162 return False;
163 if (!prs_uint16("duplex", ps, depth, &devmode->duplex))
164 return False;
165 if (!prs_uint16("yresolution", ps, depth, &devmode->yresolution))
166 return False;
167 if (!prs_uint16("ttoption", ps, depth, &devmode->ttoption))
168 return False;
169 if (!prs_uint16("collate", ps, depth, &devmode->collate))
170 return False;
172 if (UNMARSHALLING(ps)) {
173 devmode->formname.buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
174 if (devmode->formname.buffer == NULL)
175 return False;
176 unistr_buffer = devmode->formname.buffer;
178 else {
179 /* devicename is a static sized string but the buffer we set is not */
180 unistr_buffer = PRS_ALLOC_MEM(ps, uint16, MAXDEVICENAME);
181 memset( unistr_buffer, 0x0, MAXDEVICENAME );
182 for ( j=0; devmode->formname.buffer[j]; j++ )
183 unistr_buffer[j] = devmode->formname.buffer[j];
186 if (!prs_uint16uni(True, "formname", ps, depth, unistr_buffer, MAXDEVICENAME))
187 return False;
188 if (!prs_uint16("logpixels", ps, depth, &devmode->logpixels))
189 return False;
190 if (!prs_uint32("bitsperpel", ps, depth, &devmode->bitsperpel))
191 return False;
192 if (!prs_uint32("pelswidth", ps, depth, &devmode->pelswidth))
193 return False;
194 if (!prs_uint32("pelsheight", ps, depth, &devmode->pelsheight))
195 return False;
196 if (!prs_uint32("displayflags", ps, depth, &devmode->displayflags))
197 return False;
198 if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
199 return False;
201 * every device mode I've ever seen on the wire at least has up
202 * to the displayfrequency field. --jerry (05-09-2002)
205 /* add uint32's + uint16's + two UNICODE strings */
207 available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
209 /* Sanity check - we only have uint32's left tp parse */
211 if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
212 DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
213 available_space, devmode->size));
214 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
215 return False;
219 * Conditional parsing. Assume that the DeviceMode has been
220 * zero'd by the caller.
223 while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
225 DEBUG(11, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
226 if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
227 return False;
228 available_space -= sizeof(uint32);
229 i++;
232 /* Sanity Check - we should no available space at this point unless
233 MS changes the device mode structure */
235 if (available_space) {
236 DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
237 DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
238 available_space, devmode->size));
239 DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
240 return False;
244 if (devmode->driverextra!=0) {
245 if (UNMARSHALLING(ps)) {
246 devmode->dev_private=PRS_ALLOC_MEM(ps, uint8, devmode->driverextra);
247 if(devmode->dev_private == NULL)
248 return False;
249 DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for dev_private\n",devmode->driverextra));
252 DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of dev_private\n",devmode->driverextra));
253 if (!prs_uint8s(False, "dev_private", ps, depth,
254 devmode->dev_private, devmode->driverextra))
255 return False;
258 return True;
261 /*******************************************************************
262 * make a structure.
263 ********************************************************************/
265 bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
266 const POLICY_HND *handle,
267 const char *valuename, uint32 size)
269 if (q_u == NULL) return False;
271 DEBUG(5,("make_spoolss_q_getprinterdata\n"));
273 q_u->handle = *handle;
274 init_unistr2(&q_u->valuename, valuename, UNI_STR_TERMINATE);
275 q_u->size = size;
277 return True;
280 /*******************************************************************
281 * read a structure.
282 * called from spoolss_q_getprinterdata (srv_spoolss.c)
283 ********************************************************************/
285 bool spoolss_io_q_getprinterdata(const char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth)
287 if (q_u == NULL)
288 return False;
290 prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
291 depth++;
293 if (!prs_align(ps))
294 return False;
295 if (!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
296 return False;
297 if (!prs_align(ps))
298 return False;
299 if (!smb_io_unistr2("valuename", &q_u->valuename,True,ps,depth))
300 return False;
301 if (!prs_align(ps))
302 return False;
303 if (!prs_uint32("size", ps, depth, &q_u->size))
304 return False;
306 return True;
309 /*******************************************************************
310 * write a structure.
311 * called from spoolss_r_getprinterdata (srv_spoolss.c)
312 ********************************************************************/
314 bool spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
316 if (r_u == NULL)
317 return False;
319 prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
320 depth++;
322 if (!prs_align(ps))
323 return False;
324 if (!prs_uint32("type", ps, depth, &r_u->type))
325 return False;
326 if (!prs_uint32("size", ps, depth, &r_u->size))
327 return False;
329 if (UNMARSHALLING(ps) && r_u->size) {
330 r_u->data = PRS_ALLOC_MEM(ps, unsigned char, r_u->size);
331 if(!r_u->data)
332 return False;
335 if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size ))
336 return False;
338 if (!prs_align(ps))
339 return False;
341 if (!prs_uint32("needed", ps, depth, &r_u->needed))
342 return False;
343 if (!prs_werror("status", ps, depth, &r_u->status))
344 return False;
346 return True;
349 /*******************************************************************
350 * return the length of a uint16 (obvious, but the code is clean)
351 ********************************************************************/
353 static uint32 size_of_uint16(uint16 *value)
355 return (sizeof(*value));
358 /*******************************************************************
359 * return the length of a uint32 (obvious, but the code is clean)
360 ********************************************************************/
362 static uint32 size_of_uint32(uint32 *value)
364 return (sizeof(*value));
367 /*******************************************************************
368 * return the length of a NTTIME (obvious, but the code is clean)
369 ********************************************************************/
371 static uint32 size_of_nttime(NTTIME *value)
373 return (sizeof(*value));
376 /*******************************************************************
377 * return the length of a uint32 (obvious, but the code is clean)
378 ********************************************************************/
380 static uint32 size_of_device_mode(DEVICEMODE *devmode)
382 if (devmode==NULL)
383 return (4);
384 else
385 return (4+devmode->size+devmode->driverextra);
388 /*******************************************************************
389 Parse a DEVMODE structure and its relative pointer.
390 ********************************************************************/
392 static bool smb_io_reldevmode(const char *desc, RPC_BUFFER *buffer, int depth, DEVICEMODE **devmode)
394 prs_struct *ps=&buffer->prs;
396 prs_debug(ps, depth, desc, "smb_io_reldevmode");
397 depth++;
399 if (MARSHALLING(ps)) {
400 uint32 struct_offset = prs_offset(ps);
401 uint32 relative_offset;
403 if (*devmode == NULL) {
404 relative_offset=0;
405 if (!prs_uint32("offset", ps, depth, &relative_offset))
406 return False;
407 DEBUG(8, ("boing, the devmode was NULL\n"));
409 return True;
412 buffer->string_at_end -= ((*devmode)->size + (*devmode)->driverextra);
414 /* mz: we have to align the device mode for VISTA */
415 if (buffer->string_at_end % 4) {
416 buffer->string_at_end += 4 - (buffer->string_at_end % 4);
419 if(!prs_set_offset(ps, buffer->string_at_end))
420 return False;
422 /* write the DEVMODE */
423 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
424 return False;
426 if(!prs_set_offset(ps, struct_offset))
427 return False;
429 relative_offset=buffer->string_at_end - buffer->struct_start;
430 /* write its offset */
431 if (!prs_uint32("offset", ps, depth, &relative_offset))
432 return False;
434 else {
435 uint32 old_offset;
437 /* read the offset */
438 if (!prs_uint32("offset", ps, depth, &buffer->string_at_end))
439 return False;
440 if (buffer->string_at_end == 0) {
441 *devmode = NULL;
442 return True;
445 old_offset = prs_offset(ps);
446 if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start))
447 return False;
449 /* read the string */
450 if((*devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1)) == NULL)
451 return False;
452 if (!spoolss_io_devmode(desc, ps, depth, *devmode))
453 return False;
455 if(!prs_set_offset(ps, old_offset))
456 return False;
458 return True;
461 /*******************************************************************
462 Parse a PRINTER_INFO_0 structure.
463 ********************************************************************/
465 bool smb_io_printer_info_0(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
467 prs_struct *ps=&buffer->prs;
469 prs_debug(ps, depth, desc, "smb_io_printer_info_0");
470 depth++;
472 buffer->struct_start=prs_offset(ps);
474 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
475 return False;
476 if (!smb_io_relstr("servername", buffer, depth, &info->servername))
477 return False;
479 if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
480 return False;
481 if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs))
482 return False;
483 if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes))
484 return False;
486 if(!prs_uint16("year", ps, depth, &info->year))
487 return False;
488 if(!prs_uint16("month", ps, depth, &info->month))
489 return False;
490 if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek))
491 return False;
492 if(!prs_uint16("day", ps, depth, &info->day))
493 return False;
494 if(!prs_uint16("hour", ps, depth, &info->hour))
495 return False;
496 if(!prs_uint16("minute", ps, depth, &info->minute))
497 return False;
498 if(!prs_uint16("second", ps, depth, &info->second))
499 return False;
500 if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds))
501 return False;
503 if(!prs_uint32("global_counter", ps, depth, &info->global_counter))
504 return False;
505 if(!prs_uint32("total_pages", ps, depth, &info->total_pages))
506 return False;
508 if(!prs_uint16("major_version", ps, depth, &info->major_version))
509 return False;
510 if(!prs_uint16("build_version", ps, depth, &info->build_version))
511 return False;
512 if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
513 return False;
514 if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
515 return False;
516 if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
517 return False;
518 if(!prs_uint32("session_counter", ps, depth, &info->session_counter))
519 return False;
520 if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
521 return False;
522 if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors))
523 return False;
524 if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
525 return False;
526 if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
527 return False;
528 if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
529 return False;
530 if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
531 return False;
532 if(!prs_uint32("change_id", ps, depth, &info->change_id))
533 return False;
534 if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
535 return False;
536 if(!prs_uint32("status" , ps, depth, &info->status))
537 return False;
538 if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
539 return False;
540 if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter))
541 return False;
542 if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
543 return False;
544 if(!prs_uint16("unknown23", ps, depth, &info->unknown23))
545 return False;
546 if(!prs_uint16("unknown24", ps, depth, &info->unknown24))
547 return False;
548 if(!prs_uint16("unknown25", ps, depth, &info->unknown25))
549 return False;
550 if(!prs_uint16("unknown26", ps, depth, &info->unknown26))
551 return False;
552 if(!prs_uint16("unknown27", ps, depth, &info->unknown27))
553 return False;
554 if(!prs_uint16("unknown28", ps, depth, &info->unknown28))
555 return False;
556 if(!prs_uint16("unknown29", ps, depth, &info->unknown29))
557 return False;
559 return True;
562 /*******************************************************************
563 Parse a PRINTER_INFO_1 structure.
564 ********************************************************************/
566 bool smb_io_printer_info_1(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
568 prs_struct *ps=&buffer->prs;
570 prs_debug(ps, depth, desc, "smb_io_printer_info_1");
571 depth++;
573 buffer->struct_start=prs_offset(ps);
575 if (!prs_uint32("flags", ps, depth, &info->flags))
576 return False;
577 if (!smb_io_relstr("description", buffer, depth, &info->description))
578 return False;
579 if (!smb_io_relstr("name", buffer, depth, &info->name))
580 return False;
581 if (!smb_io_relstr("comment", buffer, depth, &info->comment))
582 return False;
584 return True;
587 /*******************************************************************
588 Parse a PRINTER_INFO_2 structure.
589 ********************************************************************/
591 bool smb_io_printer_info_2(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
593 prs_struct *ps=&buffer->prs;
594 uint32 dm_offset, sd_offset, current_offset;
595 uint32 dummy_value = 0, has_secdesc = 0;
597 prs_debug(ps, depth, desc, "smb_io_printer_info_2");
598 depth++;
600 buffer->struct_start=prs_offset(ps);
602 if (!smb_io_relstr("servername", buffer, depth, &info->servername))
603 return False;
604 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
605 return False;
606 if (!smb_io_relstr("sharename", buffer, depth, &info->sharename))
607 return False;
608 if (!smb_io_relstr("portname", buffer, depth, &info->portname))
609 return False;
610 if (!smb_io_relstr("drivername", buffer, depth, &info->drivername))
611 return False;
612 if (!smb_io_relstr("comment", buffer, depth, &info->comment))
613 return False;
614 if (!smb_io_relstr("location", buffer, depth, &info->location))
615 return False;
617 /* save current offset and wind forwared by a uint32 */
618 dm_offset = prs_offset(ps);
619 if (!prs_uint32("devmode", ps, depth, &dummy_value))
620 return False;
622 if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
623 return False;
624 if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
625 return False;
626 if (!smb_io_relstr("datatype", buffer, depth, &info->datatype))
627 return False;
628 if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
629 return False;
631 /* save current offset for the sec_desc */
632 sd_offset = prs_offset(ps);
633 if (!prs_uint32("sec_desc", ps, depth, &has_secdesc))
634 return False;
637 /* save current location so we can pick back up here */
638 current_offset = prs_offset(ps);
640 /* parse the devmode */
641 if (!prs_set_offset(ps, dm_offset))
642 return False;
643 if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
644 return False;
646 /* parse the sec_desc */
647 if (info->secdesc) {
648 if (!prs_set_offset(ps, sd_offset))
649 return False;
650 if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
651 return False;
654 /* pick up where we left off */
655 if (!prs_set_offset(ps, current_offset))
656 return False;
658 if (!prs_uint32("attributes", ps, depth, &info->attributes))
659 return False;
660 if (!prs_uint32("priority", ps, depth, &info->priority))
661 return False;
662 if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
663 return False;
664 if (!prs_uint32("starttime", ps, depth, &info->starttime))
665 return False;
666 if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
667 return False;
668 if (!prs_uint32("status", ps, depth, &info->status))
669 return False;
670 if (!prs_uint32("jobs", ps, depth, &info->cjobs))
671 return False;
672 if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
673 return False;
675 return True;
678 /*******************************************************************
679 Parse a PRINTER_INFO_3 structure.
680 ********************************************************************/
682 bool smb_io_printer_info_3(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_3 *info, int depth)
684 uint32 offset = 0;
685 prs_struct *ps=&buffer->prs;
687 prs_debug(ps, depth, desc, "smb_io_printer_info_3");
688 depth++;
690 buffer->struct_start=prs_offset(ps);
692 if (MARSHALLING(ps)) {
693 /* Ensure the SD is 8 byte aligned in the buffer. */
694 uint32 start = prs_offset(ps); /* Remember the start position. */
695 uint32 off_val = 0;
697 /* Write a dummy value. */
698 if (!prs_uint32("offset", ps, depth, &off_val))
699 return False;
701 /* 8 byte align. */
702 if (!prs_align_uint64(ps))
703 return False;
705 /* Remember where we must seek back to write the SD. */
706 offset = prs_offset(ps);
708 /* Calculate the real offset for the SD. */
710 off_val = offset - start;
712 /* Seek back to where we store the SD offset & store. */
713 prs_set_offset(ps, start);
714 if (!prs_uint32("offset", ps, depth, &off_val))
715 return False;
717 /* Return to after the 8 byte align. */
718 prs_set_offset(ps, offset);
720 } else {
721 if (!prs_uint32("offset", ps, depth, &offset))
722 return False;
723 /* Seek within the buffer. */
724 if (!prs_set_offset(ps, offset))
725 return False;
727 if (!sec_io_desc("sec_desc", &info->secdesc, ps, depth))
728 return False;
730 return True;
733 /*******************************************************************
734 Parse a PRINTER_INFO_4 structure.
735 ********************************************************************/
737 bool smb_io_printer_info_4(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_4 *info, int depth)
739 prs_struct *ps=&buffer->prs;
741 prs_debug(ps, depth, desc, "smb_io_printer_info_4");
742 depth++;
744 buffer->struct_start=prs_offset(ps);
746 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
747 return False;
748 if (!smb_io_relstr("servername", buffer, depth, &info->servername))
749 return False;
750 if (!prs_uint32("attributes", ps, depth, &info->attributes))
751 return False;
752 return True;
755 /*******************************************************************
756 Parse a PRINTER_INFO_5 structure.
757 ********************************************************************/
759 bool smb_io_printer_info_5(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_5 *info, int depth)
761 prs_struct *ps=&buffer->prs;
763 prs_debug(ps, depth, desc, "smb_io_printer_info_5");
764 depth++;
766 buffer->struct_start=prs_offset(ps);
768 if (!smb_io_relstr("printername", buffer, depth, &info->printername))
769 return False;
770 if (!smb_io_relstr("portname", buffer, depth, &info->portname))
771 return False;
772 if (!prs_uint32("attributes", ps, depth, &info->attributes))
773 return False;
774 if (!prs_uint32("device_not_selected_timeout", ps, depth, &info->device_not_selected_timeout))
775 return False;
776 if (!prs_uint32("transmission_retry_timeout", ps, depth, &info->transmission_retry_timeout))
777 return False;
778 return True;
781 /*******************************************************************
782 Parse a PRINTER_INFO_6 structure.
783 ********************************************************************/
785 bool smb_io_printer_info_6(const char *desc, RPC_BUFFER *buffer,
786 PRINTER_INFO_6 *info, int depth)
788 prs_struct *ps=&buffer->prs;
790 prs_debug(ps, depth, desc, "smb_io_printer_info_6");
791 depth++;
793 if (!prs_uint32("status", ps, depth, &info->status))
794 return False;
796 return True;
799 /*******************************************************************
800 Parse a PRINTER_INFO_7 structure.
801 ********************************************************************/
803 bool smb_io_printer_info_7(const char *desc, RPC_BUFFER *buffer, PRINTER_INFO_7 *info, int depth)
805 prs_struct *ps=&buffer->prs;
807 prs_debug(ps, depth, desc, "smb_io_printer_info_7");
808 depth++;
810 buffer->struct_start=prs_offset(ps);
812 if (!smb_io_relstr("guid", buffer, depth, &info->guid))
813 return False;
814 if (!prs_uint32("action", ps, depth, &info->action))
815 return False;
816 return True;
819 /*******************************************************************
820 return the size required by a struct in the stream
821 ********************************************************************/
823 uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
825 int size=0;
827 size+=size_of_relative_string( &info->printername );
828 size+=size_of_relative_string( &info->servername );
830 size+=size_of_uint32( &info->cjobs);
831 size+=size_of_uint32( &info->total_jobs);
832 size+=size_of_uint32( &info->total_bytes);
834 size+=size_of_uint16( &info->year);
835 size+=size_of_uint16( &info->month);
836 size+=size_of_uint16( &info->dayofweek);
837 size+=size_of_uint16( &info->day);
838 size+=size_of_uint16( &info->hour);
839 size+=size_of_uint16( &info->minute);
840 size+=size_of_uint16( &info->second);
841 size+=size_of_uint16( &info->milliseconds);
843 size+=size_of_uint32( &info->global_counter);
844 size+=size_of_uint32( &info->total_pages);
846 size+=size_of_uint16( &info->major_version);
847 size+=size_of_uint16( &info->build_version);
849 size+=size_of_uint32( &info->unknown7);
850 size+=size_of_uint32( &info->unknown8);
851 size+=size_of_uint32( &info->unknown9);
852 size+=size_of_uint32( &info->session_counter);
853 size+=size_of_uint32( &info->unknown11);
854 size+=size_of_uint32( &info->printer_errors);
855 size+=size_of_uint32( &info->unknown13);
856 size+=size_of_uint32( &info->unknown14);
857 size+=size_of_uint32( &info->unknown15);
858 size+=size_of_uint32( &info->unknown16);
859 size+=size_of_uint32( &info->change_id);
860 size+=size_of_uint32( &info->unknown18);
861 size+=size_of_uint32( &info->status);
862 size+=size_of_uint32( &info->unknown20);
863 size+=size_of_uint32( &info->c_setprinter);
865 size+=size_of_uint16( &info->unknown22);
866 size+=size_of_uint16( &info->unknown23);
867 size+=size_of_uint16( &info->unknown24);
868 size+=size_of_uint16( &info->unknown25);
869 size+=size_of_uint16( &info->unknown26);
870 size+=size_of_uint16( &info->unknown27);
871 size+=size_of_uint16( &info->unknown28);
872 size+=size_of_uint16( &info->unknown29);
874 return size;
877 /*******************************************************************
878 return the size required by a struct in the stream
879 ********************************************************************/
881 uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
883 int size=0;
885 size+=size_of_uint32( &info->flags );
886 size+=size_of_relative_string( &info->description );
887 size+=size_of_relative_string( &info->name );
888 size+=size_of_relative_string( &info->comment );
890 return size;
893 /*******************************************************************
894 return the size required by a struct in the stream
895 ********************************************************************/
897 uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
899 uint32 size=0;
901 size += 4;
903 size += ndr_size_security_descriptor( info->secdesc, NULL, 0 );
905 size+=size_of_device_mode( info->devmode );
907 size+=size_of_relative_string( &info->servername );
908 size+=size_of_relative_string( &info->printername );
909 size+=size_of_relative_string( &info->sharename );
910 size+=size_of_relative_string( &info->portname );
911 size+=size_of_relative_string( &info->drivername );
912 size+=size_of_relative_string( &info->comment );
913 size+=size_of_relative_string( &info->location );
915 size+=size_of_relative_string( &info->sepfile );
916 size+=size_of_relative_string( &info->printprocessor );
917 size+=size_of_relative_string( &info->datatype );
918 size+=size_of_relative_string( &info->parameters );
920 size+=size_of_uint32( &info->attributes );
921 size+=size_of_uint32( &info->priority );
922 size+=size_of_uint32( &info->defaultpriority );
923 size+=size_of_uint32( &info->starttime );
924 size+=size_of_uint32( &info->untiltime );
925 size+=size_of_uint32( &info->status );
926 size+=size_of_uint32( &info->cjobs );
927 size+=size_of_uint32( &info->averageppm );
930 * add any adjustments for alignment. This is
931 * not optimal since we could be calling this
932 * function from a loop (e.g. enumprinters), but
933 * it is easier to maintain the calculation here and
934 * not place the burden on the caller to remember. --jerry
936 if ((size % 4) != 0)
937 size += 4 - (size % 4);
939 return size;
942 /*******************************************************************
943 return the size required by a struct in the stream
944 ********************************************************************/
946 uint32 spoolss_size_printer_info_4(PRINTER_INFO_4 *info)
948 uint32 size=0;
950 size+=size_of_relative_string( &info->printername );
951 size+=size_of_relative_string( &info->servername );
953 size+=size_of_uint32( &info->attributes );
954 return size;
957 /*******************************************************************
958 return the size required by a struct in the stream
959 ********************************************************************/
961 uint32 spoolss_size_printer_info_5(PRINTER_INFO_5 *info)
963 uint32 size=0;
965 size+=size_of_relative_string( &info->printername );
966 size+=size_of_relative_string( &info->portname );
968 size+=size_of_uint32( &info->attributes );
969 size+=size_of_uint32( &info->device_not_selected_timeout );
970 size+=size_of_uint32( &info->transmission_retry_timeout );
971 return size;
974 /*******************************************************************
975 return the size required by a struct in the stream
976 ********************************************************************/
978 uint32 spoolss_size_printer_info_6(PRINTER_INFO_6 *info)
980 return sizeof(uint32);
983 /*******************************************************************
984 return the size required by a struct in the stream
985 ********************************************************************/
987 uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
989 /* The 8 is for the self relative pointer - 8 byte aligned.. */
990 return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, NULL, 0 );
993 /*******************************************************************
994 return the size required by a struct in the stream
995 ********************************************************************/
997 uint32 spoolss_size_printer_info_7(PRINTER_INFO_7 *info)
999 uint32 size=0;
1001 size+=size_of_relative_string( &info->guid );
1002 size+=size_of_uint32( &info->action );
1003 return size;
1006 /*******************************************************************
1007 return the size required by a string array.
1008 ********************************************************************/
1010 uint32 spoolss_size_string_array(uint16 *string)
1012 uint32 i = 0;
1014 if (string) {
1015 for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++);
1017 i=i+2; /* to count all chars including the leading zero */
1018 i=2*i; /* because we need the value in bytes */
1019 i=i+4; /* the offset pointer size */
1021 return i;
1024 /*******************************************************************
1025 return the size required by a struct in the stream
1026 ********************************************************************/
1027 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
1029 uint32 size = 0;
1031 if (!p)
1032 return 0;
1034 /* uint32(offset) + uint32(length) + length) */
1035 size += (size_of_uint32(&p->value_len)*2) + p->value_len;
1036 size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
1038 size += size_of_uint32(&p->type);
1040 return size;
1043 /*******************************************************************
1044 * init a structure.
1045 ********************************************************************/
1047 bool make_spoolss_q_enumprinters(
1048 SPOOL_Q_ENUMPRINTERS *q_u,
1049 uint32 flags,
1050 char *servername,
1051 uint32 level,
1052 RPC_BUFFER *buffer,
1053 uint32 offered
1056 q_u->flags=flags;
1058 q_u->servername_ptr = (servername != NULL) ? 1 : 0;
1059 init_buf_unistr2(&q_u->servername, &q_u->servername_ptr, servername);
1061 q_u->level=level;
1062 q_u->buffer=buffer;
1063 q_u->offered=offered;
1065 return True;
1068 /*******************************************************************
1069 * read a structure.
1070 * called from spoolss_enumprinters (srv_spoolss.c)
1071 ********************************************************************/
1073 bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
1075 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
1076 depth++;
1078 if (!prs_align(ps))
1079 return False;
1081 if (!prs_uint32("flags", ps, depth, &q_u->flags))
1082 return False;
1083 if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
1084 return False;
1086 if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
1087 return False;
1089 if (!prs_align(ps))
1090 return False;
1091 if (!prs_uint32("level", ps, depth, &q_u->level))
1092 return False;
1094 if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1095 return False;
1097 if (!prs_align(ps))
1098 return False;
1099 if (!prs_uint32("offered", ps, depth, &q_u->offered))
1100 return False;
1102 return True;
1105 /*******************************************************************
1106 Parse a SPOOL_R_ENUMPRINTERS structure.
1107 ********************************************************************/
1109 bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
1111 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinters");
1112 depth++;
1114 if (!prs_align(ps))
1115 return False;
1117 if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1118 return False;
1120 if (!prs_align(ps))
1121 return False;
1123 if (!prs_uint32("needed", ps, depth, &r_u->needed))
1124 return False;
1126 if (!prs_uint32("returned", ps, depth, &r_u->returned))
1127 return False;
1129 if (!prs_werror("status", ps, depth, &r_u->status))
1130 return False;
1132 return True;
1135 /*******************************************************************
1136 * write a structure.
1137 * called from spoolss_r_enum_printers (srv_spoolss.c)
1139 ********************************************************************/
1141 bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
1143 prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
1144 depth++;
1146 if (!prs_align(ps))
1147 return False;
1149 if (!prs_rpcbuffer_p("", ps, depth, &r_u->buffer))
1150 return False;
1152 if (!prs_align(ps))
1153 return False;
1155 if (!prs_uint32("needed", ps, depth, &r_u->needed))
1156 return False;
1158 if (!prs_werror("status", ps, depth, &r_u->status))
1159 return False;
1161 return True;
1164 /*******************************************************************
1165 * read a structure.
1166 * called from spoolss_getprinter (srv_spoolss.c)
1167 ********************************************************************/
1169 bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
1171 prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
1172 depth++;
1174 if (!prs_align(ps))
1175 return False;
1177 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1178 return False;
1179 if (!prs_uint32("level", ps, depth, &q_u->level))
1180 return False;
1182 if (!prs_rpcbuffer_p("", ps, depth, &q_u->buffer))
1183 return False;
1185 if (!prs_align(ps))
1186 return False;
1187 if (!prs_uint32("offered", ps, depth, &q_u->offered))
1188 return False;
1190 return True;
1193 /*******************************************************************
1194 make a BUFFER5 struct from a uint16*
1195 ******************************************************************/
1197 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
1200 buf5->buf_len = len;
1201 if (src) {
1202 if (len) {
1203 if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
1204 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
1205 return False;
1207 } else {
1208 buf5->buffer = NULL;
1210 } else {
1211 buf5->buffer=NULL;
1214 return True;
1217 /*******************************************************************
1218 ********************************************************************/
1220 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
1222 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
1223 depth++;
1225 if(!prs_align(ps))
1226 return False;
1227 if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
1228 return False;
1230 if (UNMARSHALLING(ps) && r_u->valuesize) {
1231 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
1232 if (!r_u->value) {
1233 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
1234 return False;
1238 if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
1239 return False;
1241 if(!prs_align(ps))
1242 return False;
1244 if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
1245 return False;
1247 if(!prs_uint32("type", ps, depth, &r_u->type))
1248 return False;
1250 if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
1251 return False;
1253 if (UNMARSHALLING(ps) && r_u->datasize) {
1254 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
1255 if (!r_u->data) {
1256 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
1257 return False;
1261 if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
1262 return False;
1263 if(!prs_align(ps))
1264 return False;
1266 if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
1267 return False;
1268 if(!prs_werror("status", ps, depth, &r_u->status))
1269 return False;
1271 return True;
1274 /*******************************************************************
1275 ********************************************************************/
1277 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
1279 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
1280 depth++;
1282 if(!prs_align(ps))
1283 return False;
1284 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
1285 return False;
1286 if(!prs_uint32("index", ps, depth, &q_u->index))
1287 return False;
1288 if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
1289 return False;
1290 if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
1291 return False;
1293 return True;
1296 /*******************************************************************
1297 ********************************************************************/
1299 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
1300 const POLICY_HND *hnd,
1301 uint32 idx, uint32 valuelen, uint32 datalen)
1303 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1304 q_u->index=idx;
1305 q_u->valuesize=valuelen;
1306 q_u->datasize=datalen;
1308 return True;
1311 /*******************************************************************
1312 ********************************************************************/
1314 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
1315 const POLICY_HND *hnd, const char *key,
1316 uint32 size)
1318 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1319 init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
1320 q_u->size = size;
1322 return True;
1325 /*******************************************************************
1326 ********************************************************************/
1327 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
1328 char* value, uint32 data_type, char* data, uint32 data_size)
1330 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1331 q_u->type = data_type;
1332 init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
1334 q_u->max_len = q_u->real_len = data_size;
1335 q_u->data = (unsigned char *)data;
1337 return True;
1340 /*******************************************************************
1341 ********************************************************************/
1343 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
1345 prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
1346 depth++;
1348 if(!prs_align(ps))
1349 return False;
1350 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1351 return False;
1352 if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
1353 return False;
1355 if(!prs_align(ps))
1356 return False;
1358 if(!prs_uint32("type", ps, depth, &q_u->type))
1359 return False;
1361 if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
1362 return False;
1364 switch (q_u->type)
1366 case REG_SZ:
1367 case REG_BINARY:
1368 case REG_DWORD:
1369 case REG_MULTI_SZ:
1370 if (q_u->max_len) {
1371 if (UNMARSHALLING(ps))
1372 q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
1373 if(q_u->data == NULL)
1374 return False;
1375 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
1376 return False;
1378 if(!prs_align(ps))
1379 return False;
1380 break;
1383 if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
1384 return False;
1386 return True;
1389 /*******************************************************************
1390 ********************************************************************/
1392 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
1394 prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
1395 depth++;
1397 if(!prs_align(ps))
1398 return False;
1399 if(!prs_werror("status", ps, depth, &r_u->status))
1400 return False;
1402 return True;
1405 void free_devmode(DEVICEMODE *devmode)
1407 if (devmode!=NULL) {
1408 SAFE_FREE(devmode->dev_private);
1409 SAFE_FREE(devmode);
1413 void free_printer_info_1(PRINTER_INFO_1 *printer)
1415 SAFE_FREE(printer);
1418 void free_printer_info_2(PRINTER_INFO_2 *printer)
1420 if (printer!=NULL) {
1421 free_devmode(printer->devmode);
1422 printer->devmode = NULL;
1423 SAFE_FREE(printer);
1427 void free_printer_info_3(PRINTER_INFO_3 *printer)
1429 SAFE_FREE(printer);
1432 void free_printer_info_4(PRINTER_INFO_4 *printer)
1434 SAFE_FREE(printer);
1437 void free_printer_info_5(PRINTER_INFO_5 *printer)
1439 SAFE_FREE(printer);
1442 void free_printer_info_6(PRINTER_INFO_6 *printer)
1444 SAFE_FREE(printer);
1447 void free_printer_info_7(PRINTER_INFO_7 *printer)
1449 SAFE_FREE(printer);
1452 /*******************************************************************
1453 * read a structure.
1454 ********************************************************************/
1455 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u,
1456 POLICY_HND *hnd, const char *key,
1457 uint32 size)
1459 DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
1461 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
1462 init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
1463 q_u->size = size;
1465 return True;
1468 /*******************************************************************
1469 * read a structure.
1470 ********************************************************************/
1472 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
1474 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
1475 depth++;
1477 if(!prs_align(ps))
1478 return False;
1479 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1480 return False;
1482 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
1483 return False;
1485 if(!prs_align(ps))
1486 return False;
1488 if(!prs_uint32("size", ps, depth, &q_u->size))
1489 return False;
1491 return True;
1494 /*******************************************************************
1495 * write a structure.
1496 ********************************************************************/
1498 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
1500 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
1501 depth++;
1503 if(!prs_align(ps))
1504 return False;
1506 if (!smb_io_buffer5("", &r_u->keys, ps, depth))
1507 return False;
1509 if(!prs_align(ps))
1510 return False;
1512 if(!prs_uint32("needed", ps, depth, &r_u->needed))
1513 return False;
1515 if(!prs_werror("status", ps, depth, &r_u->status))
1516 return False;
1518 return True;
1521 /*******************************************************************
1522 * read a structure.
1523 ********************************************************************/
1525 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
1527 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
1528 depth++;
1530 if(!prs_align(ps))
1531 return False;
1532 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
1533 return False;
1535 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
1536 return False;
1538 if(!prs_align(ps))
1539 return False;
1541 if(!prs_uint32("size", ps, depth, &q_u->size))
1542 return False;
1544 return True;
1547 /*******************************************************************
1548 ********************************************************************/
1550 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps,
1551 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
1553 int i;
1554 uint32 valuename_offset,
1555 data_offset,
1556 current_offset;
1557 const uint32 basic_unit = 20; /* size of static portion of enum_values */
1559 prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
1560 depth++;
1563 * offset data begins at 20 bytes per structure * size_of_array.
1564 * Don't forget the uint32 at the beginning
1565 * */
1567 current_offset = basic_unit * ctr->size_of_array;
1569 /* first loop to write basic enum_value information */
1571 if (UNMARSHALLING(ps) && ctr->size_of_array) {
1572 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
1573 if (!ctr->values)
1574 return False;
1577 for (i=0; i<ctr->size_of_array; i++) {
1578 uint32 base_offset, return_offset;
1580 base_offset = prs_offset(ps);
1582 valuename_offset = current_offset;
1583 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
1584 return False;
1586 /* Read or write the value. */
1588 return_offset = prs_offset(ps);
1590 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
1591 return False;
1594 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
1595 return False;
1597 /* And go back. */
1598 if (!prs_set_offset(ps, return_offset))
1599 return False;
1601 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
1602 return False;
1604 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
1605 return False;
1607 data_offset = ctr->values[i].value_len + valuename_offset;
1609 if (!prs_uint32("data_offset", ps, depth, &data_offset))
1610 return False;
1612 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
1613 return False;
1615 /* Read or write the data. */
1617 return_offset = prs_offset(ps);
1619 if (!prs_set_offset(ps, base_offset + data_offset)) {
1620 return False;
1623 if ( ctr->values[i].data_len ) {
1624 if ( UNMARSHALLING(ps) ) {
1625 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
1626 if (!ctr->values[i].data)
1627 return False;
1629 if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
1630 return False;
1633 current_offset = data_offset + ctr->values[i].data_len - basic_unit;
1634 /* account for 2 byte alignment */
1635 current_offset += (current_offset % 2);
1637 /* Remember how far we got. */
1638 data_offset = prs_offset(ps);
1640 /* And go back. */
1641 if (!prs_set_offset(ps, return_offset))
1642 return False;
1646 /* Go to the last data offset we got to. */
1648 if (!prs_set_offset(ps, data_offset))
1649 return False;
1651 /* And ensure we're 2 byte aligned. */
1653 if ( !prs_align_uint16(ps) )
1654 return False;
1656 return True;
1659 /*******************************************************************
1660 * write a structure.
1661 ********************************************************************/
1663 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
1665 uint32 data_offset, end_offset;
1666 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
1667 depth++;
1669 if(!prs_align(ps))
1670 return False;
1672 if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
1673 return False;
1675 data_offset = prs_offset(ps);
1677 if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
1678 return False;
1680 if(!prs_align(ps))
1681 return False;
1683 if(!prs_uint32("needed", ps, depth, &r_u->needed))
1684 return False;
1686 if(!prs_uint32("returned", ps, depth, &r_u->returned))
1687 return False;
1689 if(!prs_werror("status", ps, depth, &r_u->status))
1690 return False;
1692 r_u->ctr.size_of_array = r_u->returned;
1694 end_offset = prs_offset(ps);
1696 if (!prs_set_offset(ps, data_offset))
1697 return False;
1699 if (r_u->ctr.size)
1700 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
1701 return False;
1703 if (!prs_set_offset(ps, end_offset))
1704 return False;
1705 return True;