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 /*******************************************************************
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
)
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
);
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
)
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"));
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");
323 if(!prs_uint32("valuesize", ps
, depth
, &r_u
->valuesize
))
326 if (UNMARSHALLING(ps
) && r_u
->valuesize
) {
327 r_u
->value
= PRS_ALLOC_MEM(ps
, uint16
, r_u
->valuesize
);
329 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata value\n"));
334 if(!prs_uint16uni(False
, "value", ps
, depth
, r_u
->value
, r_u
->valuesize
))
340 if(!prs_uint32("realvaluesize", ps
, depth
, &r_u
->realvaluesize
))
343 if(!prs_uint32("type", ps
, depth
, &r_u
->type
))
346 if(!prs_uint32("datasize", ps
, depth
, &r_u
->datasize
))
349 if (UNMARSHALLING(ps
) && r_u
->datasize
) {
350 r_u
->data
= PRS_ALLOC_MEM(ps
, uint8
, r_u
->datasize
);
352 DEBUG(0, ("spoolss_io_r_enumprinterdata: out of memory for printerdata data\n"));
357 if(!prs_uint8s(False
, "data", ps
, depth
, r_u
->data
, r_u
->datasize
))
362 if(!prs_uint32("realdatasize", ps
, depth
, &r_u
->realdatasize
))
364 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
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");
380 if(!smb_io_pol_hnd("printer handle",&q_u
->handle
,ps
,depth
))
382 if(!prs_uint32("index", ps
, depth
, &q_u
->index
))
384 if(!prs_uint32("valuesize", ps
, depth
, &q_u
->valuesize
))
386 if(!prs_uint32("datasize", ps
, depth
, &q_u
->datasize
))
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
));
401 q_u
->valuesize
=valuelen
;
402 q_u
->datasize
=datalen
;
407 /*******************************************************************
408 ********************************************************************/
410 bool make_spoolss_q_enumprinterdataex(SPOOL_Q_ENUMPRINTERDATAEX
*q_u
,
411 const POLICY_HND
*hnd
, const char *key
,
414 memcpy(&q_u
->handle
, hnd
, sizeof(q_u
->handle
));
415 init_unistr2(&q_u
->key
, key
, UNI_STR_TERMINATE
);
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
;
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");
446 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
448 if(!smb_io_unistr2("", &q_u
->value
, True
, ps
, depth
))
454 if(!prs_uint32("type", ps
, depth
, &q_u
->type
))
457 if(!prs_uint32("max_len", ps
, depth
, &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
)
471 if(!prs_uint8s(False
,"data", ps
, depth
, q_u
->data
, q_u
->max_len
))
479 if(!prs_uint32("real_len", ps
, depth
, &q_u
->real_len
))
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");
495 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
501 /*******************************************************************
503 ********************************************************************/
504 bool make_spoolss_q_enumprinterkey(SPOOL_Q_ENUMPRINTERKEY
*q_u
,
505 POLICY_HND
*hnd
, const char *key
,
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
);
517 /*******************************************************************
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");
528 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
531 if(!smb_io_unistr2("", &q_u
->key
, True
, ps
, depth
))
537 if(!prs_uint32("size", ps
, depth
, &q_u
->size
))
543 /*******************************************************************
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");
555 if (!smb_io_buffer5("", &r_u
->keys
, ps
, depth
))
561 if(!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
564 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
570 /*******************************************************************
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");
581 if(!smb_io_pol_hnd("printer handle", &q_u
->handle
, ps
, depth
))
584 if(!smb_io_unistr2("", &q_u
->key
, True
, ps
, depth
))
590 if(!prs_uint32("size", ps
, depth
, &q_u
->size
))
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
)
603 uint32 valuename_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");
612 * offset data begins at 20 bytes per structure * size_of_array.
613 * Don't forget the uint32 at the beginning
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
);
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
))
635 /* Read or write the value. */
637 return_offset
= prs_offset(ps
);
639 if (!prs_set_offset(ps
, base_offset
+ valuename_offset
)) {
643 if (!prs_unistr("valuename", ps
, depth
, &ctr
->values
[i
].valuename
))
647 if (!prs_set_offset(ps
, return_offset
))
650 if (!prs_uint32("value_len", ps
, depth
, &ctr
->values
[i
].value_len
))
653 if (!prs_uint32("type", ps
, depth
, &ctr
->values
[i
].type
))
656 data_offset
= ctr
->values
[i
].value_len
+ valuename_offset
;
658 if (!prs_uint32("data_offset", ps
, depth
, &data_offset
))
661 if (!prs_uint32("data_len", ps
, depth
, &ctr
->values
[i
].data_len
))
664 /* Read or write the data. */
666 return_offset
= prs_offset(ps
);
668 if (!prs_set_offset(ps
, base_offset
+ data_offset
)) {
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
)
678 if (!prs_uint8s(False
, "data", ps
, depth
, ctr
->values
[i
].data
, ctr
->values
[i
].data_len
))
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
);
690 if (!prs_set_offset(ps
, return_offset
))
695 /* Go to the last data offset we got to. */
697 if (!prs_set_offset(ps
, data_offset
))
700 /* And ensure we're 2 byte aligned. */
702 if ( !prs_align_uint16(ps
) )
708 /*******************************************************************
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");
721 if (!prs_uint32("size", ps
, depth
, &r_u
->ctr
.size
))
724 data_offset
= prs_offset(ps
);
726 if (!prs_set_offset(ps
, data_offset
+ r_u
->ctr
.size
))
732 if(!prs_uint32("needed", ps
, depth
, &r_u
->needed
))
735 if(!prs_uint32("returned", ps
, depth
, &r_u
->returned
))
738 if(!prs_werror("status", ps
, depth
, &r_u
->status
))
741 r_u
->ctr
.size_of_array
= r_u
->returned
;
743 end_offset
= prs_offset(ps
);
745 if (!prs_set_offset(ps
, data_offset
))
749 if (!spoolss_io_printer_enum_values_ctr("", ps
, &r_u
->ctr
, depth
))
752 if (!prs_set_offset(ps
, end_offset
))