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/>.
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
))
38 if(!prs_uint16("month", ps
, depth
, &systime
->month
))
40 if(!prs_uint16("dayofweek", ps
, depth
, &systime
->dayofweek
))
42 if(!prs_uint16("day", ps
, depth
, &systime
->day
))
44 if(!prs_uint16("hour", ps
, depth
, &systime
->hour
))
46 if(!prs_uint16("minute", ps
, depth
, &systime
->minute
))
48 if(!prs_uint16("second", ps
, depth
, &systime
->second
))
50 if(!prs_uint16("milliseconds", ps
, depth
, &systime
->milliseconds
))
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;
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 */
85 uint16
*unistr_buffer
;
88 struct optional_fields
{
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");
117 if (UNMARSHALLING(ps
)) {
118 devmode
->devicename
.buffer
= PRS_ALLOC_MEM(ps
, uint16
, MAXDEVICENAME
);
119 if (devmode
->devicename
.buffer
== NULL
)
121 unistr_buffer
= devmode
->devicename
.buffer
;
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
))
134 if (!prs_uint16("specversion", ps
, depth
, &devmode
->specversion
))
137 if (!prs_uint16("driverversion", ps
, depth
, &devmode
->driverversion
))
139 if (!prs_uint16("size", ps
, depth
, &devmode
->size
))
141 if (!prs_uint16("driverextra", ps
, depth
, &devmode
->driverextra
))
143 if (!prs_uint32("fields", ps
, depth
, &devmode
->fields
))
145 if (!prs_uint16("orientation", ps
, depth
, &devmode
->orientation
))
147 if (!prs_uint16("papersize", ps
, depth
, &devmode
->papersize
))
149 if (!prs_uint16("paperlength", ps
, depth
, &devmode
->paperlength
))
151 if (!prs_uint16("paperwidth", ps
, depth
, &devmode
->paperwidth
))
153 if (!prs_uint16("scale", ps
, depth
, &devmode
->scale
))
155 if (!prs_uint16("copies", ps
, depth
, &devmode
->copies
))
157 if (!prs_uint16("defaultsource", ps
, depth
, &devmode
->defaultsource
))
159 if (!prs_uint16("printquality", ps
, depth
, &devmode
->printquality
))
161 if (!prs_uint16("color", ps
, depth
, &devmode
->color
))
163 if (!prs_uint16("duplex", ps
, depth
, &devmode
->duplex
))
165 if (!prs_uint16("yresolution", ps
, depth
, &devmode
->yresolution
))
167 if (!prs_uint16("ttoption", ps
, depth
, &devmode
->ttoption
))
169 if (!prs_uint16("collate", ps
, depth
, &devmode
->collate
))
172 if (UNMARSHALLING(ps
)) {
173 devmode
->formname
.buffer
= PRS_ALLOC_MEM(ps
, uint16
, MAXDEVICENAME
);
174 if (devmode
->formname
.buffer
== NULL
)
176 unistr_buffer
= devmode
->formname
.buffer
;
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
))
188 if (!prs_uint16("logpixels", ps
, depth
, &devmode
->logpixels
))
190 if (!prs_uint32("bitsperpel", ps
, depth
, &devmode
->bitsperpel
))
192 if (!prs_uint32("pelswidth", ps
, depth
, &devmode
->pelswidth
))
194 if (!prs_uint32("pelsheight", ps
, depth
, &devmode
->pelsheight
))
196 if (!prs_uint32("displayflags", ps
, depth
, &devmode
->displayflags
))
198 if (!prs_uint32("displayfrequency", ps
, depth
, &devmode
->displayfrequency
))
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"));
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
))
228 available_space
-= sizeof(uint32
);
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"));
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
)
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
))
261 /*******************************************************************
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
);
280 /*******************************************************************
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
)
290 prs_debug(ps
, depth
, desc
, "spoolss_io_q_getprinterdata");
295 if (!smb_io_pol_hnd("printer handle",&q_u
->handle
,ps
,depth
))
299 if (!smb_io_unistr2("valuename", &q_u
->valuename
,True
,ps
,depth
))
303 if (!prs_uint32("size", ps
, depth
, &q_u
->size
))
309 /*******************************************************************
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
)
319 prs_debug(ps
, depth
, desc
, "spoolss_io_r_getprinterdata");
324 if (!prs_uint32("type", ps
, depth
, &r_u
->type
))
326 if (!prs_uint32("size", ps
, depth
, &r_u
->size
))
329 if (UNMARSHALLING(ps
) && r_u
->size
) {
330 r_u
->data
= PRS_ALLOC_MEM(ps
, unsigned char, r_u
->size
);
335 if (!prs_uint8s( False
, "data", ps
, depth
, r_u
->data
, r_u
->size
))
341 if (!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
343 if (!prs_werror("status", ps
, depth
, &r_u
->status
))
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
)
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");
399 if (MARSHALLING(ps
)) {
400 uint32 struct_offset
= prs_offset(ps
);
401 uint32 relative_offset
;
403 if (*devmode
== NULL
) {
405 if (!prs_uint32("offset", ps
, depth
, &relative_offset
))
407 DEBUG(8, ("boing, the devmode was NULL\n"));
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
))
422 /* write the DEVMODE */
423 if (!spoolss_io_devmode(desc
, ps
, depth
, *devmode
))
426 if(!prs_set_offset(ps
, struct_offset
))
429 relative_offset
=buffer
->string_at_end
- buffer
->struct_start
;
430 /* write its offset */
431 if (!prs_uint32("offset", ps
, depth
, &relative_offset
))
437 /* read the offset */
438 if (!prs_uint32("offset", ps
, depth
, &buffer
->string_at_end
))
440 if (buffer
->string_at_end
== 0) {
445 old_offset
= prs_offset(ps
);
446 if(!prs_set_offset(ps
, buffer
->string_at_end
+ buffer
->struct_start
))
449 /* read the string */
450 if((*devmode
=PRS_ALLOC_MEM(ps
,DEVICEMODE
,1)) == NULL
)
452 if (!spoolss_io_devmode(desc
, ps
, depth
, *devmode
))
455 if(!prs_set_offset(ps
, old_offset
))
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");
472 buffer
->struct_start
=prs_offset(ps
);
474 if (!smb_io_relstr("printername", buffer
, depth
, &info
->printername
))
476 if (!smb_io_relstr("servername", buffer
, depth
, &info
->servername
))
479 if(!prs_uint32("cjobs", ps
, depth
, &info
->cjobs
))
481 if(!prs_uint32("total_jobs", ps
, depth
, &info
->total_jobs
))
483 if(!prs_uint32("total_bytes", ps
, depth
, &info
->total_bytes
))
486 if(!prs_uint16("year", ps
, depth
, &info
->year
))
488 if(!prs_uint16("month", ps
, depth
, &info
->month
))
490 if(!prs_uint16("dayofweek", ps
, depth
, &info
->dayofweek
))
492 if(!prs_uint16("day", ps
, depth
, &info
->day
))
494 if(!prs_uint16("hour", ps
, depth
, &info
->hour
))
496 if(!prs_uint16("minute", ps
, depth
, &info
->minute
))
498 if(!prs_uint16("second", ps
, depth
, &info
->second
))
500 if(!prs_uint16("milliseconds", ps
, depth
, &info
->milliseconds
))
503 if(!prs_uint32("global_counter", ps
, depth
, &info
->global_counter
))
505 if(!prs_uint32("total_pages", ps
, depth
, &info
->total_pages
))
508 if(!prs_uint16("major_version", ps
, depth
, &info
->major_version
))
510 if(!prs_uint16("build_version", ps
, depth
, &info
->build_version
))
512 if(!prs_uint32("unknown7", ps
, depth
, &info
->unknown7
))
514 if(!prs_uint32("unknown8", ps
, depth
, &info
->unknown8
))
516 if(!prs_uint32("unknown9", ps
, depth
, &info
->unknown9
))
518 if(!prs_uint32("session_counter", ps
, depth
, &info
->session_counter
))
520 if(!prs_uint32("unknown11", ps
, depth
, &info
->unknown11
))
522 if(!prs_uint32("printer_errors", ps
, depth
, &info
->printer_errors
))
524 if(!prs_uint32("unknown13", ps
, depth
, &info
->unknown13
))
526 if(!prs_uint32("unknown14", ps
, depth
, &info
->unknown14
))
528 if(!prs_uint32("unknown15", ps
, depth
, &info
->unknown15
))
530 if(!prs_uint32("unknown16", ps
, depth
, &info
->unknown16
))
532 if(!prs_uint32("change_id", ps
, depth
, &info
->change_id
))
534 if(!prs_uint32("unknown18", ps
, depth
, &info
->unknown18
))
536 if(!prs_uint32("status" , ps
, depth
, &info
->status
))
538 if(!prs_uint32("unknown20", ps
, depth
, &info
->unknown20
))
540 if(!prs_uint32("c_setprinter", ps
, depth
, &info
->c_setprinter
))
542 if(!prs_uint16("unknown22", ps
, depth
, &info
->unknown22
))
544 if(!prs_uint16("unknown23", ps
, depth
, &info
->unknown23
))
546 if(!prs_uint16("unknown24", ps
, depth
, &info
->unknown24
))
548 if(!prs_uint16("unknown25", ps
, depth
, &info
->unknown25
))
550 if(!prs_uint16("unknown26", ps
, depth
, &info
->unknown26
))
552 if(!prs_uint16("unknown27", ps
, depth
, &info
->unknown27
))
554 if(!prs_uint16("unknown28", ps
, depth
, &info
->unknown28
))
556 if(!prs_uint16("unknown29", ps
, depth
, &info
->unknown29
))
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");
573 buffer
->struct_start
=prs_offset(ps
);
575 if (!prs_uint32("flags", ps
, depth
, &info
->flags
))
577 if (!smb_io_relstr("description", buffer
, depth
, &info
->description
))
579 if (!smb_io_relstr("name", buffer
, depth
, &info
->name
))
581 if (!smb_io_relstr("comment", buffer
, depth
, &info
->comment
))
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");
600 buffer
->struct_start
=prs_offset(ps
);
602 if (!smb_io_relstr("servername", buffer
, depth
, &info
->servername
))
604 if (!smb_io_relstr("printername", buffer
, depth
, &info
->printername
))
606 if (!smb_io_relstr("sharename", buffer
, depth
, &info
->sharename
))
608 if (!smb_io_relstr("portname", buffer
, depth
, &info
->portname
))
610 if (!smb_io_relstr("drivername", buffer
, depth
, &info
->drivername
))
612 if (!smb_io_relstr("comment", buffer
, depth
, &info
->comment
))
614 if (!smb_io_relstr("location", buffer
, depth
, &info
->location
))
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
))
622 if (!smb_io_relstr("sepfile", buffer
, depth
, &info
->sepfile
))
624 if (!smb_io_relstr("printprocessor", buffer
, depth
, &info
->printprocessor
))
626 if (!smb_io_relstr("datatype", buffer
, depth
, &info
->datatype
))
628 if (!smb_io_relstr("parameters", buffer
, depth
, &info
->parameters
))
631 /* save current offset for the sec_desc */
632 sd_offset
= prs_offset(ps
);
633 if (!prs_uint32("sec_desc", ps
, depth
, &has_secdesc
))
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
))
643 if (!smb_io_reldevmode("devmode", buffer
, depth
, &info
->devmode
))
646 /* parse the sec_desc */
648 if (!prs_set_offset(ps
, sd_offset
))
650 if (!smb_io_relsecdesc("secdesc", buffer
, depth
, &info
->secdesc
))
654 /* pick up where we left off */
655 if (!prs_set_offset(ps
, current_offset
))
658 if (!prs_uint32("attributes", ps
, depth
, &info
->attributes
))
660 if (!prs_uint32("priority", ps
, depth
, &info
->priority
))
662 if (!prs_uint32("defpriority", ps
, depth
, &info
->defaultpriority
))
664 if (!prs_uint32("starttime", ps
, depth
, &info
->starttime
))
666 if (!prs_uint32("untiltime", ps
, depth
, &info
->untiltime
))
668 if (!prs_uint32("status", ps
, depth
, &info
->status
))
670 if (!prs_uint32("jobs", ps
, depth
, &info
->cjobs
))
672 if (!prs_uint32("averageppm", ps
, depth
, &info
->averageppm
))
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
)
685 prs_struct
*ps
=&buffer
->prs
;
687 prs_debug(ps
, depth
, desc
, "smb_io_printer_info_3");
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. */
697 /* Write a dummy value. */
698 if (!prs_uint32("offset", ps
, depth
, &off_val
))
702 if (!prs_align_uint64(ps
))
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
))
717 /* Return to after the 8 byte align. */
718 prs_set_offset(ps
, offset
);
721 if (!prs_uint32("offset", ps
, depth
, &offset
))
723 /* Seek within the buffer. */
724 if (!prs_set_offset(ps
, offset
))
727 if (!sec_io_desc("sec_desc", &info
->secdesc
, ps
, depth
))
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");
744 buffer
->struct_start
=prs_offset(ps
);
746 if (!smb_io_relstr("printername", buffer
, depth
, &info
->printername
))
748 if (!smb_io_relstr("servername", buffer
, depth
, &info
->servername
))
750 if (!prs_uint32("attributes", ps
, depth
, &info
->attributes
))
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");
766 buffer
->struct_start
=prs_offset(ps
);
768 if (!smb_io_relstr("printername", buffer
, depth
, &info
->printername
))
770 if (!smb_io_relstr("portname", buffer
, depth
, &info
->portname
))
772 if (!prs_uint32("attributes", ps
, depth
, &info
->attributes
))
774 if (!prs_uint32("device_not_selected_timeout", ps
, depth
, &info
->device_not_selected_timeout
))
776 if (!prs_uint32("transmission_retry_timeout", ps
, depth
, &info
->transmission_retry_timeout
))
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");
793 if (!prs_uint32("status", ps
, depth
, &info
->status
))
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");
810 buffer
->struct_start
=prs_offset(ps
);
812 if (!smb_io_relstr("guid", buffer
, depth
, &info
->guid
))
814 if (!prs_uint32("action", ps
, depth
, &info
->action
))
819 /*******************************************************************
820 return the size required by a struct in the stream
821 ********************************************************************/
823 uint32
spoolss_size_printer_info_0(PRINTER_INFO_0
*info
)
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
);
877 /*******************************************************************
878 return the size required by a struct in the stream
879 ********************************************************************/
881 uint32
spoolss_size_printer_info_1(PRINTER_INFO_1
*info
)
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
);
893 /*******************************************************************
894 return the size required by a struct in the stream
895 ********************************************************************/
897 uint32
spoolss_size_printer_info_2(PRINTER_INFO_2
*info
)
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
937 size
+= 4 - (size
% 4);
942 /*******************************************************************
943 return the size required by a struct in the stream
944 ********************************************************************/
946 uint32
spoolss_size_printer_info_4(PRINTER_INFO_4
*info
)
950 size
+=size_of_relative_string( &info
->printername
);
951 size
+=size_of_relative_string( &info
->servername
);
953 size
+=size_of_uint32( &info
->attributes
);
957 /*******************************************************************
958 return the size required by a struct in the stream
959 ********************************************************************/
961 uint32
spoolss_size_printer_info_5(PRINTER_INFO_5
*info
)
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
);
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
)
1001 size
+=size_of_relative_string( &info
->guid
);
1002 size
+=size_of_uint32( &info
->action
);
1006 /*******************************************************************
1007 return the size required by a string array.
1008 ********************************************************************/
1010 uint32
spoolss_size_string_array(uint16
*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 */
1024 /*******************************************************************
1025 return the size required by a struct in the stream
1026 ********************************************************************/
1027 uint32
spoolss_size_printer_enum_values(PRINTER_ENUM_VALUES
*p
)
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
);
1043 /*******************************************************************
1045 * called from spoolss_enumprinters (srv_spoolss.c)
1046 ********************************************************************/
1048 bool spoolss_io_q_enumprinters(const char *desc
, SPOOL_Q_ENUMPRINTERS
*q_u
, prs_struct
*ps
, int depth
)
1050 prs_debug(ps
, depth
, desc
, "spoolss_io_q_enumprinters");
1056 if (!prs_uint32("flags", ps
, depth
, &q_u
->flags
))
1058 if (!prs_uint32("servername_ptr", ps
, depth
, &q_u
->servername_ptr
))
1061 if (!smb_io_unistr2("", &q_u
->servername
, q_u
->servername_ptr
, ps
, depth
))
1066 if (!prs_uint32("level", ps
, depth
, &q_u
->level
))
1069 if (!prs_rpcbuffer_p("", ps
, depth
, &q_u
->buffer
))
1074 if (!prs_uint32("offered", ps
, depth
, &q_u
->offered
))
1080 /*******************************************************************
1081 Parse a SPOOL_R_ENUMPRINTERS structure.
1082 ********************************************************************/
1084 bool spoolss_io_r_enumprinters(const char *desc
, SPOOL_R_ENUMPRINTERS
*r_u
, prs_struct
*ps
, int depth
)
1086 prs_debug(ps
, depth
, desc
, "spoolss_io_r_enumprinters");
1092 if (!prs_rpcbuffer_p("", ps
, depth
, &r_u
->buffer
))
1098 if (!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
1101 if (!prs_uint32("returned", ps
, depth
, &r_u
->returned
))
1104 if (!prs_werror("status", ps
, depth
, &r_u
->status
))
1110 /*******************************************************************
1111 * write a structure.
1112 * called from spoolss_r_enum_printers (srv_spoolss.c)
1114 ********************************************************************/
1116 bool spoolss_io_r_getprinter(const char *desc
, SPOOL_R_GETPRINTER
*r_u
, prs_struct
*ps
, int depth
)
1118 prs_debug(ps
, depth
, desc
, "spoolss_io_r_getprinter");
1124 if (!prs_rpcbuffer_p("", ps
, depth
, &r_u
->buffer
))
1130 if (!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
1133 if (!prs_werror("status", ps
, depth
, &r_u
->status
))
1139 /*******************************************************************
1141 * called from spoolss_getprinter (srv_spoolss.c)
1142 ********************************************************************/
1144 bool spoolss_io_q_getprinter(const char *desc
, SPOOL_Q_GETPRINTER
*q_u
, prs_struct
*ps
, int depth
)
1146 prs_debug(ps
, depth
, desc
, "spoolss_io_q_getprinter");
1152 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
1154 if (!prs_uint32("level", ps
, depth
, &q_u
->level
))
1157 if (!prs_rpcbuffer_p("", ps
, depth
, &q_u
->buffer
))
1162 if (!prs_uint32("offered", ps
, depth
, &q_u
->offered
))
1168 /*******************************************************************
1169 make a BUFFER5 struct from a uint16*
1170 ******************************************************************/
1172 bool make_spoolss_buffer5(TALLOC_CTX
*mem_ctx
, BUFFER5
*buf5
, uint32 len
, uint16
*src
)
1175 buf5
->buf_len
= len
;
1178 if((buf5
->buffer
=(uint16
*)TALLOC_MEMDUP(mem_ctx
, src
, sizeof(uint16
)*len
)) == NULL
) {
1179 DEBUG(0,("make_spoolss_buffer5: Unable to malloc memory for buffer!\n"));
1183 buf5
->buffer
= NULL
;
1192 /*******************************************************************
1193 ********************************************************************/
1195 bool spoolss_io_r_enumprinterdata(const char *desc
, SPOOL_R_ENUMPRINTERDATA
*r_u
, prs_struct
*ps
, int depth
)
1197 prs_debug(ps
, depth
, desc
, "spoolss_io_r_enumprinterdata");
1202 if(!prs_uint32("valuesize", ps
, depth
, &r_u
->valuesize
))
1205 if (UNMARSHALLING(ps
) && r_u
->valuesize
) {
1206 r_u
->value
= PRS_ALLOC_MEM(ps
, uint16
, r_u
->valuesize
);
1208 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
1213 if(!prs_uint16uni(False
, "value", ps
, depth
, r_u
->value
, r_u
->valuesize
))
1219 if(!prs_uint32("realvaluesize", ps
, depth
, &r_u
->realvaluesize
))
1222 if(!prs_uint32("type", ps
, depth
, &r_u
->type
))
1225 if(!prs_uint32("datasize", ps
, depth
, &r_u
->datasize
))
1228 if (UNMARSHALLING(ps
) && r_u
->datasize
) {
1229 r_u
->data
= PRS_ALLOC_MEM(ps
, uint8
, r_u
->datasize
);
1231 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
1236 if(!prs_uint8s(False
, "data", ps
, depth
, r_u
->data
, r_u
->datasize
))
1241 if(!prs_uint32("realdatasize", ps
, depth
, &r_u
->realdatasize
))
1243 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
1249 /*******************************************************************
1250 ********************************************************************/
1252 bool spoolss_io_q_enumprinterdata(const char *desc
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, prs_struct
*ps
, int depth
)
1254 prs_debug(ps
, depth
, desc
, "spoolss_io_q_enumprinterdata");
1259 if(!smb_io_pol_hnd("printer handle",&q_u
->handle
,ps
,depth
))
1261 if(!prs_uint32("index", ps
, depth
, &q_u
->index
))
1263 if(!prs_uint32("valuesize", ps
, depth
, &q_u
->valuesize
))
1265 if(!prs_uint32("datasize", ps
, depth
, &q_u
->datasize
))
1271 /*******************************************************************
1272 ********************************************************************/
1274 bool make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA
*q_u
,
1275 const POLICY_HND
*hnd
,
1276 uint32 idx
, uint32 valuelen
, uint32 datalen
)
1278 memcpy(&q_u
->handle
, hnd
, sizeof(q_u
->handle
));
1280 q_u
->valuesize
=valuelen
;
1281 q_u
->datasize
=datalen
;
1286 /*******************************************************************
1287 ********************************************************************/
1289 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX
*q_u
,
1290 const POLICY_HND
*hnd
, const char *key
,
1293 memcpy(&q_u
->handle
, hnd
, sizeof(q_u
->handle
));
1294 init_unistr2(&q_u
->key
, key
, UNI_STR_TERMINATE
);
1300 /*******************************************************************
1301 ********************************************************************/
1302 bool make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA
*q_u
, const POLICY_HND
*hnd
,
1303 char* value
, uint32 data_type
, char* data
, uint32 data_size
)
1305 memcpy(&q_u
->handle
, hnd
, sizeof(q_u
->handle
));
1306 q_u
->type
= data_type
;
1307 init_unistr2(&q_u
->value
, value
, UNI_STR_TERMINATE
);
1309 q_u
->max_len
= q_u
->real_len
= data_size
;
1310 q_u
->data
= (unsigned char *)data
;
1315 /*******************************************************************
1316 ********************************************************************/
1318 bool spoolss_io_q_setprinterdata(const char *desc
, SPOOL_Q_SETPRINTERDATA
*q_u
, prs_struct
*ps
, int depth
)
1320 prs_debug(ps
, depth
, desc
, "spoolss_io_q_setprinterdata");
1325 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
1327 if(!smb_io_unistr2("", &q_u
->value
, True
, ps
, depth
))
1333 if(!prs_uint32("type", ps
, depth
, &q_u
->type
))
1336 if(!prs_uint32("max_len", ps
, depth
, &q_u
->max_len
))
1346 if (UNMARSHALLING(ps
))
1347 q_u
->data
=PRS_ALLOC_MEM(ps
, uint8
, q_u
->max_len
);
1348 if(q_u
->data
== NULL
)
1350 if(!prs_uint8s(False
,"data", ps
, depth
, q_u
->data
, q_u
->max_len
))
1358 if(!prs_uint32("real_len", ps
, depth
, &q_u
->real_len
))
1364 /*******************************************************************
1365 ********************************************************************/
1367 bool spoolss_io_r_setprinterdata(const char *desc
, SPOOL_R_SETPRINTERDATA
*r_u
, prs_struct
*ps
, int depth
)
1369 prs_debug(ps
, depth
, desc
, "spoolss_io_r_setprinterdata");
1374 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
1380 void free_devmode(DEVICEMODE
*devmode
)
1382 if (devmode
!=NULL
) {
1383 SAFE_FREE(devmode
->dev_private
);
1388 void free_printer_info_1(PRINTER_INFO_1
*printer
)
1393 void free_printer_info_2(PRINTER_INFO_2
*printer
)
1395 if (printer
!=NULL
) {
1396 free_devmode(printer
->devmode
);
1397 printer
->devmode
= NULL
;
1402 void free_printer_info_3(PRINTER_INFO_3
*printer
)
1407 void free_printer_info_4(PRINTER_INFO_4
*printer
)
1412 void free_printer_info_5(PRINTER_INFO_5
*printer
)
1417 void free_printer_info_6(PRINTER_INFO_6
*printer
)
1422 void free_printer_info_7(PRINTER_INFO_7
*printer
)
1427 /*******************************************************************
1429 ********************************************************************/
1430 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY
*q_u
,
1431 POLICY_HND
*hnd
, const char *key
,
1434 DEBUG(5,("make_spoolss_q_enumprinterkey\n"));
1436 memcpy(&q_u
->handle
, hnd
, sizeof(q_u
->handle
));
1437 init_unistr2(&q_u
->key
, key
, UNI_STR_TERMINATE
);
1443 /*******************************************************************
1445 ********************************************************************/
1447 bool spoolss_io_q_enumprinterkey(const char *desc
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, prs_struct
*ps
, int depth
)
1449 prs_debug(ps
, depth
, desc
, "spoolss_io_q_enumprinterkey");
1454 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
1457 if(!smb_io_unistr2("", &q_u
->key
, True
, ps
, depth
))
1463 if(!prs_uint32("size", ps
, depth
, &q_u
->size
))
1469 /*******************************************************************
1470 * write a structure.
1471 ********************************************************************/
1473 bool spoolss_io_r_enumprinterkey(const char *desc
, SPOOL_R_ENUMPRINTERKEY
*r_u
, prs_struct
*ps
, int depth
)
1475 prs_debug(ps
, depth
, desc
, "spoolss_io_r_enumprinterkey");
1481 if (!smb_io_buffer5("", &r_u
->keys
, ps
, depth
))
1487 if(!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
1490 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
1496 /*******************************************************************
1498 ********************************************************************/
1500 bool spoolss_io_q_enumprinterdataex(const char *desc
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, prs_struct
*ps
, int depth
)
1502 prs_debug(ps
, depth
, desc
, "spoolss_io_q_enumprinterdataex");
1507 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
1510 if(!smb_io_unistr2("", &q_u
->key
, True
, ps
, depth
))
1516 if(!prs_uint32("size", ps
, depth
, &q_u
->size
))
1522 /*******************************************************************
1523 ********************************************************************/
1525 static bool spoolss_io_printer_enum_values_ctr(const char *desc
, prs_struct
*ps
,
1526 PRINTER_ENUM_VALUES_CTR
*ctr
, int depth
)
1529 uint32 valuename_offset
,
1532 const uint32 basic_unit
= 20; /* size of static portion of enum_values */
1534 prs_debug(ps
, depth
, desc
, "spoolss_io_printer_enum_values_ctr");
1538 * offset data begins at 20 bytes per structure * size_of_array.
1539 * Don't forget the uint32 at the beginning
1542 current_offset
= basic_unit
* ctr
->size_of_array
;
1544 /* first loop to write basic enum_value information */
1546 if (UNMARSHALLING(ps
) && ctr
->size_of_array
) {
1547 ctr
->values
= PRS_ALLOC_MEM(ps
, PRINTER_ENUM_VALUES
, ctr
->size_of_array
);
1552 for (i
=0; i
<ctr
->size_of_array
; i
++) {
1553 uint32 base_offset
, return_offset
;
1555 base_offset
= prs_offset(ps
);
1557 valuename_offset
= current_offset
;
1558 if (!prs_uint32("valuename_offset", ps
, depth
, &valuename_offset
))
1561 /* Read or write the value. */
1563 return_offset
= prs_offset(ps
);
1565 if (!prs_set_offset(ps
, base_offset
+ valuename_offset
)) {
1569 if (!prs_unistr("valuename", ps
, depth
, &ctr
->values
[i
].valuename
))
1573 if (!prs_set_offset(ps
, return_offset
))
1576 if (!prs_uint32("value_len", ps
, depth
, &ctr
->values
[i
].value_len
))
1579 if (!prs_uint32("type", ps
, depth
, &ctr
->values
[i
].type
))
1582 data_offset
= ctr
->values
[i
].value_len
+ valuename_offset
;
1584 if (!prs_uint32("data_offset", ps
, depth
, &data_offset
))
1587 if (!prs_uint32("data_len", ps
, depth
, &ctr
->values
[i
].data_len
))
1590 /* Read or write the data. */
1592 return_offset
= prs_offset(ps
);
1594 if (!prs_set_offset(ps
, base_offset
+ data_offset
)) {
1598 if ( ctr
->values
[i
].data_len
) {
1599 if ( UNMARSHALLING(ps
) ) {
1600 ctr
->values
[i
].data
= PRS_ALLOC_MEM(ps
, uint8
, ctr
->values
[i
].data_len
);
1601 if (!ctr
->values
[i
].data
)
1604 if (!prs_uint8s(False
, "data", ps
, depth
, ctr
->values
[i
].data
, ctr
->values
[i
].data_len
))
1608 current_offset
= data_offset
+ ctr
->values
[i
].data_len
- basic_unit
;
1609 /* account for 2 byte alignment */
1610 current_offset
+= (current_offset
% 2);
1612 /* Remember how far we got. */
1613 data_offset
= prs_offset(ps
);
1616 if (!prs_set_offset(ps
, return_offset
))
1621 /* Go to the last data offset we got to. */
1623 if (!prs_set_offset(ps
, data_offset
))
1626 /* And ensure we're 2 byte aligned. */
1628 if ( !prs_align_uint16(ps
) )
1634 /*******************************************************************
1635 * write a structure.
1636 ********************************************************************/
1638 bool spoolss_io_r_enumprinterdataex(const char *desc
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
, prs_struct
*ps
, int depth
)
1640 uint32 data_offset
, end_offset
;
1641 prs_debug(ps
, depth
, desc
, "spoolss_io_r_enumprinterdataex");
1647 if (!prs_uint32("size", ps
, depth
, &r_u
->ctr
.size
))
1650 data_offset
= prs_offset(ps
);
1652 if (!prs_set_offset(ps
, data_offset
+ r_u
->ctr
.size
))
1658 if(!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
1661 if(!prs_uint32("returned", ps
, depth
, &r_u
->returned
))
1664 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
1667 r_u
->ctr
.size_of_array
= r_u
->returned
;
1669 end_offset
= prs_offset(ps
);
1671 if (!prs_set_offset(ps
, data_offset
))
1675 if (!spoolss_io_printer_enum_values_ctr("", ps
, &r_u
->ctr
, depth
))
1678 if (!prs_set_offset(ps
, end_offset
))