s3-spoolss: remove old spoolss_GetPrinterData.
[Samba/gbeck.git] / source3 / rpc_parse / parse_spoolss.c
bloba7d69f67efad15eaf4b667f9b194d99e9aa55aa2
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 * return the length of a uint32 (obvious, but the code is clean)
263 ********************************************************************/
265 static uint32 size_of_uint32(uint32 *value)
267 return (sizeof(*value));
270 /*******************************************************************
271 return the size required by a struct in the stream
272 ********************************************************************/
273 uint32 spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES *p)
275 uint32 size = 0;
277 if (!p)
278 return 0;
280 /* uint32(offset) + uint32(length) + length) */
281 size += (size_of_uint32(&p->value_len)*2) + p->value_len;
282 size += (size_of_uint32(&p->data_len)*2) + p->data_len + (p->data_len%2) ;
284 size += size_of_uint32(&p->type);
286 return size;
289 /*******************************************************************
290 make a BUFFER5 struct from a uint16*
291 ******************************************************************/
293 bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src)
296 buf5->buf_len = len;
297 if (src) {
298 if (len) {
299 if((buf5->buffer=(uint16*)TALLOC_MEMDUP(mem_ctx, src, sizeof(uint16)*len)) == NULL) {
300 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
301 return False;
303 } else {
304 buf5->buffer = NULL;
306 } else {
307 buf5->buffer=NULL;
310 return True;
313 /*******************************************************************
314 ********************************************************************/
316 bool spoolss_io_r_enumprinterdata(const char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
318 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
319 depth++;
321 if(!prs_align(ps))
322 return False;
323 if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
324 return False;
326 if (UNMARSHALLING(ps) && r_u->valuesize) {
327 r_u->value = PRS_ALLOC_MEM(ps, uint16, r_u->valuesize);
328 if (!r_u->value) {
329 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
330 return False;
334 if(!prs_uint16uni(False, "value", ps, depth, r_u->value, r_u->valuesize ))
335 return False;
337 if(!prs_align(ps))
338 return False;
340 if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
341 return False;
343 if(!prs_uint32("type", ps, depth, &r_u->type))
344 return False;
346 if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
347 return False;
349 if (UNMARSHALLING(ps) && r_u->datasize) {
350 r_u->data = PRS_ALLOC_MEM(ps, uint8, r_u->datasize);
351 if (!r_u->data) {
352 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
353 return False;
357 if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
358 return False;
359 if(!prs_align(ps))
360 return False;
362 if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
363 return False;
364 if(!prs_werror("status", ps, depth, &r_u->status))
365 return False;
367 return True;
370 /*******************************************************************
371 ********************************************************************/
373 bool spoolss_io_q_enumprinterdata(const char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth)
375 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
376 depth++;
378 if(!prs_align(ps))
379 return False;
380 if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth))
381 return False;
382 if(!prs_uint32("index", ps, depth, &q_u->index))
383 return False;
384 if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
385 return False;
386 if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
387 return False;
389 return True;
392 /*******************************************************************
393 ********************************************************************/
395 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
396 const POLICY_HND *hnd,
397 uint32 idx, uint32 valuelen, uint32 datalen)
399 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
400 q_u->index=idx;
401 q_u->valuesize=valuelen;
402 q_u->datasize=datalen;
404 return True;
407 /*******************************************************************
408 ********************************************************************/
410 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX *q_u,
411 const POLICY_HND *hnd, const char *key,
412 uint32 size)
414 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
415 init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
416 q_u->size = size;
418 return True;
421 /*******************************************************************
422 ********************************************************************/
423 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND *hnd,
424 char* value, uint32 data_type, char* data, uint32 data_size)
426 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
427 q_u->type = data_type;
428 init_unistr2(&q_u->value, value, UNI_STR_TERMINATE);
430 q_u->max_len = q_u->real_len = data_size;
431 q_u->data = (unsigned char *)data;
433 return True;
436 /*******************************************************************
437 ********************************************************************/
439 bool spoolss_io_q_setprinterdata(const char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth)
441 prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata");
442 depth++;
444 if(!prs_align(ps))
445 return False;
446 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
447 return False;
448 if(!smb_io_unistr2("", &q_u->value, True, ps, depth))
449 return False;
451 if(!prs_align(ps))
452 return False;
454 if(!prs_uint32("type", ps, depth, &q_u->type))
455 return False;
457 if(!prs_uint32("max_len", ps, depth, &q_u->max_len))
458 return False;
460 switch (q_u->type)
462 case REG_SZ:
463 case REG_BINARY:
464 case REG_DWORD:
465 case REG_MULTI_SZ:
466 if (q_u->max_len) {
467 if (UNMARSHALLING(ps))
468 q_u->data=PRS_ALLOC_MEM(ps, uint8, q_u->max_len);
469 if(q_u->data == NULL)
470 return False;
471 if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len))
472 return False;
474 if(!prs_align(ps))
475 return False;
476 break;
479 if(!prs_uint32("real_len", ps, depth, &q_u->real_len))
480 return False;
482 return True;
485 /*******************************************************************
486 ********************************************************************/
488 bool spoolss_io_r_setprinterdata(const char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth)
490 prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata");
491 depth++;
493 if(!prs_align(ps))
494 return False;
495 if(!prs_werror("status", ps, depth, &r_u->status))
496 return False;
498 return True;
501 /*******************************************************************
502 * read a structure.
503 ********************************************************************/
504 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY *q_u,
505 POLICY_HND *hnd, const char *key,
506 uint32 size)
508 DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
510 memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
511 init_unistr2(&q_u->key, key, UNI_STR_TERMINATE);
512 q_u->size = size;
514 return True;
517 /*******************************************************************
518 * read a structure.
519 ********************************************************************/
521 bool spoolss_io_q_enumprinterkey(const char *desc, SPOOL_Q_ENUMPRINTERKEY *q_u, prs_struct *ps, int depth)
523 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterkey");
524 depth++;
526 if(!prs_align(ps))
527 return False;
528 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
529 return False;
531 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
532 return False;
534 if(!prs_align(ps))
535 return False;
537 if(!prs_uint32("size", ps, depth, &q_u->size))
538 return False;
540 return True;
543 /*******************************************************************
544 * write a structure.
545 ********************************************************************/
547 bool spoolss_io_r_enumprinterkey(const char *desc, SPOOL_R_ENUMPRINTERKEY *r_u, prs_struct *ps, int depth)
549 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterkey");
550 depth++;
552 if(!prs_align(ps))
553 return False;
555 if (!smb_io_buffer5("", &r_u->keys, ps, depth))
556 return False;
558 if(!prs_align(ps))
559 return False;
561 if(!prs_uint32("needed", ps, depth, &r_u->needed))
562 return False;
564 if(!prs_werror("status", ps, depth, &r_u->status))
565 return False;
567 return True;
570 /*******************************************************************
571 * read a structure.
572 ********************************************************************/
574 bool spoolss_io_q_enumprinterdataex(const char *desc, SPOOL_Q_ENUMPRINTERDATAEX *q_u, prs_struct *ps, int depth)
576 prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdataex");
577 depth++;
579 if(!prs_align(ps))
580 return False;
581 if(!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth))
582 return False;
584 if(!smb_io_unistr2("", &q_u->key, True, ps, depth))
585 return False;
587 if(!prs_align(ps))
588 return False;
590 if(!prs_uint32("size", ps, depth, &q_u->size))
591 return False;
593 return True;
596 /*******************************************************************
597 ********************************************************************/
599 static bool spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps,
600 PRINTER_ENUM_VALUES_CTR *ctr, int depth)
602 int i;
603 uint32 valuename_offset,
604 data_offset,
605 current_offset;
606 const uint32 basic_unit = 20; /* size of static portion of enum_values */
608 prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr");
609 depth++;
612 * offset data begins at 20 bytes per structure * size_of_array.
613 * Don't forget the uint32 at the beginning
614 * */
616 current_offset = basic_unit * ctr->size_of_array;
618 /* first loop to write basic enum_value information */
620 if (UNMARSHALLING(ps) && ctr->size_of_array) {
621 ctr->values = PRS_ALLOC_MEM(ps, PRINTER_ENUM_VALUES, ctr->size_of_array);
622 if (!ctr->values)
623 return False;
626 for (i=0; i<ctr->size_of_array; i++) {
627 uint32 base_offset, return_offset;
629 base_offset = prs_offset(ps);
631 valuename_offset = current_offset;
632 if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset))
633 return False;
635 /* Read or write the value. */
637 return_offset = prs_offset(ps);
639 if (!prs_set_offset(ps, base_offset + valuename_offset)) {
640 return False;
643 if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename))
644 return False;
646 /* And go back. */
647 if (!prs_set_offset(ps, return_offset))
648 return False;
650 if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len))
651 return False;
653 if (!prs_uint32("type", ps, depth, &ctr->values[i].type))
654 return False;
656 data_offset = ctr->values[i].value_len + valuename_offset;
658 if (!prs_uint32("data_offset", ps, depth, &data_offset))
659 return False;
661 if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len))
662 return False;
664 /* Read or write the data. */
666 return_offset = prs_offset(ps);
668 if (!prs_set_offset(ps, base_offset + data_offset)) {
669 return False;
672 if ( ctr->values[i].data_len ) {
673 if ( UNMARSHALLING(ps) ) {
674 ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len);
675 if (!ctr->values[i].data)
676 return False;
678 if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len))
679 return False;
682 current_offset = data_offset + ctr->values[i].data_len - basic_unit;
683 /* account for 2 byte alignment */
684 current_offset += (current_offset % 2);
686 /* Remember how far we got. */
687 data_offset = prs_offset(ps);
689 /* And go back. */
690 if (!prs_set_offset(ps, return_offset))
691 return False;
695 /* Go to the last data offset we got to. */
697 if (!prs_set_offset(ps, data_offset))
698 return False;
700 /* And ensure we're 2 byte aligned. */
702 if ( !prs_align_uint16(ps) )
703 return False;
705 return True;
708 /*******************************************************************
709 * write a structure.
710 ********************************************************************/
712 bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX *r_u, prs_struct *ps, int depth)
714 uint32 data_offset, end_offset;
715 prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdataex");
716 depth++;
718 if(!prs_align(ps))
719 return False;
721 if (!prs_uint32("size", ps, depth, &r_u->ctr.size))
722 return False;
724 data_offset = prs_offset(ps);
726 if (!prs_set_offset(ps, data_offset + r_u->ctr.size))
727 return False;
729 if(!prs_align(ps))
730 return False;
732 if(!prs_uint32("needed", ps, depth, &r_u->needed))
733 return False;
735 if(!prs_uint32("returned", ps, depth, &r_u->returned))
736 return False;
738 if(!prs_werror("status", ps, depth, &r_u->status))
739 return False;
741 r_u->ctr.size_of_array = r_u->returned;
743 end_offset = prs_offset(ps);
745 if (!prs_set_offset(ps, data_offset))
746 return False;
748 if (r_u->ctr.size)
749 if (!spoolss_io_printer_enum_values_ctr("", ps, &r_u->ctr, depth ))
750 return False;
752 if (!prs_set_offset(ps, end_offset))
753 return False;
754 return True;