1 /* packet-dcerpc-spoolss.c
2  * Routines for SMB \PIPE\spoolss packet disassembly
3  * Copyright 2001-2003, Tim Potter <tpot@samba.org>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 /* TODO list:
13 
14  - audit of item lengths
15 
16 */
17 
18 #include "config.h"
19 
20 
21 #include <epan/packet.h>
22 #include <epan/expert.h>
23 #include "packet-dcerpc.h"
24 #include "packet-dcerpc-nt.h"
25 #include "packet-dcerpc-spoolss.h"
26 #include "packet-windows-common.h"
27 
28 void proto_register_dcerpc_spoolss(void);
29 void proto_reg_handoff_dcerpc_spoolss(void);
30 
31 /* GetPrinterDriver2 */
32 
33 static int hf_clientmajorversion = -1;
34 static int hf_clientminorversion = -1;
35 static int hf_servermajorversion = -1;
36 static int hf_serverminorversion = -1;
37 static int hf_driverpath = -1;
38 static int hf_datafile = -1;
39 static int hf_configfile = -1;
40 static int hf_helpfile = -1;
41 static int hf_monitorname = -1;
42 static int hf_defaultdatatype = -1;
43 static int hf_driverinfo_cversion = -1;
44 static int hf_dependentfiles = -1;
45 static int hf_previousdrivernames = -1;
46 static int hf_color_profiles = -1;
47 static int hf_core_driver_dependencies = -1;
48 static int hf_driverdate = -1;
49 static int hf_min_inbox_driverdate = -1;
50 static int hf_padding = -1;
51 static int hf_driver_version_low = -1;
52 static int hf_driver_version_high = -1;
53 static int hf_min_inbox_driver_version_low = -1;
54 static int hf_min_inbox_driver_version_high = -1;
55 static int hf_mfgname = -1;
56 static int hf_oemurl = -1;
57 static int hf_hardwareid= -1;
58 static int hf_provider = -1;
59 
60 /* GetPrinter */
61 
62 /* Times */
63 
64 static int hf_start_time = -1;
65 static int hf_end_time = -1;
66 static int hf_elapsed_time = -1;
67 static int hf_device_not_selected_timeout = -1;
68 static int hf_transmission_retry_timeout = -1;
69 
70 /****************************************************************************/
71 
72 /*
73  * New hf index values - I'm in the process of doing a bit of a cleanup -tpot
74  */
75 
76 static int hf_opnum = -1;
77 static int hf_hnd = -1;
78 static int hf_rc = -1;
79 static int hf_hresult = -1;
80 static int hf_offered = -1;
81 static int hf_needed = -1;
82 static int hf_returned = -1;
83 static int hf_buffer_size = -1;
84 static int hf_buffer_data = -1;
85 static int hf_string_parm_size = -1;
86 static int hf_string_parm_data= -1;
87 static int hf_offset = -1;
88 static int hf_level = -1;
89 static int hf_access_required = -1;
90 
91 static int hf_printername = -1;
92 static int hf_machinename = -1;
93 static int hf_notifyname = -1;
94 static int hf_printerdesc = -1;
95 static int hf_printercomment = -1;
96 static int hf_servername = -1;
97 static int hf_sharename = -1;
98 static int hf_portname = -1;
99 static int hf_printerlocation = -1;
100 static int hf_drivername = -1;
101 static int hf_environment = -1;
102 static int hf_username = -1;
103 static int hf_documentname = -1;
104 static int hf_outputfile = -1;
105 static int hf_datatype = -1;
106 static int hf_textstatus = -1;
107 static int hf_sepfile = -1;
108 static int hf_printprocessor = -1;
109 static int hf_vendor_setup = -1;
110 static int hf_inf_path = -1;
111 static int hf_parameters = -1;
112 static int hf_core_printer_driver_ids = -1;
113 static int hf_core_driver_guid = -1;
114 static int hf_core_driver_size = -1;
115 static int hf_driver_version = -1;
116 static int hf_core_printer_driver_count = -1;
117 static int hf_package_id = -1;
118 static int hf_language = -1;
119 static int hf_driver_package_cab_size = -1;
120 
121 /* Printer information */
122 
123 static int hf_printer_cjobs = -1;
124 static int hf_printer_total_jobs = -1;
125 static int hf_printer_total_bytes = -1;
126 static int hf_printer_global_counter = -1;
127 static int hf_printer_total_pages = -1;
128 static int hf_printer_major_version = -1;
129 static int hf_printer_build_version = -1;
130 static int hf_printer_unk7 = -1;
131 static int hf_printer_unk8 = -1;
132 static int hf_printer_unk9 = -1;
133 static int hf_printer_session_ctr = -1;
134 static int hf_printer_unk11 = -1;
135 static int hf_printer_printer_errors = -1;
136 static int hf_printer_unk13 = -1;
137 static int hf_printer_unk14 = -1;
138 static int hf_printer_unk15 = -1;
139 static int hf_printer_unk16 = -1;
140 static int hf_printer_changeid = -1;
141 static int hf_printer_unk18 = -1;
142 static int hf_printer_unk20 = -1;
143 static int hf_printer_c_setprinter = -1;
144 static int hf_printer_unk22 = -1;
145 static int hf_printer_unk23 = -1;
146 static int hf_printer_unk24 = -1;
147 static int hf_printer_unk25 = -1;
148 static int hf_printer_unk26 = -1;
149 static int hf_printer_unk27 = -1;
150 static int hf_printer_unk28 = -1;
151 static int hf_printer_unk29 = -1;
152 static int hf_printer_flags = -1;
153 static int hf_printer_priority = -1;
154 static int hf_printer_default_priority = -1;
155 static int hf_printer_jobs = -1;
156 static int hf_printer_averageppm = -1;
157 static int hf_printer_guid = -1;
158 static int hf_printer_action = -1;
159 
160 /* Printer data */
161 
162 static int hf_printerdata = -1;
163 static int hf_printerdata_key = -1;
164 static int hf_printerdata_value = -1;
165 static int hf_printerdata_type = -1;
166 static int hf_printerdata_size = -1; /* Length of printer data */
167 static int hf_printerdata_data = -1;
168 static int hf_printerdata_data_sz = -1;
169 static int hf_printerdata_data_dword = -1;
170 
171 /* Devicemode */
172 
173 static int hf_devmodectr_size = -1;
174 
175 static int hf_devmode = -1;
176 static int hf_devmode_size = -1;
177 static int hf_devmode_spec_version = -1;
178 static int hf_devmode_driver_version = -1;
179 static int hf_devmode_size2 = -1;
180 static int hf_devmode_driver_extra_len = -1;
181 static int hf_devmode_fields = -1;
182 static int hf_devmode_orientation = -1;
183 static int hf_devmode_paper_size = -1;
184 static int hf_devmode_paper_width = -1;
185 static int hf_devmode_paper_length = -1;
186 static int hf_devmode_scale = -1;
187 static int hf_devmode_copies = -1;
188 static int hf_devmode_default_source = -1;
189 static int hf_devmode_print_quality = -1;
190 static int hf_devmode_color = -1;
191 static int hf_devmode_duplex = -1;
192 static int hf_devmode_y_resolution = -1;
193 static int hf_devmode_tt_option = -1;
194 static int hf_devmode_collate = -1;
195 static int hf_devmode_log_pixels = -1;
196 static int hf_devmode_bits_per_pel = -1;
197 static int hf_devmode_pels_width = -1;
198 static int hf_devmode_pels_height = -1;
199 static int hf_devmode_display_flags = -1;
200 static int hf_devmode_display_freq = -1;
201 static int hf_devmode_icm_method = -1;
202 static int hf_devmode_icm_intent = -1;
203 static int hf_devmode_media_type = -1;
204 static int hf_devmode_dither_type = -1;
205 static int hf_devmode_reserved1 = -1;
206 static int hf_devmode_reserved2 = -1;
207 static int hf_devmode_panning_width = -1;
208 static int hf_devmode_panning_height = -1;
209 static int hf_devmode_driver_extra = -1;
210 
211 static int hf_devmode_fields_orientation = -1;
212 static int hf_devmode_fields_papersize = -1;
213 static int hf_devmode_fields_paperlength = -1;
214 static int hf_devmode_fields_paperwidth = -1;
215 static int hf_devmode_fields_scale = -1;
216 static int hf_devmode_fields_position = -1;
217 static int hf_devmode_fields_nup = -1;
218 static int hf_devmode_fields_copies = -1;
219 static int hf_devmode_fields_defaultsource = -1;
220 static int hf_devmode_fields_printquality = -1;
221 static int hf_devmode_fields_color = -1;
222 static int hf_devmode_fields_duplex = -1;
223 static int hf_devmode_fields_yresolution = -1;
224 static int hf_devmode_fields_ttoption = -1;
225 static int hf_devmode_fields_collate = -1;
226 static int hf_devmode_fields_formname = -1;
227 static int hf_devmode_fields_logpixels = -1;
228 static int hf_devmode_fields_bitsperpel = -1;
229 static int hf_devmode_fields_pelswidth = -1;
230 static int hf_devmode_fields_pelsheight = -1;
231 static int hf_devmode_fields_displayflags = -1;
232 static int hf_devmode_fields_displayfrequency = -1;
233 static int hf_devmode_fields_icmmethod = -1;
234 static int hf_devmode_fields_icmintent = -1;
235 static int hf_devmode_fields_mediatype = -1;
236 static int hf_devmode_fields_dithertype = -1;
237 static int hf_devmode_fields_panningwidth = -1;
238 static int hf_devmode_fields_panningheight = -1;
239 
240 /* Print job */
241 
242 static int hf_job_id = -1;
243 static int hf_job_priority = -1;
244 static int hf_job_position = -1;
245 static int hf_job_totalpages = -1;
246 static int hf_job_totalbytes = -1;
247 static int hf_job_pagesprinted = -1;
248 static int hf_job_bytesprinted = -1;
249 static int hf_job_size = -1;
250 
251 static int hf_job_status = -1;
252 static int hf_job_status_paused = -1;
253 static int hf_job_status_error = -1;
254 static int hf_job_status_deleting = -1;
255 static int hf_job_status_spooling = -1;
256 static int hf_job_status_printing = -1;
257 static int hf_job_status_offline = -1;
258 static int hf_job_status_paperout = -1;
259 static int hf_job_status_printed = -1;
260 static int hf_job_status_deleted = -1;
261 static int hf_job_status_blocked = -1;
262 static int hf_job_status_user_intervention = -1;
263 
264 /* Forms */
265 
266 static int hf_form = -1;
267 static int hf_form_level = -1;
268 static int hf_form_name = -1;
269 static int hf_form_flags = -1;
270 static int hf_form_unknown = -1;
271 static int hf_form_width = -1;
272 static int hf_form_height = -1;
273 static int hf_form_left_margin = -1;
274 static int hf_form_top_margin = -1;
275 static int hf_form_horiz_len = -1;
276 static int hf_form_vert_len = -1;
277 
278 static int hf_enumforms_num = -1;
279 
280 /* Print notify */
281 
282 static int hf_notify_options_version = -1;
283 static int hf_notify_options_flags = -1;
284 static int hf_notify_options_flags_refresh = -1;
285 static int hf_notify_options_count = -1;
286 static int hf_notify_option_type = -1;
287 static int hf_notify_option_reserved1 = -1;
288 static int hf_notify_option_reserved2 = -1;
289 static int hf_notify_option_reserved3 = -1;
290 static int hf_notify_option_count = -1;
291 static int hf_notify_option_data_count = -1;
292 static int hf_notify_info_count = -1;
293 static int hf_notify_info_version = -1;
294 static int hf_notify_info_flags = -1;
295 static int hf_notify_info_data_type = -1;
296 static int hf_notify_info_data_count = -1;
297 static int hf_notify_info_data_id = -1;
298 static int hf_notify_info_data_value1 = -1;
299 static int hf_notify_info_data_value2 = -1;
300 static int hf_notify_info_data_bufsize = -1;
301 static int hf_notify_info_data_buffer = -1;
302 static int hf_notify_info_data_buffer_len = -1;
303 static int hf_notify_info_data_buffer_data = -1;
304 
305 static int hf_notify_field = -1;
306 
307 static int hf_printerlocal = -1;
308 
309 static int hf_rrpcn_changelow = -1;
310 static int hf_rrpcn_changehigh = -1;
311 static int hf_rrpcn_unk0 = -1;
312 static int hf_rrpcn_unk1 = -1;
313 
314 static int hf_replyopenprinter_unk0 = -1;
315 static int hf_replyopenprinter_unk1 = -1;
316 
317 static int hf_devmode_devicename = -1;
318 static int hf_devmode_form_name = -1;
319 static int hf_relative_string = -1;
320 static int hf_value_name = -1;
321 static int hf_keybuffer = -1;
322 static int hf_value_string = -1;
323 
324 static expert_field ei_unimplemented_dissector = EI_INIT;
325 static expert_field ei_unknown_data = EI_INIT;
326 static expert_field ei_spool_printer_info_level = EI_INIT;
327 static expert_field ei_printer_info_level = EI_INIT;
328 static expert_field ei_form_level = EI_INIT;
329 static expert_field ei_job_info_level = EI_INIT;
330 static expert_field ei_driver_info_level = EI_INIT;
331 static expert_field ei_level = EI_INIT;
332 static expert_field ei_notify_info_data_type = EI_INIT;
333 static expert_field ei_enumprinterdataex_value = EI_INIT;
334 static expert_field ei_buffer_size_too_long = EI_INIT;
335 
336 /* Registry data types */
337 
338 #define DCERPC_REG_NONE                        0
339 #define DCERPC_REG_SZ                          1
340 #define DCERPC_REG_EXPAND_SZ                   2
341 #define DCERPC_REG_BINARY                      3
342 #define DCERPC_REG_DWORD                       4
343 #define DCERPC_REG_DWORD_LE                    4        /* DWORD, little endian
344 */
345 #define DCERPC_REG_DWORD_BE                    5        /* DWORD, big endian */
346 #define DCERPC_REG_LINK                        6
347 #define DCERPC_REG_MULTI_SZ                    7
348 #define DCERPC_REG_RESOURCE_LIST               8
349 #define DCERPC_REG_FULL_RESOURCE_DESCRIPTOR    9
350 #define DCERPC_REG_RESOURCE_REQUIREMENTS_LIST 10
351 
352 static const value_string reg_datatypes[] = {
353 	{ DCERPC_REG_NONE, "REG_NONE" },
354 	{ DCERPC_REG_SZ, "REG_SZ" },
355 	{ DCERPC_REG_EXPAND_SZ, "REG_EXPAND_SZ" },
356 	{ DCERPC_REG_BINARY, "REG_BINARY" },
357 	{ DCERPC_REG_DWORD, "REG_DWORD" },
358 /*	  { DCERPC_REG_DWORD_LE, "REG_DWORD_LE" }, */
359 	{ DCERPC_REG_DWORD_BE, "REG_DWORD_BE" },
360 	{ DCERPC_REG_LINK, "REG_LINK" },
361 	{ DCERPC_REG_MULTI_SZ, "REG_MULTI_SZ" },
362 	{ DCERPC_REG_RESOURCE_LIST, "REG_RESOURCE_LIST" },
363 	{ DCERPC_REG_FULL_RESOURCE_DESCRIPTOR, "REG_FULL_RESOURCE_DESCRIPTOR" },
364 	{ DCERPC_REG_RESOURCE_REQUIREMENTS_LIST, "REG_RESOURCE_REQUIREMENTS_LIST" },
365 	{0, NULL }
366 };
367 static value_string_ext reg_datatypes_ext = VALUE_STRING_EXT_INIT(reg_datatypes);
368 
369 /****************************************************************************/
370 
371 /*
372  * Dissect SPOOLSS specific access rights
373  */
374 
375 static int hf_server_access_admin = -1;
376 static int hf_server_access_enum = -1;
377 static int hf_printer_access_admin = -1;
378 static int hf_printer_access_use = -1;
379 static int hf_job_access_admin = -1;
380 
381 static void
spoolss_printer_specific_rights(tvbuff_t * tvb,gint offset,proto_tree * tree,guint32 access)382 spoolss_printer_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree,
383 				guint32 access)
384 {
385 	proto_tree_add_boolean(
386 		tree, hf_printer_access_use, tvb, offset, 4, access);
387 
388 	proto_tree_add_boolean(
389 		tree, hf_printer_access_admin, tvb, offset, 4, access);
390 }
391 
392 struct access_mask_info spoolss_printer_access_mask_info = {
393 	"SPOOLSS printer",
394 	spoolss_printer_specific_rights,
395 	NULL,			/* Generic mapping table */
396 	NULL			/* Standard mapping table */
397 };
398 
399 static void
spoolss_printserver_specific_rights(tvbuff_t * tvb,gint offset,proto_tree * tree,guint32 access)400 spoolss_printserver_specific_rights(tvbuff_t *tvb, gint offset,
401 				    proto_tree *tree, guint32 access)
402 {
403 	proto_tree_add_boolean(
404 		tree, hf_server_access_enum, tvb, offset, 4, access);
405 
406 	proto_tree_add_boolean(
407 		tree, hf_server_access_admin, tvb, offset, 4, access);
408 }
409 
410 static struct access_mask_info spoolss_printserver_access_mask_info = {
411 	"SPOOLSS print server",
412 	spoolss_printserver_specific_rights,
413 	NULL,			/* Generic mapping table */
414 	NULL			/* Standard mapping table */
415 };
416 
417 static void
spoolss_job_specific_rights(tvbuff_t * tvb,gint offset,proto_tree * tree,guint32 access)418 spoolss_job_specific_rights(tvbuff_t *tvb, gint offset,
419 			    proto_tree *tree, guint32 access)
420 {
421 	proto_tree_add_boolean(
422 		tree, hf_job_access_admin, tvb, offset, 4, access);
423 }
424 
425 static struct access_mask_info spoolss_job_access_mask_info = {
426 	"SPOOLSS job",
427 	spoolss_job_specific_rights,
428 	NULL,			/* Generic mapping table */
429 	NULL			/* Standard mapping table */
430 };
431 
432 /*
433  * Routines to dissect a spoolss BUFFER
434  */
435 
436 typedef struct {
437 	tvbuff_t *tvb;
438 	proto_item *tree;	/* Proto tree buffer located in */
439 	proto_item *item;
440 } BUFFER;
441 
442 static gint ett_BUFFER = -1;
443 
444 static int
dissect_spoolss_buffer_data(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)445 dissect_spoolss_buffer_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
446 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
447 {
448 	BUFFER *b = (BUFFER *)di->private_data;
449 	proto_item *item;
450 	guint32 size;
451 	const guint8 *data;
452 
453 	if (di->conformant_run)
454 		return offset;
455 
456 	/* Dissect size and data */
457 
458 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
459 				    hf_buffer_size, &size);
460 
461 	/* Before going any further, we must ensure the bytes
462 	   actually esist in the tvb */
463 	if ((guint32)tvb_reported_length_remaining(tvb, offset) < size) {
464 		expert_add_info(pinfo, tree, &ei_buffer_size_too_long);
465 		return offset;
466 	}
467 
468 	offset = dissect_ndr_uint8s(tvb, offset, pinfo, NULL, di, drep,
469 				    hf_buffer_data, size, &data);
470 
471 	item = proto_tree_add_item(
472 		tree, hf_buffer_data, tvb, offset - size,
473 		size, ENC_NA);
474 
475 	/* Return buffer info */
476 
477 	if (b) {
478 
479 		/* I'm not sure about this.  Putting the buffer into
480 		   its own tvb makes sense and the dissection code is
481 		   much clearer, but the data is a proper subset of
482 		   the actual tvb.  Not adding the new data source
483 		   makes the hex display confusing as it switches
484 		   between the 'DCERPC over SMB' tvb and the buffer
485 		   tvb with no visual cues as to what is going on. */
486 
487 		b->tvb = tvb_new_child_real_data(tvb, data, size, size);
488 		add_new_data_source(pinfo, b->tvb, "SPOOLSS buffer");
489 
490 		b->item = item;
491 		b->tree = proto_item_add_subtree(item, ett_BUFFER);
492 	}
493 
494 	return offset;
495 }
496 
497 /* Dissect a spoolss buffer and return buffer data */
498 
499 static int
dissect_spoolss_buffer(tvbuff_t * tvb,gint offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,BUFFER * b)500 dissect_spoolss_buffer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
501 		       proto_tree *tree, dcerpc_info *di, guint8 *drep, BUFFER *b)
502 {
503 	if (b)
504 		memset(b, 0, sizeof(BUFFER));
505 
506 	di->private_data = b;
507 
508 	offset = dissect_ndr_pointer(
509 		tvb, offset, pinfo, tree, di, drep,
510 		dissect_spoolss_buffer_data, NDR_POINTER_UNIQUE,
511 		"Buffer", -1);
512 
513 	return offset;
514 }
515 
516 static int
dissect_spoolss_string_parm_data(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)517 dissect_spoolss_string_parm_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
518 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
519 {
520 	guint32 buffer_len, len;
521 	gchar *s;
522 	proto_item *item = NULL;
523 
524 	if (di->conformant_run)
525 		return offset;
526 
527 	/* Dissect size and data */
528 
529 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
530 				hf_string_parm_size, &buffer_len);
531 
532 	s = tvb_get_stringz_enc(pinfo->pool, tvb, offset, &len, ENC_UTF_16|ENC_LITTLE_ENDIAN);
533 
534 	if (tree && buffer_len) {
535 		tvb_ensure_bytes_exist(tvb, offset, buffer_len);
536 
537 		item = proto_tree_add_string(
538 			tree, hf_string_parm_data, tvb, offset, len, s);
539 	}
540 	offset += buffer_len;
541 
542 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", s);
543 
544 	/* Append string to upper level item */
545 	if (tree && item) {
546 		item = item->parent != NULL ? item->parent : item;
547 		proto_item_append_text(item, ": %s", s);
548 	}
549 
550 	return offset;
551 }
552 
553 /* Dissect a spoolss string parameter */
554 
555 static int
dissect_spoolss_string_parm(tvbuff_t * tvb,gint offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,const char * text)556 dissect_spoolss_string_parm(tvbuff_t *tvb, gint offset, packet_info *pinfo,
557 		       proto_tree *tree, dcerpc_info *di, guint8 *drep, const char *text)
558 {
559 	offset = dissect_ndr_pointer(
560 		tvb, offset, pinfo, tree, di, drep,
561 		dissect_spoolss_string_parm_data, NDR_POINTER_UNIQUE,
562 		text, -1);
563 
564 	return offset;
565 }
566 
567 /*
568  * SYSTEM_TIME
569  */
570 
571 static gint ett_SYSTEM_TIME = -1;
572 
573 static int hf_time_year = -1;
574 static int hf_time_month = -1;
575 static int hf_time_dow = -1;
576 static int hf_time_day = -1;
577 static int hf_time_hour = -1;
578 static int hf_time_minute = -1;
579 static int hf_time_second = -1;
580 static int hf_time_msec = -1;
581 
582 static int
dissect_SYSTEM_TIME(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,const char * name,gboolean add_subtree,char ** data)583 dissect_SYSTEM_TIME(tvbuff_t *tvb, int offset, packet_info *pinfo,
584 		    proto_tree *tree, dcerpc_info *di, guint8 *drep, const char *name,
585 		    gboolean add_subtree, char **data)
586 {
587 	proto_item *item = NULL;
588 	proto_tree *subtree = tree;
589 	guint16 year, month, day, hour, minute, second, millisecond;
590 	char *str;
591 
592 	if (add_subtree) {
593 		subtree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_SYSTEM_TIME, &item, name);
594 	}
595 
596 	offset = dissect_ndr_uint16(
597 		tvb, offset, pinfo, subtree, di, drep, hf_time_year, &year);
598 
599 	offset = dissect_ndr_uint16(
600 		tvb, offset, pinfo, subtree, di, drep, hf_time_month, &month);
601 
602 	offset = dissect_ndr_uint16(
603 		tvb, offset, pinfo, subtree, di, drep, hf_time_dow, NULL);
604 
605 	offset = dissect_ndr_uint16(
606 		tvb, offset, pinfo, subtree, di, drep, hf_time_day, &day);
607 
608 	offset = dissect_ndr_uint16(
609 		tvb, offset, pinfo, subtree, di, drep, hf_time_hour, &hour);
610 
611 	offset = dissect_ndr_uint16(
612 		tvb, offset, pinfo, subtree, di, drep, hf_time_minute, &minute);
613 
614 	offset = dissect_ndr_uint16(
615 		tvb, offset, pinfo, subtree, di, drep, hf_time_second, &second);
616 
617 	offset = dissect_ndr_uint16(
618 		tvb, offset, pinfo, subtree, di, drep, hf_time_msec, &millisecond);
619 
620 	str = wmem_strdup_printf(pinfo->pool,
621 			      "%d/%02d/%02d %02d:%02d:%02d.%03d",
622 			      year, month, day, hour, minute, second,
623 			      millisecond);
624 
625 	if (add_subtree)
626 		proto_item_append_text(item, ": %s", str);
627 
628 	if (data)
629 		*data = str;
630 
631 	return offset;
632 }
633 
634 static int
dissect_SYSTEM_TIME_ptr(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)635 dissect_SYSTEM_TIME_ptr(tvbuff_t *tvb, int offset, packet_info *pinfo,
636 			proto_tree *tree, dcerpc_info *di, guint8 *drep)
637 {
638 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
639 	char *str;
640 
641 
642 	offset =  dissect_SYSTEM_TIME(
643 		tvb, offset, pinfo, tree, di, drep, NULL, FALSE, &str);
644 	dcv->private_data = wmem_strdup(wmem_file_scope(), str);
645 
646 	return offset;
647 }
648 
649 /*
650  * SpoolssClosePrinter
651  */
652 
653 static int
SpoolssClosePrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)654 SpoolssClosePrinter_q(tvbuff_t *tvb, int offset,
655 				 packet_info *pinfo, proto_tree *tree,
656 				 dcerpc_info *di, guint8 *drep)
657 {
658 	e_ctx_hnd policy_hnd;
659 	char *pol_name;
660 
661 	/* Parse packet */
662 
663 	offset = dissect_nt_policy_hnd(
664 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
665 		FALSE, TRUE);
666 
667 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
668 			     pinfo->num);
669 
670 	if (pol_name)
671 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
672 				pol_name);
673 
674 	return offset;
675 }
676 
677 static int
SpoolssClosePrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)678 SpoolssClosePrinter_r(tvbuff_t *tvb, int offset,
679 				 packet_info *pinfo, proto_tree *tree,
680 				 dcerpc_info *di, guint8 *drep)
681 {
682 	/* Parse packet */
683 
684 	offset = dissect_nt_policy_hnd(
685 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
686 		FALSE, FALSE);
687 
688 
689 	offset = dissect_doserror(
690 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
691 
692 	return offset;
693 }
694 
695 /* Dissect some printer data.  The get/set/enum printerdata routines all
696    store value/data in a uint8 array.  We could use the ndr routines for
697    this but that would result in one item for each byte in the printer
698    data. */
699 
700 static gint ett_printerdata_data = -1;
701 static gint ett_printerdata_value = -1;
702 
703 static int
dissect_printerdata_data(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,guint32 type)704 dissect_printerdata_data(tvbuff_t *tvb, int offset,
705 				    packet_info *pinfo, proto_tree *tree,
706 				    dcerpc_info *di, guint8 *drep, guint32 type)
707 {
708 	proto_item *item, *hidden_item;
709 	proto_tree *subtree;
710 	guint32 size;
711 
712 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_printerdata_data, &item, "Data");
713 
714 	offset = dissect_ndr_uint32(
715 		tvb, offset, pinfo, subtree, di, drep, hf_printerdata_size, &size);
716 
717 	if (size) {
718 
719 		offset = dissect_ndr_uint8s(
720 			tvb, offset, pinfo, subtree, di, drep,
721 			hf_printerdata_data, size, NULL);
722 
723 		switch(type) {
724 		case DCERPC_REG_SZ: {
725 			const guint8 *data;
726 
727 			hidden_item = proto_tree_add_item_ret_string(
728 				tree, hf_printerdata_data_sz, tvb,
729 				offset - size, size, ENC_UTF_16|ENC_LITTLE_ENDIAN, pinfo->pool, &data);
730 			proto_item_set_hidden(hidden_item);
731 
732 			proto_item_append_text(item, ": %s", data);
733 
734 			col_append_fstr(pinfo->cinfo, COL_INFO, " = %s", data);
735 			break;
736 		}
737 		case DCERPC_REG_DWORD: {
738 			guint32 data = tvb_get_letohl(tvb, offset - size);
739 
740 			proto_item_append_text(item, ": 0x%08x", data);
741 
742 			col_append_fstr(
743 					pinfo->cinfo, COL_INFO, " = 0x%08x",
744 					data);
745 
746 			hidden_item = proto_tree_add_uint(
747 				tree, hf_printerdata_data_dword, tvb,
748 				offset - size, 4, data);
749 			proto_item_set_hidden(hidden_item);
750 
751 			break;
752 		}
753 		case DCERPC_REG_BINARY:
754 			col_append_str(
755 					pinfo->cinfo, COL_INFO,
756 					" = <binary data>");
757 			break;
758 
759 		default:
760 			break;
761 		}
762 	}
763 
764 	proto_item_set_len(item, size + 4);
765 
766 	return offset;
767 }
768 
769 /*
770  * SpoolssGetPrinterData
771  */
772 
773 static int
SpoolssGetPrinterData_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)774 SpoolssGetPrinterData_q(tvbuff_t *tvb, int offset,
775 				   packet_info *pinfo, proto_tree *tree,
776 				   dcerpc_info *di, guint8 *drep)
777 {
778 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
779 	char *value_name;
780 	proto_item *hidden_item;
781 
782 	hidden_item = proto_tree_add_uint(
783 		tree, hf_printerdata, tvb, offset, 0, 1);
784 	proto_item_set_hidden(hidden_item);
785 
786 	/* Parse packet */
787 
788 	offset = dissect_nt_policy_hnd(
789 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
790 		FALSE, FALSE);
791 
792 
793 	value_name = NULL;
794  	offset = dissect_ndr_cvstring(
795  		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
796 		hf_printerdata_value, TRUE, &value_name);
797 	/* GetPrinterData() stores the printerdata in se_data */
798 	if(!pinfo->fd->visited){
799 		if(!dcv->se_data && value_name){
800 			dcv->se_data = wmem_strdup(wmem_file_scope(), value_name);
801 		}
802 	}
803 
804 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", value_name);
805 
806 	offset = dissect_ndr_uint32(
807 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
808 
809 	return offset;
810 }
811 
812 static int
SpoolssGetPrinterData_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)813 SpoolssGetPrinterData_r(tvbuff_t *tvb, int offset,
814 				   packet_info *pinfo, proto_tree *tree,
815 				   dcerpc_info *di, guint8 *drep)
816 {
817 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
818 	guint32 type;
819 	proto_item *hidden_item;
820 	const char *data;
821 
822 	hidden_item = proto_tree_add_uint(
823 		tree, hf_printerdata, tvb, offset, 0, 1);
824 	proto_item_set_hidden(hidden_item);
825 
826 	/* Parse packet */
827 
828 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
829 				    hf_printerdata_type, &type);
830 
831 	data = (const char *)(dcv->se_data ? dcv->se_data : "????");
832 
833 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", data);
834 
835 	offset = dissect_printerdata_data(
836 		tvb, offset, pinfo, tree, di, drep, type);
837 
838 	offset = dissect_ndr_uint32(
839 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
840 
841 	offset = dissect_doserror(
842 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
843 
844 	return offset;
845 }
846 
847 /*
848  * SpoolssGetPrinterDataEx
849  */
850 
851 static int
SpoolssGetPrinterDataEx_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)852 SpoolssGetPrinterDataEx_q(tvbuff_t *tvb, int offset,
853 				     packet_info *pinfo, proto_tree *tree,
854 				     dcerpc_info *di, guint8 *drep)
855 {
856 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
857 	char *key_name, *value_name;
858 	proto_item *hidden_item;
859 
860 	hidden_item = proto_tree_add_uint(
861 		tree, hf_printerdata, tvb, offset, 0, 1);
862 	proto_item_set_hidden(hidden_item);
863 
864 	/* Parse packet */
865 
866 	offset = dissect_nt_policy_hnd(
867 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
868 		FALSE, FALSE);
869 
870 	key_name=NULL;
871 	offset = dissect_ndr_cvstring(
872 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
873 		hf_printerdata_key, TRUE, &key_name);
874 
875 	value_name=NULL;
876 	offset = dissect_ndr_cvstring(
877 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
878 		hf_printerdata_value, TRUE, &value_name);
879 
880 	/* GetPrinterDataEx() stores the key/value in se_data */
881 	if(!pinfo->fd->visited){
882 		if(!dcv->se_data){
883 			dcv->se_data = wmem_strdup_printf(wmem_file_scope(),
884 				"%s==%s",
885 				key_name?key_name:"",
886 				value_name?value_name:"");
887 		}
888 	}
889 
890 	if (dcv->se_data)
891 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
892 				(char *)dcv->se_data);
893 
894 	offset = dissect_ndr_uint32(
895 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
896 
897 	return offset;
898 }
899 
900 static int
SpoolssGetPrinterDataEx_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)901 SpoolssGetPrinterDataEx_r(tvbuff_t *tvb, int offset,
902 				     packet_info *pinfo, proto_tree *tree,
903 				     dcerpc_info *di, guint8 *drep)
904 {
905 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
906 	guint32 size, type;
907 	proto_item *hidden_item;
908 
909 	hidden_item = proto_tree_add_uint(
910 		tree, hf_printerdata, tvb, offset, 0, 1);
911 	proto_item_set_hidden(hidden_item);
912 
913 	/* Parse packet */
914 
915 	offset = dissect_ndr_uint32(
916 		tvb, offset, pinfo, tree, di, drep, hf_printerdata_type, &type);
917 
918 	offset = dissect_ndr_uint32(
919 		tvb, offset, pinfo, tree, di, drep, hf_returned, &size);
920 
921 	if (dcv->se_data) {
922 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", (char *)dcv->se_data);
923 	}
924 
925 	if (size)
926 		dissect_printerdata_data(tvb, offset, pinfo, tree, di, drep, type);
927 
928 	offset += size;
929 
930 	offset = dissect_ndr_uint32(
931 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
932 
933 	offset = dissect_doserror(
934 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
935 
936 	return offset;
937 }
938 
939 /*
940  * SpoolssSetPrinterData
941  */
942 
943 static int
SpoolssSetPrinterData_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)944 SpoolssSetPrinterData_q(tvbuff_t *tvb, int offset,
945 				   packet_info *pinfo, proto_tree *tree,
946 				   dcerpc_info *di, guint8 *drep)
947 {
948 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
949 	char *value_name;
950 	guint32 type;
951 	proto_item *hidden_item;
952 
953 	hidden_item = proto_tree_add_uint(
954 		tree, hf_printerdata, tvb, offset, 0, 1);
955 	proto_item_set_hidden(hidden_item);
956 
957 	/* Parse packet */
958 
959 	offset = dissect_nt_policy_hnd(
960 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
961 		FALSE, FALSE);
962 
963 	value_name=NULL;
964 	offset = dissect_ndr_cvstring(
965 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
966 		hf_printerdata_value, TRUE, &value_name);
967 
968 	/* GetPrinterDataEx() stores the key/value in se_data */
969 	if(!pinfo->fd->visited){
970 		if(!dcv->se_data){
971 			dcv->se_data = wmem_strdup(wmem_file_scope(),
972 				value_name?value_name:"");
973 		}
974 	}
975 
976 
977 	if (dcv->se_data){
978 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", (char *)dcv->se_data);
979 	}
980 
981 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
982 				    hf_printerdata_type, &type);
983 
984 	offset = dissect_printerdata_data(
985 		tvb, offset, pinfo, tree, di, drep, type);
986 
987 	offset = dissect_ndr_uint32(
988 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
989 
990 	return offset;
991 }
992 
993 static int
SpoolssSetPrinterData_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)994 SpoolssSetPrinterData_r(tvbuff_t *tvb, int offset,
995 				   packet_info *pinfo, proto_tree *tree,
996 				   dcerpc_info *di, guint8 *drep)
997 {
998 	proto_item *hidden_item;
999 
1000 	hidden_item = proto_tree_add_uint(
1001 		tree, hf_printerdata, tvb, offset, 0, 1);
1002 	proto_item_set_hidden(hidden_item);
1003 
1004 	/* Parse packet */
1005 
1006 	offset = dissect_doserror(
1007 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
1008 
1009 	return offset;
1010 }
1011 
1012 /*
1013  * SpoolssSetPrinterDataEx
1014  */
1015 
1016 static int hf_setprinterdataex_max_len = -1;
1017 static int hf_setprinterdataex_real_len = -1;
1018 static int hf_setprinterdataex_data = -1;
1019 
1020 static int
SpoolssSetPrinterDataEx_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1021 SpoolssSetPrinterDataEx_q(tvbuff_t *tvb, int offset,
1022 				     packet_info *pinfo, proto_tree *tree,
1023 				     dcerpc_info *di, guint8 *drep)
1024 {
1025 	char *key_name, *value_name;
1026 	guint32 max_len;
1027 	proto_item *hidden_item;
1028 
1029 	hidden_item = proto_tree_add_uint(
1030 		tree, hf_printerdata, tvb, offset, 0, 1);
1031 	proto_item_set_hidden(hidden_item);
1032 
1033 	/* Parse packet */
1034 
1035 	offset = dissect_nt_policy_hnd(
1036 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
1037 		FALSE, FALSE);
1038 
1039 	offset = dissect_ndr_cvstring(
1040 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
1041 		hf_printerdata_key, TRUE, &key_name);
1042 
1043 	offset = dissect_ndr_cvstring(
1044 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
1045 		hf_printerdata_value, TRUE, &value_name);
1046 
1047 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s/%s",
1048 				key_name, value_name);
1049 
1050 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
1051 				    hf_printerdata_type, NULL);
1052 
1053 	offset = dissect_ndr_uint32(
1054 		tvb, offset, pinfo, tree, di, drep,
1055 		hf_setprinterdataex_max_len, &max_len);
1056 
1057 	offset = dissect_ndr_uint8s(
1058 		tvb, offset, pinfo, tree, di, drep,
1059 		hf_setprinterdataex_data, max_len, NULL);
1060 
1061 	offset = dissect_ndr_uint32(
1062 		tvb, offset, pinfo, tree, di, drep,
1063 		hf_setprinterdataex_real_len, NULL);
1064 
1065 	return offset;
1066 }
1067 
1068 static int
SpoolssSetPrinterDataEx_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1069 SpoolssSetPrinterDataEx_r(tvbuff_t *tvb, int offset,
1070 				     packet_info *pinfo, proto_tree *tree,
1071 				     dcerpc_info *di, guint8 *drep)
1072 {
1073 	proto_item *hidden_item;
1074 
1075 	hidden_item = proto_tree_add_uint(
1076 		tree, hf_printerdata, tvb, offset, 0, 1);
1077 	proto_item_set_hidden(hidden_item);
1078 
1079 	/* Parse packet */
1080 
1081 	offset = dissect_doserror(
1082 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
1083 
1084 	return offset;
1085 }
1086 
1087 /* XXX - "name" should be an hf_ value for an FT_STRING. */
1088 static int
dissect_spoolss_uint16uni(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,guint8 * drep _U_,char ** data,int hf_name)1089 dissect_spoolss_uint16uni(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
1090 			  proto_tree *tree, guint8 *drep _U_, char **data,
1091 			  int hf_name)
1092 {
1093 	gint len, remaining;
1094 	char *text;
1095 
1096 	if (offset % 2)
1097 		offset += 2 - (offset % 2);
1098 
1099 	/* Get remaining data in buffer as a string */
1100 
1101 	remaining = tvb_reported_length_remaining(tvb, offset);
1102 	if (remaining <= 0) {
1103 		if (data)
1104 			*data = wmem_strdup(pinfo->pool, "");
1105 		return offset;
1106 	}
1107 
1108 	text = tvb_get_string_enc(pinfo->pool, tvb, offset, remaining, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1109 	len = (int)strlen(text);
1110 
1111 	proto_tree_add_string(tree, hf_name, tvb, offset, len * 2, text);
1112 
1113 	if (data)
1114 		*data = text;
1115 
1116 	return offset + (len + 1) * 2;
1117 }
1118 
1119 /*
1120  * DEVMODE
1121  */
1122 
1123 /* Devicemode orientation values */
1124 
1125 static const value_string devmode_orientation_vals[] =
1126 {
1127 	{ DEVMODE_ORIENTATION_PORTRAIT, "Portrait" },
1128 	{ DEVMODE_ORIENTATION_LANDSCAPE, "Landscape" },
1129 	{ 0, NULL }
1130 };
1131 
1132 /* Paper size values.  International paper sizes is a fascinating
1133    topic.  No seriously!  (-: */
1134 
1135 static const value_string devmode_papersize_vals[] =
1136 {
1137 	{ DEVMODE_PAPERSIZE_LETTER, "Letter" },
1138 	{ DEVMODE_PAPERSIZE_LETTERSMALL, "Letter (small)" },
1139 	{ DEVMODE_PAPERSIZE_TABLOID, "Tabloid" },
1140 	{ DEVMODE_PAPERSIZE_LEDGER, "Ledger" },
1141 	{ DEVMODE_PAPERSIZE_LEGAL, "Legal" },
1142 	{ DEVMODE_PAPERSIZE_STATEMENT, "Statement" },
1143 	{ DEVMODE_PAPERSIZE_EXECUTIVE, "Executive" },
1144 	{ DEVMODE_PAPERSIZE_A3, "A3" },
1145 	{ DEVMODE_PAPERSIZE_A4, "A4" },
1146 	{ DEVMODE_PAPERSIZE_A4SMALL, "A4 (small)" },
1147 	{ DEVMODE_PAPERSIZE_A5, "A5" },
1148 	{ DEVMODE_PAPERSIZE_B4, "B4" },
1149 	{ DEVMODE_PAPERSIZE_B5, "B5" },
1150 	{ DEVMODE_PAPERSIZE_FOLIO, "Folio" },
1151 	{ DEVMODE_PAPERSIZE_QUARTO, "Quarto" },
1152 	{ DEVMODE_PAPERSIZE_10X14, "10x14" },
1153 	{ DEVMODE_PAPERSIZE_11X17, "11x17" },
1154 	{ DEVMODE_PAPERSIZE_NOTE, "Note" },
1155 	{ DEVMODE_PAPERSIZE_ENV9, "Envelope #9" },
1156 	{ DEVMODE_PAPERSIZE_ENV10, "Envelope #10" },
1157 	{ DEVMODE_PAPERSIZE_ENV11, "Envelope #11" },
1158 	{ DEVMODE_PAPERSIZE_ENV12, "Envelope #12" },
1159 	{ DEVMODE_PAPERSIZE_ENV14, "Envelope #14" },
1160 	{ DEVMODE_PAPERSIZE_CSHEET, "C sheet" },
1161 	{ DEVMODE_PAPERSIZE_DSHEET, "D sheet" },
1162 	{ DEVMODE_PAPERSIZE_ESHEET, "E sheet" },
1163 	{ DEVMODE_PAPERSIZE_ENVDL, "Envelope DL" },
1164 	{ DEVMODE_PAPERSIZE_ENVC5, "Envelope C5" },
1165 	{ DEVMODE_PAPERSIZE_ENVC3, "Envelope C3" },
1166 	{ DEVMODE_PAPERSIZE_ENVC4, "Envelope C4" },
1167 	{ DEVMODE_PAPERSIZE_ENVC6, "Envelope C6" },
1168 	{ DEVMODE_PAPERSIZE_ENVC65, "Envelope C65" },
1169 	{ DEVMODE_PAPERSIZE_ENVB4, "Envelope B4" },
1170 	{ DEVMODE_PAPERSIZE_ENVB5, "Envelope B5" },
1171 	{ DEVMODE_PAPERSIZE_ENVB6, "Envelope B6" },
1172 	{ DEVMODE_PAPERSIZE_ENVITALY, "Envelope (Italy)" },
1173 	{ DEVMODE_PAPERSIZE_ENVMONARCH, "Envelope (Monarch)" },
1174 	{ DEVMODE_PAPERSIZE_ENVPERSONAL, "Envelope (Personal)" },
1175 	{ DEVMODE_PAPERSIZE_FANFOLDUS, "Fanfold (US)" },
1176 	{ DEVMODE_PAPERSIZE_FANFOLDSTDGERMAN, "Fanfold (Std German)" },
1177 	{ DEVMODE_PAPERSIZE_FANFOLDLGLGERMAN, "Fanfold (Legal German)" },
1178 	{ DEVMODE_PAPERSIZE_ISOB4, "B4 (ISO)" },
1179 	{ DEVMODE_PAPERSIZE_JAPANESEPOSTCARD, "Japanese postcard" },
1180 	{ DEVMODE_PAPERSIZE_9X11, "9x11" },
1181 	{ DEVMODE_PAPERSIZE_10X11, "10x11" },
1182 	{ DEVMODE_PAPERSIZE_15X11, "15x11" },
1183 	{ DEVMODE_PAPERSIZE_ENVINVITE, "Envelope (Invite)" },
1184 	{ DEVMODE_PAPERSIZE_RESERVED48, "Reserved (48)" },
1185 	{ DEVMODE_PAPERSIZE_RESERVED49, "Reserved (49)" },
1186 	{ DEVMODE_PAPERSIZE_LETTEREXTRA, "Letter (Extra)" },
1187 	{ DEVMODE_PAPERSIZE_LEGALEXTRA, "Legal (Extra)" },
1188 	{ DEVMODE_PAPERSIZE_TABLOIDEXTRA, "Tabloid (Extra)" },
1189 	{ DEVMODE_PAPERSIZE_A4EXTRA, "A4 (Extra)" },
1190 	{ DEVMODE_PAPERSIZE_LETTERTRANS, "Letter (Transverse)" },
1191 	{ DEVMODE_PAPERSIZE_A4TRANS, "A4 (Transverse)" },
1192 	{ DEVMODE_PAPERSIZE_LETTEREXTRATRANS, "Letter (Extra, Transverse)" },
1193 	{ DEVMODE_PAPERSIZE_APLUS, "A+" },
1194 	{ DEVMODE_PAPERSIZE_BPLUS, "B+" },
1195 	{ DEVMODE_PAPERSIZE_LETTERPLUS, "Letter+" },
1196 	{ DEVMODE_PAPERSIZE_A4PLUS, "A4+" },
1197 	{ DEVMODE_PAPERSIZE_A5TRANS, "A5 (Transverse)" },
1198 	{ DEVMODE_PAPERSIZE_B5TRANS, "B5 (Transverse)" },
1199 	{ DEVMODE_PAPERSIZE_A3EXTRA, "A3 (Extra)" },
1200 	{ DEVMODE_PAPERSIZE_A5EXTRA, "A5 (Extra)" },
1201 	{ DEVMODE_PAPERSIZE_B5EXTRA, "B5 (Extra)" },
1202 	{ DEVMODE_PAPERSIZE_A2, "A2" },
1203 	{ DEVMODE_PAPERSIZE_A3TRANS, "A3 (Transverse)" },
1204 	{ DEVMODE_PAPERSIZE_A3EXTRATRANS, "A3 (Extra, Transverse" },
1205 	{ DEVMODE_PAPERSIZE_DBLJAPANESEPOSTCARD, "Double Japanese Postcard" },
1206 	{ DEVMODE_PAPERSIZE_A6, "A6" },
1207 	{ DEVMODE_PAPERSIZE_JENVKAKU2, "Japanese Envelope (Kaku #2)" },
1208 	{ DEVMODE_PAPERSIZE_JENVKAKU3, "Japanese Envelope (Kaku #3)" },
1209 	{ DEVMODE_PAPERSIZE_JENVCHOU3, "Japanese Envelope (Chou #3)" },
1210 	{ DEVMODE_PAPERSIZE_JENVCHOU4, "Japanese Envelope (Chou #4)" },
1211 	{ DEVMODE_PAPERSIZE_LETTERROT, "Letter (Rotated)" },
1212 	{ DEVMODE_PAPERSIZE_A3ROT, "A3 (Rotated)" },
1213 	{ DEVMODE_PAPERSIZE_A4ROT, "A4 (Rotated)" },
1214 	{ DEVMODE_PAPERSIZE_A5ROT, "A5 (Rotated)" },
1215 	{ DEVMODE_PAPERSIZE_B4JISROT, "B4 (JIS, Rotated)" },
1216 	{ DEVMODE_PAPERSIZE_B5JISROT, "B5 (JIS, Rotated)"},
1217 	{ DEVMODE_PAPERSIZE_JAPANESEPOSTCARDROT,
1218 	  "Japanese Postcard (Rotated)" },
1219 	{ DEVMODE_PAPERSIZE_DBLJAPANESEPOSTCARDROT82,
1220 	  "Double Japanese Postcard (Rotated)" },
1221 	{ DEVMODE_PAPERSIZE_A6ROT, "A6 (Rotated)" },
1222 	{ DEVMODE_PAPERSIZE_JENVKAKU2ROT,
1223 	  "Japanese Envelope (Kaku #2, Rotated)" },
1224 	{ DEVMODE_PAPERSIZE_JENVKAKU3ROT,
1225 	  "Japanese Envelope (Kaku #3, Rotated)" },
1226 	{ DEVMODE_PAPERSIZE_JENVCHOU3ROT,
1227 	  "Japanese Envelope (Chou #3, Rotated)" },
1228 	{ DEVMODE_PAPERSIZE_JENVCHOU4ROT,
1229 	  "Japanese Envelope (Chou #4, Rotated)" },
1230 	{ DEVMODE_PAPERSIZE_B6JIS, "B6 (JIS)" },
1231 	{ DEVMODE_PAPERSIZE_B6JISROT, "B6 (JIS, Rotated)" },
1232 	{ DEVMODE_PAPERSIZE_12X11, "12x11" },
1233 	{ DEVMODE_PAPERSIZE_JENVYOU4, "Japanese Envelope (You #4)" },
1234 	{ DEVMODE_PAPERSIZE_JENVYOU4ROT,
1235 	  "Japanese Envelope (You #4, Rotated" },
1236 	{ DEVMODE_PAPERSIZE_P16K, "PRC 16K" },
1237 	{ DEVMODE_PAPERSIZE_P32K, "PRC 32K" },
1238 	{ DEVMODE_PAPERSIZE_P32KBIG, "P32K (Big)" },
1239 	{ DEVMODE_PAPERSIZE_PENV1, "PRC Envelope #1" },
1240 	{ DEVMODE_PAPERSIZE_PENV2, "PRC Envelope #2" },
1241 	{ DEVMODE_PAPERSIZE_PENV3, "PRC Envelope #3" },
1242 	{ DEVMODE_PAPERSIZE_PENV4, "PRC Envelope #4" },
1243 	{ DEVMODE_PAPERSIZE_PENV5, "PRC Envelope #5" },
1244 	{ DEVMODE_PAPERSIZE_PENV6, "PRC Envelope #6" },
1245 	{ DEVMODE_PAPERSIZE_PENV7, "PRC Envelope #7" },
1246 	{ DEVMODE_PAPERSIZE_PENV8, "PRC Envelope #8" },
1247 	{ DEVMODE_PAPERSIZE_PENV9, "PRC Envelope #9" },
1248 	{ DEVMODE_PAPERSIZE_PENV10, "PRC Envelope #10" },
1249 	{ DEVMODE_PAPERSIZE_P16KROT, "PRC 16K (Rotated)" },
1250 	{ DEVMODE_PAPERSIZE_P32KROT, "PRC 32K (Rotated)" },
1251 	{ DEVMODE_PAPERSIZE_P32KBIGROT, "PRC 32K (Big, Rotated)" },
1252 	{ DEVMODE_PAPERSIZE_PENV1ROT, "PRC Envelope #1 (Rotated)" },
1253 	{ DEVMODE_PAPERSIZE_PENV2ROT, "PRC Envelope #2 (Rotated)" },
1254 	{ DEVMODE_PAPERSIZE_PENV3ROT, "PRC Envelope #3 (Rotated)" },
1255 	{ DEVMODE_PAPERSIZE_PENV4ROT, "PRC Envelope #4 (Rotated)" },
1256 	{ DEVMODE_PAPERSIZE_PENV5ROT, "PRC Envelope #5 (Rotated)" },
1257 	{ DEVMODE_PAPERSIZE_PENV6ROT, "PRC Envelope #6 (Rotated)" },
1258 	{ DEVMODE_PAPERSIZE_PENV7ROT, "PRC Envelope #7 (Rotated)" },
1259 	{ DEVMODE_PAPERSIZE_PENV8ROT, "PRC Envelope #8 (Rotated)" },
1260 	{ DEVMODE_PAPERSIZE_PENV9ROT, "PRC Envelope #9 (Rotated)" },
1261 	{ DEVMODE_PAPERSIZE_PENV10ROT, "PRC Envelope #10 (Rotated)" },
1262 	{ 0, NULL }
1263 };
1264 static value_string_ext devmode_papersize_vals_ext = VALUE_STRING_EXT_INIT(devmode_papersize_vals);
1265 
1266 /* List of observed specversions */
1267 
1268 static const value_string devmode_specversion_vals[] =
1269 {
1270 	{ 0x0320, "Observed" },
1271 	{ 0x0400, "Observed" },
1272 	{ 0x0401, "Observed" },
1273 	{ 0x040d, "Observed" },
1274 	{ 0, NULL }
1275 };
1276 
1277 /* Paper sources */
1278 
1279 static const value_string devmode_papersource_vals[] =
1280 {
1281 	{ DEVMODE_PAPERSOURCE_UPPER, "Upper" },
1282 	{ DEVMODE_PAPERSOURCE_LOWER, "Lower" },
1283 	{ DEVMODE_PAPERSOURCE_MIDDLE, "Middle" },
1284 	{ DEVMODE_PAPERSOURCE_MANUAL, "Manual" },
1285 	{ DEVMODE_PAPERSOURCE_ENV, "Envelope" },
1286 	{ DEVMODE_PAPERSOURCE_ENVMANUAL, "Envelope Manual" },
1287 	{ DEVMODE_PAPERSOURCE_AUTO, "Auto" },
1288 	{ DEVMODE_PAPERSOURCE_TRACTOR, "Tractor" },
1289 	{ DEVMODE_PAPERSOURCE_SMALLFMT, "Small Format" },
1290 	{ DEVMODE_PAPERSOURCE_LARGEFMAT, "Large Format" },
1291 	{ DEVMODE_PAPERSOURCE_LARGECAP, "Large Capacity" },
1292 	{ DEVMODE_PAPERSOURCE_CASSETTE, "Cassette" },
1293 	{ DEVMODE_PAPERSOURCE_FORMSRC, "Form Source" },
1294 	{ 0, NULL }
1295 };
1296 static value_string_ext devmode_papersource_vals_ext = VALUE_STRING_EXT_INIT(devmode_papersource_vals);
1297 
1298 /* Print quality */
1299 
1300 static const value_string devmode_printquality_vals[] =
1301 {
1302 	{ DEVMODE_PRINTQUALITY_HIGH, "High" },
1303 	{ DEVMODE_PRINTQUALITY_MEDIUM, "Medium" },
1304 	{ DEVMODE_PRINTQUALITY_LOW, "Low" },
1305 	{ DEVMODE_PRINTQUALITY_DRAFT, "Draft" },
1306 	{ 0, NULL }
1307 };
1308 
1309 /* Color */
1310 
1311 static const value_string devmode_colour_vals[] =
1312 {
1313 	{ DEVMODE_COLOUR_COLOUR, "Colour" },
1314 	{ DEVMODE_COLOUR_MONO, "Monochrome" },
1315 	{ 0, NULL }
1316 };
1317 
1318 /* TrueType options */
1319 
1320 static const value_string devmode_ttoption_vals[] =
1321 {
1322 	{ 0, "Not set" },
1323 	{ DEVMODE_TTOPTION_BITMAP, "Bitmap" },
1324 	{ DEVMODE_TTOPTION_DOWNLOAD, "Download" },
1325 	{ DEVMODE_TTOPTION_DOWNLOAD_OUTLINE, "Download outline" },
1326 	{ DEVMODE_TTOPTION_SUBDEV, "Substitute device fonts" },
1327 	{ 0, NULL }
1328 };
1329 
1330 /* Collate info */
1331 
1332 static const value_string devmode_collate_vals[] =
1333 {
1334 	{ DEVMODE_COLLATE_FALSE, "False" },
1335 	{ DEVMODE_COLLATE_TRUE, "True" },
1336 	{ 0, NULL }
1337 };
1338 
1339 /* Duplex info */
1340 
1341 static const value_string devmode_duplex_vals[] =
1342 {
1343 	{ DEVMODE_DUPLEX_SIMPLEX, "Simplex" },
1344 	{ DEVMODE_DUPLEX_VERT, "Vertical" },
1345 	{ DEVMODE_DUPLEX_HORIZ, "Horizontal" },
1346 	{ 0, NULL }
1347 };
1348 
1349 static const value_string devmode_displayflags_vals[] =
1350 {
1351 	{ 0, "Colour" },
1352 	{ DEVMODE_DISPLAYFLAGS_GRAYSCALE, "Grayscale" },
1353 	{ DEVMODE_DISPLAYFLAGS_INTERLACED, "Interlaced" },
1354 	{ 0, NULL }
1355 };
1356 
1357 static const value_string devmode_icmmethod_vals[] =
1358 {
1359 	{ DEVMODE_ICMMETHOD_NONE, "None" },
1360 	{ DEVMODE_ICMMETHOD_SYSTEM, "System" },
1361 	{ DEVMODE_ICMMETHOD_DRIVER, "Driver" },
1362 	{ DEVMODE_ICMMETHOD_DEVICE, "Device" },
1363 	{ 0, NULL }
1364 };
1365 
1366 static const value_string devmode_icmintent_vals[] =
1367 {
1368 	{ 0, "Not set" },
1369 	{ DEVMODE_ICMINTENT_SATURATE, "Saturate" },
1370 	{ DEVMODE_ICMINTENT_CONTRAST, "Contrast" },
1371 	{ DEVMODE_ICMINTENT_COLORIMETRIC, "Colorimetric" },
1372 	{ DEVMODE_ICMINTENT_ABS_COLORIMETRIC, "Absolute colorimetric" },
1373 	{ 0, NULL }
1374 };
1375 
1376 static const value_string devmode_mediatype_vals[] =
1377 {
1378 	{ 0, "Not set" },
1379 	{ DEVMODE_MEDIATYPE_STANDARD, "Standard" },
1380 	{ DEVMODE_MEDIATYPE_TRANSPARENCY, "Transparency" },
1381 	{ DEVMODE_MEDIATYPE_GLOSSY, "Glossy" },
1382 	{ 0, NULL }
1383 };
1384 
1385 static const value_string devmode_dithertype_vals[] =
1386 {
1387 	{ 0, "Not set" },
1388 	{ DEVMODE_DITHERTYPE_NONE, "None" },
1389 	{ DEVMODE_DITHERTYPE_COARSE, "Coarse" },
1390 	{ DEVMODE_DITHERTYPE_LINE, "Line" },
1391 	{ DEVMODE_DITHERTYPE_LINEART, "Line art" },
1392 	{ DEVMODE_DITHERTYPE_ERRORDIFFUSION, "Error diffusion" },
1393 	{ DEVMODE_DITHERTYPE_RESERVED6, "Reserved 6" },
1394 	{ DEVMODE_DITHERTYPE_RESERVED7, "Reserved 7" },
1395 	{ DEVMODE_DITHERTYPE_GRAYSCALE, "Grayscale" },
1396 	{ 0, NULL }
1397 };
1398 
1399 static gint ett_DEVMODE_fields = -1;
1400 
1401 static int
dissect_DEVMODE_fields(tvbuff_t * tvb,gint offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,guint32 * pdata)1402 dissect_DEVMODE_fields(tvbuff_t *tvb, gint offset, packet_info *pinfo,
1403 		       proto_tree *tree, dcerpc_info *di, guint8 *drep, guint32 *pdata)
1404 {
1405 	guint32 fields;
1406 	proto_item *hidden_item;
1407 
1408 	static int * const hf_fields[] = {
1409 		&hf_devmode_fields_orientation,
1410 		&hf_devmode_fields_papersize,
1411 		&hf_devmode_fields_paperlength,
1412 		&hf_devmode_fields_paperwidth,
1413 		&hf_devmode_fields_scale,
1414 		&hf_devmode_fields_position,
1415 		&hf_devmode_fields_nup,
1416 		&hf_devmode_fields_copies,
1417 		&hf_devmode_fields_defaultsource,
1418 		&hf_devmode_fields_printquality,
1419 		&hf_devmode_fields_color,
1420 		&hf_devmode_fields_duplex,
1421 		&hf_devmode_fields_yresolution,
1422 		&hf_devmode_fields_ttoption,
1423 		&hf_devmode_fields_collate,
1424 		&hf_devmode_fields_formname,
1425 		&hf_devmode_fields_logpixels,
1426 		&hf_devmode_fields_bitsperpel,
1427 		&hf_devmode_fields_pelswidth,
1428 		&hf_devmode_fields_pelsheight,
1429 		&hf_devmode_fields_displayflags,
1430 		&hf_devmode_fields_displayfrequency,
1431 		&hf_devmode_fields_icmmethod,
1432 		&hf_devmode_fields_icmintent,
1433 		&hf_devmode_fields_mediatype,
1434 		&hf_devmode_fields_dithertype,
1435 		&hf_devmode_fields_panningwidth,
1436 		&hf_devmode_fields_panningheight,
1437 		NULL
1438 	};
1439 
1440 	hidden_item = proto_tree_add_uint(
1441 		tree, hf_devmode, tvb, offset, 0, 1);
1442 	proto_item_set_hidden(hidden_item);
1443 
1444 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &fields);
1445 
1446 	proto_tree_add_bitmask_value_with_flags(tree, tvb, offset - 4, hf_devmode_fields,
1447 					ett_DEVMODE_fields, hf_fields, fields, BMT_NO_APPEND);
1448 
1449 	if (pdata)
1450 		*pdata = fields;
1451 
1452 	return offset;
1453 }
1454 
1455 static gint ett_DEVMODE = -1;
1456 
1457 static int
dissect_DEVMODE(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1458 dissect_DEVMODE(tvbuff_t *tvb, int offset, packet_info *pinfo,
1459 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
1460 {
1461 	proto_item *item;
1462 	proto_tree *subtree;
1463 	guint16 driver_extra;
1464 	gint16 print_quality;
1465 	guint32 fields;
1466 	int struct_start = offset;
1467 
1468 	if (di->conformant_run)
1469 		return offset;
1470 
1471 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_DEVMODE, &item, "Devicemode");
1472 
1473 	offset = dissect_ndr_uint32(
1474 		tvb, offset, pinfo, subtree, di, drep, hf_devmode_size,
1475 		NULL);
1476 
1477 	/* The device name is stored in a 32-wchar buffer */
1478 
1479 	dissect_spoolss_uint16uni(tvb, offset, pinfo, subtree, drep, NULL, hf_devmode_devicename);
1480 	offset += 64;
1481 
1482 	offset = dissect_ndr_uint16(
1483 		tvb, offset, pinfo, subtree, di, drep,
1484 		hf_devmode_spec_version, NULL);
1485 
1486 	offset = dissect_ndr_uint16(
1487 		tvb, offset, pinfo, subtree, di, drep,
1488 		hf_devmode_driver_version, NULL);
1489 
1490 	offset = dissect_ndr_uint16(
1491 		tvb, offset, pinfo, subtree, di, drep,
1492 		hf_devmode_size2, NULL);
1493 
1494 	offset = dissect_ndr_uint16(
1495 		tvb, offset, pinfo, subtree, di, drep,
1496 		hf_devmode_driver_extra_len, &driver_extra);
1497 
1498 	offset = dissect_DEVMODE_fields(
1499 		tvb, offset, pinfo, subtree, di, drep, &fields);
1500 
1501 	offset = dissect_ndr_uint16(
1502 		tvb, offset, pinfo, subtree, di, drep,
1503 		hf_devmode_orientation, NULL);
1504 
1505 	offset = dissect_ndr_uint16(
1506 		tvb, offset, pinfo, subtree, di, drep,
1507 		hf_devmode_paper_size, NULL);
1508 
1509 	offset = dissect_ndr_uint16(
1510 		tvb, offset, pinfo, subtree, di, drep,
1511 		hf_devmode_paper_length, NULL);
1512 
1513 	offset = dissect_ndr_uint16(
1514 		tvb, offset, pinfo, subtree, di, drep,
1515 		hf_devmode_paper_width, NULL);
1516 
1517 	offset = dissect_ndr_uint16(
1518 		tvb, offset, pinfo, subtree, di, drep,
1519 		hf_devmode_scale, NULL);
1520 
1521 	offset = dissect_ndr_uint16(
1522 		tvb, offset, pinfo, subtree, di, drep,
1523 		hf_devmode_copies, NULL);
1524 
1525 	offset = dissect_ndr_uint16(
1526 		tvb, offset, pinfo, subtree, di, drep,
1527 		hf_devmode_default_source, NULL);
1528 
1529 	offset = dissect_ndr_uint16(
1530 		tvb, offset, pinfo, NULL, di, drep,
1531 		hf_devmode_print_quality, &print_quality);
1532 
1533 	if (print_quality < 0)
1534 		proto_tree_add_item(
1535 			subtree, hf_devmode_print_quality, tvb,
1536 			offset - 2, 2, DREP_ENC_INTEGER(drep));
1537 	else
1538 		proto_tree_add_uint_format_value(
1539 			subtree, hf_devmode_print_quality, tvb, offset - 4, 4,
1540 			print_quality, "%d dpi", print_quality);
1541 
1542 	offset = dissect_ndr_uint16(
1543 		tvb, offset, pinfo, subtree, di, drep,
1544 		hf_devmode_color, NULL);
1545 
1546 	offset = dissect_ndr_uint16(
1547 		tvb, offset, pinfo, subtree, di, drep,
1548 		hf_devmode_duplex, NULL);
1549 
1550 	offset = dissect_ndr_uint16(
1551 		tvb, offset, pinfo, subtree, di, drep,
1552 		hf_devmode_y_resolution, NULL);
1553 
1554 	offset = dissect_ndr_uint16(
1555 		tvb, offset, pinfo, subtree, di, drep,
1556 		hf_devmode_tt_option, NULL);
1557 
1558 	offset = dissect_ndr_uint16(
1559 		tvb, offset, pinfo, subtree, di, drep,
1560 		hf_devmode_collate, NULL);
1561 
1562 	dissect_spoolss_uint16uni(tvb, offset, pinfo, subtree, drep, NULL, hf_devmode_form_name);
1563 	offset += 64;
1564 
1565 	offset = dissect_ndr_uint16(
1566 		tvb, offset, pinfo, subtree, di, drep,
1567 		hf_devmode_log_pixels, NULL);
1568 
1569 	offset = dissect_ndr_uint32(
1570 		tvb, offset, pinfo, subtree, di, drep,
1571 		hf_devmode_bits_per_pel, NULL);
1572 
1573 	offset = dissect_ndr_uint32(
1574 		tvb, offset, pinfo, subtree, di, drep,
1575 		hf_devmode_pels_width, NULL);
1576 
1577 	offset = dissect_ndr_uint32(
1578 		tvb, offset, pinfo, subtree, di, drep,
1579 		hf_devmode_pels_height, NULL);
1580 
1581 	offset = dissect_ndr_uint32(
1582 		tvb, offset, pinfo, subtree, di, drep,
1583 		hf_devmode_display_flags, NULL);
1584 
1585 	offset = dissect_ndr_uint32(
1586 		tvb, offset, pinfo, subtree, di, drep,
1587 		hf_devmode_display_freq, NULL);
1588 
1589 	/* TODO: Some of the remaining fields are optional.  See
1590 	   rpc_parse/parse_spoolss.c in the Samba source for details. */
1591 
1592 	offset = dissect_ndr_uint32(
1593 		tvb, offset, pinfo, subtree, di, drep,
1594 		hf_devmode_icm_method, NULL);
1595 
1596 	offset = dissect_ndr_uint32(
1597 		tvb, offset, pinfo, subtree, di, drep,
1598 		hf_devmode_icm_intent, NULL);
1599 
1600 	offset = dissect_ndr_uint32(
1601 		tvb, offset, pinfo, subtree, di, drep,
1602 		hf_devmode_media_type, NULL);
1603 
1604 	offset = dissect_ndr_uint32(
1605 		tvb, offset, pinfo, subtree, di, drep,
1606 		hf_devmode_dither_type, NULL);
1607 
1608 	offset = dissect_ndr_uint32(
1609 		tvb, offset, pinfo, subtree, di, drep,
1610 		hf_devmode_reserved1, NULL);
1611 
1612 	offset = dissect_ndr_uint32(
1613 		tvb, offset, pinfo, subtree, di, drep,
1614 		hf_devmode_reserved2, NULL);
1615 
1616 	offset = dissect_ndr_uint32(
1617 		tvb, offset, pinfo, subtree, di, drep,
1618 		hf_devmode_panning_width, NULL);
1619 
1620 	offset = dissect_ndr_uint32(
1621 		tvb, offset, pinfo, subtree, di, drep,
1622 		hf_devmode_panning_height, NULL);
1623 
1624 	if (driver_extra)
1625 		offset = dissect_ndr_uint8s(
1626 			tvb, offset, pinfo, subtree, di, drep,
1627 			hf_devmode_driver_extra, driver_extra, NULL);
1628 
1629 	proto_item_set_len(item, offset - struct_start);
1630 
1631 	return offset;
1632 }
1633 
1634 /*
1635  * DEVMODE_CTR
1636  */
1637 
1638 static gint ett_DEVMODE_CTR = -1;
1639 
1640 int
dissect_DEVMODE_CTR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1641 dissect_DEVMODE_CTR(tvbuff_t *tvb, int offset, packet_info *pinfo,
1642 			       proto_tree *tree, dcerpc_info *di, guint8 *drep)
1643 {
1644 	proto_tree *subtree;
1645 	guint32 size;
1646 
1647 	subtree = proto_tree_add_subtree(
1648 		tree, tvb, offset, 0, ett_DEVMODE_CTR, NULL, "Devicemode container");
1649 
1650 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
1651 				    hf_devmodectr_size, &size);
1652 
1653 	offset = dissect_ndr_pointer(
1654 		tvb, offset, pinfo, subtree, di, drep,
1655 		dissect_DEVMODE, NDR_POINTER_UNIQUE, "Devicemode", -1);
1656 
1657 	return offset;
1658 }
1659 
1660 /*
1661  * Relative string given by offset into the current buffer.  Note that
1662  * the offset for subsequent relstrs are against the structure start, not
1663  * the point where the offset is parsed from.
1664  */
1665 
1666 static gint ett_RELSTR = -1;
1667 
1668 static int
dissect_spoolss_relstr(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index,int struct_start,char ** data)1669 dissect_spoolss_relstr(tvbuff_t *tvb, int offset, packet_info *pinfo,
1670 		       proto_tree *tree, dcerpc_info *di, guint8 *drep, int hf_index,
1671 		       int struct_start, char **data)
1672 {
1673 	proto_item *item;
1674 	proto_tree *subtree;
1675 	guint32 relstr_offset, relstr_start, relstr_end;
1676 	char *text;
1677 
1678 	/* Peek ahead to read the string.  We need this for the
1679 	   proto_tree_add_string() call so filtering will work. */
1680 
1681 	offset = dissect_ndr_uint32(
1682 		tvb, offset, pinfo, NULL, di, drep, hf_offset, &relstr_offset);
1683 
1684 	relstr_start = relstr_offset + struct_start;
1685 
1686 	if (relstr_offset) {
1687 		relstr_end = dissect_spoolss_uint16uni(
1688 			tvb, relstr_start, pinfo, NULL, drep, &text, hf_relative_string);
1689 	} else { 			/* relstr_offset == 0 is a NULL string */
1690 		text = wmem_strdup(pinfo->pool, "");
1691 		relstr_end = relstr_start;
1692 	}
1693 
1694 	/* OK now add the proto item with the string value */
1695 
1696 	item = proto_tree_add_string(tree, hf_index, tvb, relstr_start, relstr_end - relstr_start, text);
1697 	subtree = proto_item_add_subtree(item, ett_RELSTR);
1698 
1699 	dissect_ndr_uint32(
1700 		tvb, offset - 4, pinfo, subtree, di, drep, hf_offset, NULL);
1701 
1702 	if (relstr_offset)
1703 		dissect_spoolss_uint16uni(
1704 			tvb, relstr_start, pinfo, subtree, drep, NULL, hf_relative_string);
1705 
1706 	if (data)
1707 		*data = text;
1708 
1709 	return offset;
1710 }
1711 
1712 /* An array of relative strings.  This is currently just a copy of the
1713    dissect_spoolss_relstr() function as I can't find an example driver that
1714    has more than one dependent file. */
1715 
1716 static gint ett_RELSTR_ARRAY = -1;
1717 
1718 static int
dissect_spoolss_relstrarray(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hf_index,int struct_start,char ** data)1719 dissect_spoolss_relstrarray(tvbuff_t *tvb, int offset, packet_info *pinfo,
1720 			    proto_tree *tree, dcerpc_info *di, guint8 *drep, int hf_index,
1721 			    int struct_start, char **data)
1722 {
1723 	proto_item *item;
1724 	proto_tree *subtree;
1725 	guint32 relstr_offset, relstr_start/*, relstr_end, relstr_len*/;
1726 	char *text;
1727 
1728 	item = proto_tree_add_string(tree, hf_index, tvb, offset, 4, "");
1729 
1730 	subtree = proto_item_add_subtree(item, ett_RELSTR_ARRAY);
1731 
1732 	offset = dissect_ndr_uint32(
1733 		tvb, offset, pinfo, subtree, di, drep, hf_offset, &relstr_offset);
1734 
1735 	/* A relative offset of zero is a NULL string */
1736 
1737 	relstr_start = relstr_offset + struct_start;
1738 
1739 	if (relstr_offset)
1740 		/*relstr_end = */dissect_spoolss_uint16uni(
1741 			tvb, relstr_start, pinfo, subtree, drep, &text, hf_relative_string);
1742 	else {
1743 		text = wmem_strdup(pinfo->pool, "NULL");
1744 		/*relstr_end = offset;*/
1745 	}
1746 
1747 	/*relstr_len = relstr_end - relstr_start;*/
1748 
1749 	proto_item_append_text(item, "%s", text);
1750 
1751 	if (data)
1752 		*data = text;
1753 
1754 	return offset;
1755 }
1756 
1757 /*
1758  * PRINTER_INFO_0
1759  */
1760 
1761 static int hf_printer_status = -1;
1762 
1763 static const value_string printer_status_vals[] =
1764 {
1765 	{ PRINTER_STATUS_OK, "OK" },
1766 	{ PRINTER_STATUS_PAUSED, "Paused" },
1767 	{ PRINTER_STATUS_ERROR, "Error" },
1768 	{ PRINTER_STATUS_PENDING_DELETION, "Pending deletion" },
1769 	{ PRINTER_STATUS_PAPER_JAM, "Paper jam" },
1770 	{ PRINTER_STATUS_PAPER_OUT, "Paper out" },
1771 	{ PRINTER_STATUS_MANUAL_FEED, "Manual feed" },
1772 	{ PRINTER_STATUS_PAPER_PROBLEM, "Paper problem" },
1773 	{ PRINTER_STATUS_OFFLINE, "Offline" },
1774 	{ PRINTER_STATUS_IO_ACTIVE, "IO active" },
1775 	{ PRINTER_STATUS_BUSY, "Busy" },
1776 	{ PRINTER_STATUS_PRINTING, "Printing" },
1777 	{ PRINTER_STATUS_OUTPUT_BIN_FULL, "Output bin full" },
1778 	{ PRINTER_STATUS_NOT_AVAILABLE, "Not available" },
1779 	{ PRINTER_STATUS_WAITING, "Waiting" },
1780 	{ PRINTER_STATUS_PROCESSING, "Processing" },
1781 	{ PRINTER_STATUS_INITIALIZING, "Initialising" },
1782 	{ PRINTER_STATUS_WARMING_UP, "Warming up" },
1783 	{ PRINTER_STATUS_TONER_LOW, "Toner low" },
1784 	{ PRINTER_STATUS_NO_TONER, "No toner" },
1785 	{ PRINTER_STATUS_PAGE_PUNT, "Page punt" },
1786 	{ PRINTER_STATUS_USER_INTERVENTION, "User intervention" },
1787 	{ PRINTER_STATUS_OUT_OF_MEMORY, "Out of memory" },
1788 	{ PRINTER_STATUS_DOOR_OPEN, "Door open" },
1789 	{ PRINTER_STATUS_SERVER_UNKNOWN, "Server unknown" },
1790 	{ PRINTER_STATUS_POWER_SAVE, "Power save" },
1791 	{ 0, NULL }
1792 };
1793 static value_string_ext printer_status_vals_ext = VALUE_STRING_EXT_INIT(printer_status_vals);
1794 
1795 static gint ett_PRINTER_INFO_0 = -1;
1796 
1797 static int
dissect_PRINTER_INFO_0(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1798 dissect_PRINTER_INFO_0(tvbuff_t *tvb, int offset,
1799 				  packet_info *pinfo, proto_tree *tree,
1800 				  dcerpc_info *di, guint8 *drep)
1801 {
1802 	offset = dissect_spoolss_relstr(
1803 		tvb, offset, pinfo, tree, di, drep, hf_printername,
1804 		0, NULL);
1805 
1806 	offset = dissect_spoolss_relstr(
1807 		tvb, offset, pinfo, tree, di, drep, hf_servername,
1808 		0, NULL);
1809 
1810 	offset = dissect_ndr_uint32(
1811 		tvb, offset, pinfo, tree, di, drep, hf_printer_cjobs, NULL);
1812 
1813 	offset = dissect_ndr_uint32(
1814 		tvb, offset, pinfo, tree, di, drep, hf_printer_total_jobs,
1815 		NULL);
1816 
1817 	offset = dissect_ndr_uint32(
1818 		tvb, offset, pinfo, tree, di, drep, hf_printer_total_bytes,
1819 		NULL);
1820 
1821 	offset = dissect_SYSTEM_TIME(
1822 		tvb, offset, pinfo, tree, di, drep, "Unknown time", TRUE, NULL);
1823 
1824 	offset = dissect_ndr_uint32(
1825 		tvb, offset, pinfo, tree, di, drep, hf_printer_global_counter,
1826 		NULL);
1827 
1828 	offset = dissect_ndr_uint32(
1829 		tvb, offset, pinfo, tree, di, drep, hf_printer_total_pages,
1830 		NULL);
1831 
1832 	offset = dissect_ndr_uint16(
1833 		tvb, offset, pinfo, tree, di, drep, hf_printer_major_version,
1834 		NULL);
1835 
1836 	offset = dissect_ndr_uint16(
1837 		tvb, offset, pinfo, tree, di, drep, hf_printer_build_version,
1838 		NULL);
1839 
1840 	offset = dissect_ndr_uint32(
1841 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk7, NULL);
1842 
1843 	offset = dissect_ndr_uint32(
1844 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk8, NULL);
1845 
1846 	offset = dissect_ndr_uint32(
1847 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk9, NULL);
1848 
1849 	offset = dissect_ndr_uint32(
1850 		tvb, offset, pinfo, tree, di, drep, hf_printer_session_ctr,
1851 		NULL);
1852 
1853 	offset = dissect_ndr_uint32( tvb, offset, pinfo, tree, di, drep,
1854 		hf_printer_unk11, NULL);
1855 
1856 	offset = dissect_ndr_uint32( tvb, offset, pinfo, tree, di, drep,
1857 		hf_printer_printer_errors, NULL);
1858 
1859 	offset = dissect_ndr_uint32(
1860 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk13, NULL);
1861 
1862 	offset = dissect_ndr_uint32(
1863 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk14, NULL);
1864 
1865 	offset = dissect_ndr_uint32(
1866 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk15, NULL);
1867 
1868 	offset = dissect_ndr_uint32(
1869 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk16, NULL);
1870 
1871 	offset = dissect_ndr_uint32(
1872 		tvb, offset, pinfo, tree, di, drep, hf_printer_changeid, NULL);
1873 
1874 	offset = dissect_ndr_uint32(
1875 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk18, NULL);
1876 
1877 	offset = dissect_ndr_uint32(
1878 		tvb, offset, pinfo, tree, di, drep, hf_printer_status, NULL);
1879 
1880 	offset = dissect_ndr_uint32(
1881 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk20, NULL);
1882 
1883 	offset = dissect_ndr_uint32(
1884 		tvb, offset, pinfo, tree, di, drep, hf_printer_c_setprinter,
1885 		NULL);
1886 
1887 	offset = dissect_ndr_uint16(
1888 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk22, NULL);
1889 
1890 	offset = dissect_ndr_uint16(
1891 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk23, NULL);
1892 
1893 	offset = dissect_ndr_uint16(
1894 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk24, NULL);
1895 
1896 	offset = dissect_ndr_uint16(
1897 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk25, NULL);
1898 
1899 	offset = dissect_ndr_uint16(
1900 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk26, NULL);
1901 
1902 	offset = dissect_ndr_uint16(
1903 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk27, NULL);
1904 
1905 	offset = dissect_ndr_uint16(
1906 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk28, NULL);
1907 
1908 	offset = dissect_ndr_uint16(
1909 		tvb, offset, pinfo, tree, di, drep, hf_printer_unk29, NULL);
1910 
1911 	return offset;
1912 }
1913 
1914 /*
1915  * PRINTER_INFO_1
1916  */
1917 
1918 static gint ett_PRINTER_INFO_1 = -1;
1919 
1920 static int
dissect_PRINTER_INFO_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)1921 dissect_PRINTER_INFO_1(tvbuff_t *tvb, int offset,
1922 				  packet_info *pinfo, proto_tree *tree,
1923 				  dcerpc_info *di, guint8 *drep)
1924 {
1925 	offset = dissect_ndr_uint32(
1926 		tvb, offset, pinfo, tree, di, drep,
1927 		hf_printer_flags, NULL);
1928 
1929 	offset = dissect_spoolss_relstr(
1930 		tvb, offset, pinfo, tree, di, drep, hf_printerdesc,
1931 		0, NULL);
1932 
1933 	offset = dissect_spoolss_relstr(
1934 		tvb, offset, pinfo, tree, di, drep, hf_printername,
1935 		0, NULL);
1936 
1937 	offset = dissect_spoolss_relstr(
1938 		tvb, offset, pinfo, tree, di, drep, hf_printercomment,
1939 		0, NULL);
1940 
1941 	return offset;
1942 }
1943 
1944 /* Job status */
1945 
1946 static const true_false_string tfs_job_status_paused = {
1947 	"Job is paused",
1948 	"Job is not paused"
1949 };
1950 
1951 static const true_false_string tfs_job_status_error = {
1952 	"Job has an error",
1953 	"Job is OK"
1954 };
1955 
1956 static const true_false_string tfs_job_status_deleting = {
1957 	"Job is being deleted",
1958 	"Job is not being deleted"
1959 };
1960 
1961 static const true_false_string tfs_job_status_spooling = {
1962 	"Job is being spooled",
1963 	"Job is not being spooled"
1964 };
1965 
1966 static const true_false_string tfs_job_status_printing = {
1967 	"Job is being printed",
1968 	"Job is not being printed"
1969 };
1970 
1971 static const true_false_string tfs_job_status_offline = {
1972 	"Job is offline",
1973 	"Job is not offline"
1974 };
1975 
1976 static const true_false_string tfs_job_status_paperout = {
1977 	"Job is out of paper",
1978 	"Job is not out of paper"
1979 };
1980 
1981 static const true_false_string tfs_job_status_printed = {
1982 	"Job has completed printing",
1983 	"Job has not completed printing"
1984 };
1985 
1986 static const true_false_string tfs_job_status_deleted = {
1987 	"Job has been deleted",
1988 	"Job has not been deleted"
1989 };
1990 
1991 static const true_false_string tfs_job_status_blocked = {
1992 	"Job has been blocked",
1993 	"Job has not been blocked"
1994 };
1995 
1996 static const true_false_string tfs_job_status_user_intervention = {
1997 	"User intervention required",
1998 	"User intervention not required"
1999 };
2000 
2001 static gint ett_job_status = -1;
2002 
2003 static int
dissect_job_status(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2004 dissect_job_status(tvbuff_t *tvb, int offset, packet_info *pinfo,
2005 		   proto_tree *tree, dcerpc_info *di, guint8 *drep)
2006 {
2007 	guint32 status;
2008 	static int * const hf_status[] = {
2009 		&hf_job_status_user_intervention,
2010 		&hf_job_status_blocked,
2011 		&hf_job_status_deleted,
2012 		&hf_job_status_printed,
2013 		&hf_job_status_paperout,
2014 		&hf_job_status_offline,
2015 		&hf_job_status_printing,
2016 		&hf_job_status_spooling,
2017 		&hf_job_status_deleting,
2018 		&hf_job_status_error,
2019 		&hf_job_status_paused,
2020 		NULL
2021 	};
2022 
2023 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &status);
2024 
2025 	proto_tree_add_bitmask_value_with_flags(tree, tvb, offset - 4, hf_job_status,
2026 					ett_job_status, hf_status, status, BMT_NO_APPEND);
2027 
2028 	return offset;
2029 }
2030 
2031 /* Printer attributes */
2032 
2033 static gint ett_printer_attributes = -1;
2034 
2035 static int hf_printer_attributes = -1;
2036 static int hf_printer_attributes_queued = -1;
2037 static int hf_printer_attributes_direct = -1;
2038 static int hf_printer_attributes_default = -1;
2039 static int hf_printer_attributes_shared = -1;
2040 static int hf_printer_attributes_network = -1;
2041 static int hf_printer_attributes_hidden = -1;
2042 static int hf_printer_attributes_local = -1;
2043 static int hf_printer_attributes_enable_devq = -1;
2044 static int hf_printer_attributes_keep_printed_jobs = -1;
2045 static int hf_printer_attributes_do_complete_first = -1;
2046 static int hf_printer_attributes_work_offline = -1;
2047 static int hf_printer_attributes_enable_bidi = -1;
2048 static int hf_printer_attributes_raw_only = -1;
2049 static int hf_printer_attributes_published = -1;
2050 
2051 static const true_false_string tfs_printer_attributes_queued = {
2052 	"The printer starts printing after last page spooled",
2053 	"The printer starts printing while spooling"
2054 };
2055 
2056 static const true_false_string tfs_printer_attributes_direct = {
2057 	"Jobs are sent directly to the printer",
2058 	"Jobs are spooled to the printer before printing"
2059 };
2060 
2061 static const true_false_string tfs_printer_attributes_default = {
2062 	"The printer is the default printer",
2063 	"The printer is not the default printer"
2064 };
2065 
2066 static const true_false_string tfs_printer_attributes_shared = {
2067 	"The printer is shared",
2068 	"The printer is not shared"
2069 };
2070 
2071 static const true_false_string tfs_printer_attributes_network = {
2072 	"The printer is a network printer connection",
2073 	"The printer is not a network printer connection"
2074 };
2075 
2076 static const true_false_string tfs_printer_attributes_hidden = {
2077 	"The printer is hidden from some users on the network",
2078 	"The printer is not hidden from some users on the network"
2079 };
2080 
2081 static const true_false_string tfs_printer_attributes_local = {
2082 	"The printer is a local printer",
2083 	"The printer is not a local printer"
2084 };
2085 
2086 static const true_false_string tfs_printer_attributes_enable_devq = {
2087 	"The queue on the printer is enabled if available",
2088 	"The queue on the printer is not enabled",
2089 };
2090 
2091 static const true_false_string tfs_printer_attributes_keep_printed_jobs = {
2092 	"Jobs are kept after they are printed",
2093 	"Jobs are deleted after they are printed"
2094 };
2095 
2096 static const true_false_string tfs_printer_attributes_do_complete_first = {
2097 	"Jobs that have completed spooling are scheduled before still spooling jobs",
2098 	"Jobs are scheduled in the order they start spooling"
2099 };
2100 
2101 static const true_false_string tfs_printer_attributes_work_offline = {
2102 	"The printer is currently connected",
2103 	"The printer is currently not connected"
2104 };
2105 
2106 static const true_false_string tfs_printer_attributes_enable_bidi = {
2107 	"Bidirectional communications are supported",
2108 	"Bidirectional communications are not supported"
2109 };
2110 
2111 static const true_false_string tfs_printer_attributes_raw_only = {
2112 	"Only raw data type print jobs can be spooled",
2113 	"All data type print jobs can be spooled"
2114 };
2115 
2116 static const true_false_string tfs_printer_attributes_published = {
2117 	"The printer is published in the directory",
2118 	"The printer is not published in the directory"
2119 };
2120 
2121 static int
dissect_printer_attributes(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2122 dissect_printer_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
2123 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
2124 {
2125 	guint32 attributes;
2126 	static int * const hf_attributes[] = {
2127 		&hf_printer_attributes_published,
2128 		&hf_printer_attributes_raw_only,
2129 		&hf_printer_attributes_enable_bidi,
2130 		&hf_printer_attributes_work_offline,
2131 		&hf_printer_attributes_do_complete_first,
2132 		&hf_printer_attributes_keep_printed_jobs,
2133 		&hf_printer_attributes_enable_devq,
2134 		&hf_printer_attributes_local,
2135 		&hf_printer_attributes_hidden,
2136 		&hf_printer_attributes_network,
2137 		&hf_printer_attributes_shared,
2138 		&hf_printer_attributes_default,
2139 		&hf_printer_attributes_direct,
2140 		&hf_printer_attributes_queued,
2141 		NULL
2142 	};
2143 
2144 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &attributes);
2145 
2146 	proto_tree_add_bitmask_value_with_flags(tree, tvb, offset - 4, hf_printer_attributes,
2147 					ett_printer_attributes, hf_attributes, attributes, BMT_NO_APPEND);
2148 
2149 	return offset;
2150 }
2151 
2152 /* Printer Driver attributes */
2153 
2154 static gint ett_printer_driver_attributes = -1;
2155 
2156 static int hf_printer_driver_attributes = -1;
2157 static int hf_printer_driver_attributes_package_aware = -1;
2158 static int hf_printer_driver_attributes_xps = -1;
2159 static int hf_printer_driver_attributes_sandbox_enabled = -1;
2160 static int hf_printer_driver_attributes_class = -1;
2161 static int hf_printer_driver_attributes_derived = -1;
2162 static int hf_printer_driver_attributes_not_shareable = -1;
2163 static int hf_printer_driver_attributes_category_fax = -1;
2164 static int hf_printer_driver_attributes_category_file = -1;
2165 static int hf_printer_driver_attributes_category_virtual = -1;
2166 static int hf_printer_driver_attributes_category_service = -1;
2167 static int hf_printer_driver_attributes_soft_reset_required = -1;
2168 static int hf_printer_driver_attributes_category_3d = -1;
2169 
2170 static const true_false_string tfs_printer_driver_attributes_package_aware = {
2171 	"Printer Driver is package aware",
2172 	"Printer Driver is not package aware"
2173 };
2174 
2175 static const true_false_string tfs_printer_driver_attributes_xps = {
2176 	"Printer Driver is XPS based",
2177 	"Printer Driver is not XPS based"
2178 };
2179 
2180 static const true_false_string tfs_printer_driver_attributes_sandbox_enabled = {
2181 	"Printer Driver is sandbox enabled",
2182 	"Printer Driver is not sandbox enabled"
2183 };
2184 
2185 static const true_false_string tfs_printer_driver_attributes_class = {
2186 	"Printer Driver is a Class Printer Driver",
2187 	"Printer Driver is not a Class Printer Driver"
2188 };
2189 
2190 static const true_false_string tfs_printer_driver_attributes_derived = {
2191 	"Printer Driver is a derived Printer Driver",
2192 	"Printer Driver is not a derived Printer Driver"
2193 };
2194 
2195 static const true_false_string tfs_printer_driver_attributes_not_shareable = {
2196 	"Printer Driver is a not a sharable Printer Driver",
2197 	"Printer Driver is a shareable Printer Driver"
2198 };
2199 
2200 static const true_false_string tfs_printer_driver_attributes_category_fax = {
2201 	"Printer Driver is a Fax Printer Driver",
2202 	"Printer Driver is not a Fax Printer Driver"
2203 };
2204 
2205 static const true_false_string tfs_printer_driver_attributes_category_file = {
2206 	"Printer Driver is a File Printer Driver",
2207 	"Printer Driver is not a File Printer Driver"
2208 };
2209 
2210 static const true_false_string tfs_printer_driver_attributes_category_virtual = {
2211 	"Printer Driver is a Virtual Printer Driver",
2212 	"Printer Driver is not a Virtual Printer Driver"
2213 };
2214 
2215 static const true_false_string tfs_printer_driver_attributes_category_service = {
2216 	"Printer Driver is a Service Printer Driver",
2217 	"Printer Driver is not a Service Printer Driver"
2218 };
2219 
2220 static const true_false_string tfs_printer_driver_attributes_soft_reset_required = {
2221 	"Soft reset is required for this Printer Driver",
2222 	"No soft reset is required for this Printer Driver"
2223 };
2224 
2225 static const true_false_string tfs_printer_driver_attributes_category_3d = {
2226 	"Printer Driver is a 3D Printer Driver",
2227 	"Printer Driver is not a 3D Printer Driver"
2228 };
2229 
2230 static int
dissect_printer_driver_attributes(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2231 dissect_printer_driver_attributes(tvbuff_t *tvb, int offset, packet_info *pinfo,
2232 				  proto_tree *tree, dcerpc_info *di, guint8 *drep)
2233 {
2234 	guint32 attributes;
2235 	static int * const hf_attributes[] = {
2236 		&hf_printer_driver_attributes_package_aware,
2237 		&hf_printer_driver_attributes_xps,
2238 		&hf_printer_driver_attributes_sandbox_enabled,
2239 		&hf_printer_driver_attributes_class,
2240 		&hf_printer_driver_attributes_derived,
2241 		&hf_printer_driver_attributes_not_shareable,
2242 		&hf_printer_driver_attributes_category_fax,
2243 		&hf_printer_driver_attributes_category_file,
2244 		&hf_printer_driver_attributes_category_virtual,
2245 		&hf_printer_driver_attributes_category_service,
2246 		&hf_printer_driver_attributes_soft_reset_required,
2247 		&hf_printer_driver_attributes_category_3d,
2248 		NULL
2249 	};
2250 
2251 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &attributes);
2252 
2253 	proto_tree_add_bitmask_value_with_flags(tree, tvb, offset - 4, hf_printer_driver_attributes,
2254 					ett_printer_driver_attributes, hf_attributes, attributes, BMT_NO_APPEND);
2255 
2256 	return offset;
2257 }
2258 
2259 
2260 /*
2261  * PRINTER_INFO_2
2262  */
2263 
2264 static gint ett_PRINTER_INFO_2 = -1;
2265 
2266 static int
dissect_PRINTER_INFO_2(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2267 dissect_PRINTER_INFO_2(tvbuff_t *tvb, int offset,
2268 				  packet_info *pinfo, proto_tree *tree,
2269 				  dcerpc_info *di, guint8 *drep)
2270 {
2271 	guint32 devmode_offset, secdesc_offset;
2272 
2273 	offset = dissect_spoolss_relstr(
2274 		tvb, offset, pinfo, tree, di, drep, hf_servername,
2275 		0, NULL);
2276 
2277 	offset = dissect_spoolss_relstr(
2278 		tvb, offset, pinfo, tree, di, drep, hf_printername,
2279 		0, NULL);
2280 
2281 	offset = dissect_spoolss_relstr(
2282 		tvb, offset, pinfo, tree, di, drep, hf_sharename,
2283 		0, NULL);
2284 
2285 	offset = dissect_spoolss_relstr(
2286 		tvb, offset, pinfo, tree, di, drep, hf_portname,
2287 		0, NULL);
2288 
2289 	offset = dissect_spoolss_relstr(
2290 		tvb, offset, pinfo, tree, di, drep, hf_drivername,
2291 		0, NULL);
2292 
2293 	offset = dissect_spoolss_relstr(
2294 		tvb, offset, pinfo, tree, di, drep, hf_printercomment,
2295 		0, NULL);
2296 
2297 	offset = dissect_spoolss_relstr(
2298 		tvb, offset, pinfo, tree, di, drep, hf_printerlocation,
2299 		0, NULL);
2300 
2301 	offset = dissect_ndr_uint32(
2302 		tvb, offset, pinfo, NULL, di, drep, hf_offset,
2303 		&devmode_offset);
2304 
2305 	dissect_DEVMODE(tvb, devmode_offset - 4, pinfo, tree, di, drep);
2306 
2307 	offset = dissect_spoolss_relstr(
2308 		tvb, offset, pinfo, tree, di, drep, hf_sepfile,
2309 		0, NULL);
2310 
2311 	offset = dissect_spoolss_relstr(
2312 		tvb, offset, pinfo, tree, di, drep, hf_printprocessor,
2313 		0, NULL);
2314 
2315 	offset = dissect_spoolss_relstr(
2316 		tvb, offset, pinfo, tree, di, drep, hf_datatype,
2317 		0, NULL);
2318 
2319 	offset = dissect_spoolss_relstr(
2320 		tvb, offset, pinfo, tree, di, drep, hf_parameters,
2321 		0, NULL);
2322 
2323 	/*
2324 	 * XXX - what *is* the length of this security descriptor?
2325 	 * "prs_PRINTER_INFO_2()" is passed to "defer_ptr()", but
2326 	 * "defer_ptr" takes, as an argument, a function with a
2327 	 * different calling sequence from "prs_PRINTER_INFO_2()",
2328 	 * lacking the "len" argument, so that won't work.
2329 	 */
2330 
2331 	offset = dissect_ndr_uint32(
2332 		tvb, offset, pinfo, NULL, di, drep, hf_offset,
2333 		&secdesc_offset);
2334 
2335 	dissect_nt_sec_desc(
2336 		tvb, secdesc_offset, pinfo, tree, drep,
2337 		FALSE, -1,
2338 		&spoolss_printer_access_mask_info);
2339 
2340 	offset = dissect_printer_attributes(tvb, offset, pinfo, tree, di, drep);
2341 
2342 	offset = dissect_ndr_uint32(
2343 		tvb, offset, pinfo, NULL, di, drep, hf_printer_priority,
2344 		NULL);
2345 
2346 	offset = dissect_ndr_uint32(
2347 		tvb, offset, pinfo, NULL, di, drep,
2348 		hf_printer_default_priority, NULL);
2349 
2350 	offset = dissect_ndr_uint32(
2351 		tvb, offset, pinfo, NULL, di, drep, hf_start_time, NULL);
2352 
2353 	offset = dissect_ndr_uint32(
2354 		tvb, offset, pinfo, NULL, di, drep, hf_end_time, NULL);
2355 
2356 	offset = dissect_ndr_uint32(
2357 		tvb, offset, pinfo, tree, di, drep,
2358 		hf_printer_status, NULL);
2359 
2360 	offset = dissect_ndr_uint32(
2361 		tvb, offset, pinfo, NULL, di, drep, hf_printer_jobs,
2362 		NULL);
2363 
2364 	offset = dissect_ndr_uint32(
2365 		tvb, offset, pinfo, NULL, di, drep,
2366 		hf_printer_averageppm, NULL);
2367 
2368 	return offset;
2369 }
2370 
2371 /*
2372  * PRINTER_INFO_3
2373  */
2374 
2375 static gint ett_PRINTER_INFO_3 = -1;
2376 
2377 static int
dissect_PRINTER_INFO_3(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2378 dissect_PRINTER_INFO_3(tvbuff_t *tvb, int offset,
2379 				  packet_info *pinfo, proto_tree *tree,
2380 				  dcerpc_info *di, guint8 *drep)
2381 {
2382 	offset = dissect_ndr_uint32(
2383 		tvb, offset, pinfo, tree, di, drep,
2384 		hf_printer_flags, NULL);
2385 
2386 	offset = dissect_nt_sec_desc(
2387 		tvb, offset, pinfo, tree, drep,
2388 		FALSE, -1,
2389 		&spoolss_printer_access_mask_info);
2390 
2391 	return offset;
2392 }
2393 
2394 /*
2395  * PRINTER_INFO_5
2396  */
2397 
2398 static gint ett_PRINTER_INFO_5 = -1;
2399 
2400 static int
dissect_PRINTER_INFO_5(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2401 dissect_PRINTER_INFO_5(tvbuff_t *tvb, int offset,
2402 				  packet_info *pinfo, proto_tree *tree,
2403 				  dcerpc_info *di, guint8 *drep)
2404 {
2405 	offset = dissect_spoolss_relstr(
2406 		tvb, offset, pinfo, tree, di, drep, hf_printername,
2407 		0, NULL);
2408 
2409 	offset = dissect_spoolss_relstr(
2410 		tvb, offset, pinfo, tree, di, drep, hf_portname,
2411 		0, NULL);
2412 
2413 	offset = dissect_printer_attributes(tvb, offset, pinfo, tree, di, drep);
2414 
2415 	offset = dissect_ndr_uint32(
2416 		tvb, offset, pinfo, tree, di, drep,
2417 		hf_device_not_selected_timeout, NULL);
2418 
2419 	offset = dissect_ndr_uint32(
2420 		tvb, offset, pinfo, tree, di, drep,
2421 		hf_transmission_retry_timeout, NULL);
2422 
2423 	return offset;
2424 }
2425 
2426 
2427 /*
2428  * PRINTER_INFO_7
2429  */
2430 
2431 static gint ett_PRINTER_INFO_7 = -1;
2432 
2433 static const value_string getprinter_action_vals[] = {
2434 	{ DS_PUBLISH, "Publish" },
2435 	{ DS_UNPUBLISH, "Unpublish" },
2436 	{ DS_UPDATE, "Update" },
2437 	{ DS_PENDING, "Pending" },
2438 	{ DS_REPUBLISH, "Republish" },
2439 	{ 0, NULL }
2440 };
2441 
2442 static int
dissect_PRINTER_INFO_7(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2443 dissect_PRINTER_INFO_7(tvbuff_t *tvb, int offset,
2444 				  packet_info *pinfo, proto_tree *tree,
2445 				  dcerpc_info *di, guint8 *drep)
2446 {
2447 	offset = dissect_spoolss_relstr(
2448 		tvb, offset, pinfo, tree, di, drep, hf_printer_guid,
2449 		0, NULL);
2450 
2451 	offset = dissect_ndr_uint32(
2452 		tvb, offset, pinfo, tree, di, drep,
2453 		hf_printer_action, NULL);
2454 
2455 	return offset;
2456 }
2457 
2458 /*
2459  * PRINTER_DATATYPE structure
2460  */
2461 
2462 static gint ett_PRINTER_DATATYPE = -1;
2463 
2464 static int
dissect_PRINTER_DATATYPE(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2465 dissect_PRINTER_DATATYPE(tvbuff_t *tvb, int offset,
2466 				    packet_info *pinfo, proto_tree *tree,
2467 				    dcerpc_info *di, guint8 *drep)
2468 {
2469 	if (di->conformant_run)
2470 		return offset;
2471 
2472 	offset = dissect_ndr_cvstring(
2473 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
2474 		hf_datatype, TRUE, NULL);
2475 
2476 	return offset;
2477 }
2478 
2479 /*
2480  * USER_LEVEL_1 structure
2481  */
2482 
2483 static gint ett_USER_LEVEL_1 = -1;
2484 
2485 static int hf_userlevel_size = -1;
2486 static int hf_userlevel_client = -1;
2487 static int hf_userlevel_user = -1;
2488 static int hf_userlevel_build = -1;
2489 static int hf_userlevel_major = -1;
2490 static int hf_userlevel_minor = -1;
2491 static int hf_userlevel_processor = -1;
2492 
2493 static int
dissect_USER_LEVEL_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2494 dissect_USER_LEVEL_1(tvbuff_t *tvb, int offset,
2495 				packet_info *pinfo, proto_tree *tree,
2496 				dcerpc_info *di, guint8 *drep)
2497 {
2498 	guint32 level;
2499 
2500 	/* Guy has pointed out that this dissection looks wrong.  In
2501 	   the wireshark output for a USER_LEVEL_1 it looks like the
2502 	   info level and container pointer are transposed.  I'm not
2503 	   even sure this structure is a container. */
2504 
2505 	offset = dissect_ndr_uint32(
2506 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
2507 
2508 	offset = dissect_ndr_uint32(
2509 		tvb, offset, pinfo, tree, di, drep, hf_userlevel_size, NULL);
2510 
2511 	offset = dissect_ndr_str_pointer_item(
2512 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
2513 		"Client", hf_userlevel_client, 0);
2514 
2515 	offset = dissect_ndr_str_pointer_item(
2516 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
2517 		"User", hf_userlevel_user, 0);
2518 
2519 	offset = dissect_ndr_uint32(
2520 		tvb, offset, pinfo, tree, di, drep, hf_userlevel_build, NULL);
2521 
2522 	offset = dissect_ndr_uint32(
2523 		tvb, offset, pinfo, tree, di, drep, hf_userlevel_major, NULL);
2524 
2525 	offset = dissect_ndr_uint32(
2526 		tvb, offset, pinfo, tree, di, drep, hf_userlevel_minor, NULL);
2527 
2528 	offset = dissect_ndr_uint32(
2529 		tvb, offset, pinfo, tree, di, drep, hf_userlevel_processor, NULL);
2530 
2531 	return offset;
2532 }
2533 
2534 /*
2535  * USER_LEVEL_CTR structure
2536  */
2537 
2538 static gint ett_USER_LEVEL_CTR = -1;
2539 
2540 int
dissect_USER_LEVEL_CTR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2541 dissect_USER_LEVEL_CTR(tvbuff_t *tvb, int offset,
2542 				  packet_info *pinfo, proto_tree *tree,
2543 				  dcerpc_info *di, guint8 *drep)
2544 {
2545 	proto_tree *subtree;
2546 	proto_item *item;
2547 	guint32 level;
2548 
2549 	if (di->conformant_run)
2550 		return offset;
2551 
2552 	subtree = proto_tree_add_subtree(
2553 		tree, tvb, offset, 0, ett_USER_LEVEL_CTR, &item, "User level container");
2554 
2555 	offset = dissect_ndr_uint32(
2556 		tvb, offset, pinfo, subtree, di, drep, hf_level, &level);
2557 
2558 	switch(level) {
2559 	case 1:
2560 		offset = dissect_ndr_pointer(
2561 			tvb, offset, pinfo, subtree, di, drep,
2562 			dissect_USER_LEVEL_1, NDR_POINTER_UNIQUE,
2563 			"User level 1", -1);
2564 		break;
2565 	default:
2566 		expert_add_info_format(pinfo, item, &ei_level, "Info level %d not decoded", level);
2567 		break;
2568 	}
2569 
2570 	return offset;
2571 }
2572 
2573 /*
2574  * SpoolssOpenPrinterEx
2575  */
2576 
2577 static int
SpoolssOpenPrinterEx_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2578 SpoolssOpenPrinterEx_q(tvbuff_t *tvb, int offset,
2579 				  packet_info *pinfo, proto_tree *tree,
2580 				  dcerpc_info *di, guint8 *drep)
2581 {
2582 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
2583 	char *name;
2584 
2585 	/* Parse packet */
2586 
2587 	dcv->private_data=NULL;
2588 	offset = dissect_ndr_pointer_cb(
2589 		tvb, offset, pinfo, tree, di, drep,
2590 		dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
2591 		"Printer name", hf_printername, cb_wstr_postprocess,
2592 		GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
2593 	name = (char *)dcv->private_data;
2594 
2595 	/* OpenPrinterEx() stores the key/value in se_data */
2596 	if(!pinfo->fd->visited){
2597 		if(!dcv->se_data){
2598 			dcv->se_data = wmem_strdup(wmem_file_scope(),
2599 				name?name:"");
2600 		}
2601 	}
2602 
2603 	offset = dissect_ndr_pointer(
2604 		tvb, offset, pinfo, tree, di, drep,
2605 		dissect_PRINTER_DATATYPE, NDR_POINTER_UNIQUE,
2606 		"Printer datatype", -1);
2607 
2608 	offset = dissect_DEVMODE_CTR(tvb, offset, pinfo, tree, di, drep);
2609 
2610 	name=(char *)dcv->se_data;
2611 	if (name) {
2612 		if (name[0] == '\\' && name[1] == '\\')
2613 			name += 2;
2614 
2615 		/* Determine if we are opening a printer or a print server */
2616 
2617 		if (strchr(name, '\\'))
2618 			offset = dissect_nt_access_mask(
2619 				tvb, offset, pinfo, tree, di, drep,
2620 				hf_access_required,
2621 				&spoolss_printer_access_mask_info, NULL);
2622 		else
2623 			offset = dissect_nt_access_mask(
2624 				tvb, offset, pinfo, tree, di, drep,
2625 				hf_access_required,
2626 				&spoolss_printserver_access_mask_info, NULL);
2627 	} else {
2628 
2629 		/* We can't decide what type of object being opened */
2630 
2631 		offset = dissect_nt_access_mask(
2632 			tvb, offset, pinfo, tree, di, drep, hf_access_required,
2633 			NULL, NULL);
2634 	}
2635 
2636 	offset = dissect_USER_LEVEL_CTR(tvb, offset, pinfo, tree, di, drep);
2637 
2638 	return offset;
2639 }
2640 
2641 static int
SpoolssOpenPrinterEx_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2642 SpoolssOpenPrinterEx_r(tvbuff_t *tvb, int offset,
2643 				  packet_info *pinfo, proto_tree *tree,
2644 				  dcerpc_info *di, guint8 *drep)
2645 {
2646 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
2647 	e_ctx_hnd policy_hnd;
2648 	proto_item *hnd_item;
2649 	guint32 status;
2650 
2651 	/* Parse packet */
2652 
2653 	offset = dissect_nt_policy_hnd(
2654 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, &hnd_item,
2655 		TRUE, FALSE);
2656 
2657 	offset = dissect_doserror(
2658 		tvb, offset, pinfo, tree, di, drep, hf_rc, &status);
2659 
2660 	if( status == 0 ){
2661 		const char *pol_name;
2662 
2663 		if (dcv->se_data){
2664 			pol_name = wmem_strdup_printf(pinfo->pool,
2665 				"OpenPrinterEx(%s)", (char *)dcv->se_data);
2666 		} else {
2667 			pol_name = "Unknown OpenPrinterEx() handle";
2668 		}
2669 		if(!pinfo->fd->visited){
2670 			dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
2671 		}
2672 
2673 		if(hnd_item)
2674 			proto_item_append_text(hnd_item, ": %s", pol_name);
2675 	}
2676 
2677 	return offset;
2678 }
2679 
2680 static const value_string printer_notify_option_data_vals[] = {
2681 	{ PRINTER_NOTIFY_SERVER_NAME, "Server name" },
2682 	{ PRINTER_NOTIFY_PRINTER_NAME, "Printer name" },
2683 	{ PRINTER_NOTIFY_SHARE_NAME, "Share name" },
2684 	{ PRINTER_NOTIFY_PORT_NAME, "Port name" },
2685 	{ PRINTER_NOTIFY_DRIVER_NAME, "Driver name" },
2686 	{ PRINTER_NOTIFY_COMMENT, "Comment" },
2687 	{ PRINTER_NOTIFY_LOCATION, "Location" },
2688 	{ PRINTER_NOTIFY_DEVMODE, "Devmode" },
2689 	{ PRINTER_NOTIFY_SEPFILE, "Sepfile" },
2690 	{ PRINTER_NOTIFY_PRINT_PROCESSOR, "Print processor" },
2691 	{ PRINTER_NOTIFY_PARAMETERS, "Parameters" },
2692 	{ PRINTER_NOTIFY_DATATYPE, "Datatype" },
2693 	{ PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "Security descriptor" },
2694 	{ PRINTER_NOTIFY_ATTRIBUTES, "Attributes" },
2695 	{ PRINTER_NOTIFY_PRIORITY, "Priority" },
2696 	{ PRINTER_NOTIFY_DEFAULT_PRIORITY, "Default priority" },
2697 	{ PRINTER_NOTIFY_START_TIME, "Start time" },
2698 	{ PRINTER_NOTIFY_UNTIL_TIME, "Until time" },
2699 	{ PRINTER_NOTIFY_STATUS, "Status" },
2700 	{ PRINTER_NOTIFY_STATUS_STRING, "Status string" },
2701 	{ PRINTER_NOTIFY_CJOBS, "Cjobs" },
2702 	{ PRINTER_NOTIFY_AVERAGE_PPM, "Average PPM" },
2703 	{ PRINTER_NOTIFY_TOTAL_PAGES, "Total pages" },
2704 	{ PRINTER_NOTIFY_PAGES_PRINTED, "Pages printed" },
2705 	{ PRINTER_NOTIFY_TOTAL_BYTES, "Total bytes" },
2706 	{ PRINTER_NOTIFY_BYTES_PRINTED, "Bytes printed" },
2707 	{ 0, NULL}
2708 };
2709 static value_string_ext printer_notify_option_data_vals_ext = VALUE_STRING_EXT_INIT(printer_notify_option_data_vals);
2710 
2711 static const value_string job_notify_option_data_vals[] = {
2712 	{ JOB_NOTIFY_PRINTER_NAME, "Printer name" },
2713 	{ JOB_NOTIFY_MACHINE_NAME, "Machine name" },
2714 	{ JOB_NOTIFY_PORT_NAME, "Port name" },
2715 	{ JOB_NOTIFY_USER_NAME, "User name" },
2716 	{ JOB_NOTIFY_NOTIFY_NAME, "Notify name" },
2717 	{ JOB_NOTIFY_DATATYPE, "Data type" },
2718 	{ JOB_NOTIFY_PRINT_PROCESSOR, "Print processor" },
2719 	{ JOB_NOTIFY_PARAMETERS, "Parameters" },
2720 	{ JOB_NOTIFY_DRIVER_NAME, "Driver name" },
2721 	{ JOB_NOTIFY_DEVMODE, "Devmode" },
2722 	{ JOB_NOTIFY_STATUS, "Status" },
2723 	{ JOB_NOTIFY_STATUS_STRING, "Status string" },
2724 	{ JOB_NOTIFY_SECURITY_DESCRIPTOR, "Security descriptor" },
2725 	{ JOB_NOTIFY_DOCUMENT, "Document" },
2726 	{ JOB_NOTIFY_PRIORITY, "Priority" },
2727 	{ JOB_NOTIFY_POSITION, "Position" },
2728 	{ JOB_NOTIFY_SUBMITTED, "Submitted" },
2729 	{ JOB_NOTIFY_START_TIME, "Start time" },
2730 	{ JOB_NOTIFY_UNTIL_TIME, "Until time" },
2731 	{ JOB_NOTIFY_TIME, "Time" },
2732 	{ JOB_NOTIFY_TOTAL_PAGES, "Total pages" },
2733 	{ JOB_NOTIFY_PAGES_PRINTED, "Pages printed" },
2734 	{ JOB_NOTIFY_TOTAL_BYTES, "Total bytes" },
2735 	{ JOB_NOTIFY_BYTES_PRINTED, "Bytes printed" },
2736 	{ 0, NULL}
2737 };
2738 static value_string_ext job_notify_option_data_vals_ext = VALUE_STRING_EXT_INIT(job_notify_option_data_vals);
2739 
2740 static int
dissect_notify_field(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,guint16 type,guint16 * data)2741 dissect_notify_field(tvbuff_t *tvb, int offset, packet_info *pinfo,
2742 		     proto_tree *tree, dcerpc_info *di, guint8 *drep, guint16 type,
2743 		     guint16 *data)
2744 {
2745 	guint16 field;
2746 	const char *str;
2747 
2748 	offset = dissect_ndr_uint16(
2749 		tvb, offset, pinfo, NULL, di, drep,
2750 		hf_notify_field, &field);
2751 
2752 	switch(type) {
2753 	case PRINTER_NOTIFY_TYPE:
2754 		str = val_to_str_ext_const(field, &printer_notify_option_data_vals_ext,
2755 				 "Unknown");
2756 		break;
2757 	case JOB_NOTIFY_TYPE:
2758 		str = val_to_str_ext_const(field, &job_notify_option_data_vals_ext,
2759 				 "Unknown");
2760 		break;
2761 	default:
2762 		str = "Unknown notify type";
2763 		break;
2764 	}
2765 
2766 	proto_tree_add_uint_format_value(tree, hf_notify_field, tvb, offset - 2, 2, field, "%s (%d)", str, field);
2767 
2768 	if (data)
2769 		*data = field;
2770 
2771 	return offset;
2772 }
2773 
2774 static int
dissect_NOTIFY_OPTION_DATA(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2775 dissect_NOTIFY_OPTION_DATA(tvbuff_t *tvb, int offset, packet_info *pinfo,
2776 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
2777 {
2778 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
2779 	guint32 count, i;
2780 	guint16 type;
2781 
2782 	if (di->conformant_run)
2783 		return offset;
2784 
2785 	offset = dissect_ndr_uint32(
2786 		tvb, offset, pinfo, tree, di, drep,
2787 		hf_notify_option_data_count, &count);
2788 
2789 	type = GPOINTER_TO_INT(dcv->private_data);
2790 
2791 	for (i = 0; i < count; i++)
2792 		offset = dissect_notify_field(
2793 			tvb, offset, pinfo, tree, di, drep, type, NULL);
2794 
2795 	return offset;
2796 }
2797 
2798 static const value_string printer_notify_types[] =
2799 {
2800 	{ PRINTER_NOTIFY_TYPE, "Printer notify" },
2801 	{ JOB_NOTIFY_TYPE, "Job notify" },
2802 	{ 0, NULL }
2803 };
2804 
2805 static const
notify_plural(int count)2806 char *notify_plural(int count)
2807 {
2808 	if (count == 1)
2809 		return "notification";
2810 
2811 	return "notifies";
2812 }
2813 
2814 static gint ett_NOTIFY_OPTION = -1;
2815 
2816 static int
dissect_NOTIFY_OPTION(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2817 dissect_NOTIFY_OPTION(tvbuff_t *tvb, int offset, packet_info *pinfo,
2818 		      proto_tree *tree, dcerpc_info *di, guint8 *drep)
2819 {
2820 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
2821 	proto_item *item;
2822 	proto_tree *subtree;
2823 	guint16 type;
2824 	guint32 count;
2825 
2826 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_NOTIFY_OPTION, &item, "Notify Option");
2827 
2828 	offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, di, drep,
2829 				    hf_notify_option_type, &type);
2830 
2831 	proto_item_append_text(
2832 		item, ": %s", val_to_str(type, printer_notify_types,
2833 					 "Unknown (%d)"));
2834 
2835 	offset = dissect_ndr_uint16(tvb, offset, pinfo, subtree, di, drep,
2836 				    hf_notify_option_reserved1, NULL);
2837 
2838 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
2839 				    hf_notify_option_reserved2, NULL);
2840 
2841 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
2842 				    hf_notify_option_reserved3, NULL);
2843 
2844 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
2845 				    hf_notify_option_count, &count);
2846 
2847 	proto_item_append_text(
2848 		item, ", %d %s", count, notify_plural(count));
2849 
2850 	dcv->private_data = GINT_TO_POINTER((int)type);
2851 
2852 	offset = dissect_ndr_pointer(
2853 		tvb, offset, pinfo, subtree, di, drep,
2854 		dissect_NOTIFY_OPTION_DATA, NDR_POINTER_UNIQUE,
2855 		"Notify Option Data", -1);
2856 
2857 	return offset;
2858 }
2859 
2860 static int
dissect_NOTIFY_OPTIONS_ARRAY(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2861 dissect_NOTIFY_OPTIONS_ARRAY(tvbuff_t *tvb, int offset,
2862 			     packet_info *pinfo, proto_tree *tree,
2863 			     dcerpc_info *di, guint8 *drep)
2864 {
2865 	/* Why is a check for di->conformant_run not required here? */
2866 
2867 	offset = dissect_ndr_ucarray(
2868 		tvb, offset, pinfo, tree, di, drep, dissect_NOTIFY_OPTION);
2869 
2870 	return offset;
2871 }
2872 
2873 static gint ett_notify_options_flags = -1;
2874 
2875 static const true_false_string tfs_notify_options_flags_refresh = {
2876 	"Data for all monitored fields is present",
2877 	"Data for all monitored fields not present"
2878 };
2879 
2880 static int
dissect_notify_options_flags(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2881 dissect_notify_options_flags(tvbuff_t *tvb, int offset, packet_info *pinfo,
2882 			     proto_tree *tree, dcerpc_info *di, guint8 *drep)
2883 {
2884 	guint32 flags;
2885 	static int * const hf_flags[] = {
2886 		&hf_notify_options_flags_refresh,
2887 		NULL
2888 	};
2889 
2890 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &flags);
2891 
2892 	proto_tree_add_bitmask_value_with_flags(tree, tvb, offset - 4, hf_notify_options_flags,
2893 					ett_notify_options_flags, hf_flags, flags, BMT_NO_APPEND);
2894 
2895 	return offset;
2896 }
2897 
2898 int
dissect_NOTIFY_OPTIONS_ARRAY_CTR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)2899 dissect_NOTIFY_OPTIONS_ARRAY_CTR(tvbuff_t *tvb, int offset,
2900 				 packet_info *pinfo, proto_tree *tree,
2901 				 dcerpc_info *di, guint8 *drep)
2902 {
2903 	if (di->conformant_run)
2904 		return offset;
2905 
2906 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2907 				    hf_notify_options_version, NULL);
2908 
2909 	offset = dissect_notify_options_flags(tvb, offset, pinfo, tree, di, drep);
2910 
2911 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
2912 				    hf_notify_options_count, NULL);
2913 
2914 	offset = dissect_ndr_pointer(
2915 		tvb, offset, pinfo, tree, di, drep,
2916 		dissect_NOTIFY_OPTIONS_ARRAY, NDR_POINTER_UNIQUE,
2917 		"Notify Options Array", -1);
2918 
2919 	return offset;
2920 }
2921 
2922 /*
2923  * SpoolssRFFPCNEX
2924  */
2925 
2926 static gint ett_rffpcnex_flags = -1;
2927 
2928 static int hf_rffpcnex_flags = -1;
2929 static int hf_rffpcnex_options = -1;
2930 
2931 static int hf_rffpcnex_flags_add_printer = -1;
2932 static int hf_rffpcnex_flags_set_printer = -1;
2933 static int hf_rffpcnex_flags_delete_printer = -1;
2934 static int hf_rffpcnex_flags_failed_printer_connection = -1;
2935 
2936 static const true_false_string tfs_rffpcnex_flags_add_printer = {
2937 	"Notify on add printer",
2938 	"Don't notify on add printer"
2939 };
2940 
2941 static const true_false_string tfs_rffpcnex_flags_set_printer = {
2942 	"Notify on set printer",
2943 	"Don't notify on set printer"
2944 };
2945 
2946 static const true_false_string tfs_rffpcnex_flags_delete_printer = {
2947 	"Notify on delete printer",
2948 	"Don't notify on delete printer"
2949 };
2950 
2951 static const true_false_string tfs_rffpcnex_flags_failed_connection_printer = {
2952 	"Notify on failed printer connection",
2953 	"Don't notify on failed printer connection"
2954 };
2955 
2956 static int hf_rffpcnex_flags_add_job = -1;
2957 static int hf_rffpcnex_flags_set_job = -1;
2958 static int hf_rffpcnex_flags_delete_job = -1;
2959 static int hf_rffpcnex_flags_write_job = -1;
2960 
2961 static const true_false_string tfs_rffpcnex_flags_add_job = {
2962 	"Notify on add job",
2963 	"Don't notify on add job"
2964 };
2965 
2966 static const true_false_string tfs_rffpcnex_flags_set_job = {
2967 	"Notify on set job",
2968 	"Don't notify on set job"
2969 };
2970 
2971 static const true_false_string tfs_rffpcnex_flags_delete_job = {
2972 	"Notify on delete job",
2973 	"Don't notify on delete job"
2974 };
2975 
2976 static const true_false_string tfs_rffpcnex_flags_write_job = {
2977 	"Notify on writejob",
2978 	"Don't notify on write job"
2979 };
2980 
2981 static int hf_rffpcnex_flags_add_form = -1;
2982 static int hf_rffpcnex_flags_set_form = -1;
2983 static int hf_rffpcnex_flags_delete_form = -1;
2984 
2985 static const true_false_string tfs_rffpcnex_flags_add_form = {
2986 	"Notify on add form",
2987 	"Don't notify on add form"
2988 };
2989 
2990 static const true_false_string tfs_rffpcnex_flags_set_form = {
2991 	"Notify on set form",
2992 	"Don't notify on set form"
2993 };
2994 
2995 static const true_false_string tfs_rffpcnex_flags_delete_form = {
2996 	"Notify on delete form",
2997 	"Don't notify on delete form"
2998 };
2999 
3000 static int hf_rffpcnex_flags_add_port = -1;
3001 static int hf_rffpcnex_flags_configure_port = -1;
3002 static int hf_rffpcnex_flags_delete_port = -1;
3003 
3004 static const true_false_string tfs_rffpcnex_flags_add_port = {
3005 	"Notify on add port",
3006 	"Don't notify on add port"
3007 };
3008 
3009 static const true_false_string tfs_rffpcnex_flags_configure_port = {
3010 	"Notify on configure port",
3011 	"Don't notify on configure port"
3012 };
3013 
3014 static const true_false_string tfs_rffpcnex_flags_delete_port = {
3015 	"Notify on delete port",
3016 	"Don't notify on delete port"
3017 };
3018 
3019 static int hf_rffpcnex_flags_add_print_processor = -1;
3020 static int hf_rffpcnex_flags_delete_print_processor = -1;
3021 
3022 static const true_false_string tfs_rffpcnex_flags_add_print_processor = {
3023 	"Notify on add driver",
3024 	"Don't notify on add driver"
3025 };
3026 
3027 static const true_false_string tfs_rffpcnex_flags_delete_print_processor = {
3028 	"Notify on add driver",
3029 	"Don't notify on add driver"
3030 };
3031 
3032 static int hf_rffpcnex_flags_add_driver = -1;
3033 static int hf_rffpcnex_flags_set_driver = -1;
3034 static int hf_rffpcnex_flags_delete_driver = -1;
3035 
3036 static const true_false_string tfs_rffpcnex_flags_add_driver = {
3037 	"Notify on add driver",
3038 	"Don't notify on add driver"
3039 };
3040 
3041 static const true_false_string tfs_rffpcnex_flags_set_driver = {
3042 	"Notify on set driver",
3043 	"Don't notify on set driver"
3044 };
3045 
3046 static const true_false_string tfs_rffpcnex_flags_delete_driver = {
3047 	"Notify on delete driver",
3048 	"Don't notify on delete driver"
3049 };
3050 
3051 static int hf_rffpcnex_flags_timeout = -1;
3052 
3053 static const true_false_string tfs_rffpcnex_flags_timeout = {
3054 	"Notify on timeout",
3055 	"Don't notify on timeout"
3056 };
3057 
3058 static int
SpoolssRFFPCNEX_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3059 SpoolssRFFPCNEX_q(tvbuff_t *tvb, int offset,
3060 			     packet_info *pinfo, proto_tree *tree,
3061 			     dcerpc_info *di, guint8 *drep)
3062 {
3063 	guint32 flags;
3064 	static int * const hf_flags[] = {
3065 		&hf_rffpcnex_flags_timeout,
3066 		&hf_rffpcnex_flags_delete_driver,
3067 		&hf_rffpcnex_flags_set_driver,
3068 		&hf_rffpcnex_flags_add_driver,
3069 		&hf_rffpcnex_flags_delete_print_processor,
3070 		&hf_rffpcnex_flags_add_print_processor,
3071 		&hf_rffpcnex_flags_delete_port,
3072 		&hf_rffpcnex_flags_configure_port,
3073 		&hf_rffpcnex_flags_add_port,
3074 		&hf_rffpcnex_flags_delete_form,
3075 		&hf_rffpcnex_flags_set_form,
3076 		&hf_rffpcnex_flags_add_form,
3077 		&hf_rffpcnex_flags_write_job,
3078 		&hf_rffpcnex_flags_delete_job,
3079 		&hf_rffpcnex_flags_set_job,
3080 		&hf_rffpcnex_flags_add_job,
3081 		&hf_rffpcnex_flags_failed_printer_connection,
3082 		&hf_rffpcnex_flags_delete_printer,
3083 		&hf_rffpcnex_flags_set_printer,
3084 		&hf_rffpcnex_flags_add_printer,
3085 		NULL
3086 	};
3087 
3088 	/* Parse packet */
3089 
3090 	offset = dissect_nt_policy_hnd(
3091 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3092 		FALSE, FALSE);
3093 
3094 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &flags);
3095 
3096 	proto_tree_add_bitmask_value(tree, tvb, offset - 4, hf_rffpcnex_flags,
3097 					ett_rffpcnex_flags, hf_flags, flags);
3098 
3099 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3100 				    hf_rffpcnex_options, NULL);
3101 
3102 	offset = dissect_ndr_str_pointer_item(
3103 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
3104 		"Server", hf_servername, 0);
3105 
3106 	offset = dissect_ndr_uint32(
3107 		tvb, offset, pinfo, tree, di, drep, hf_printerlocal, NULL);
3108 
3109 	offset = dissect_ndr_pointer(
3110 		tvb, offset, pinfo, tree, di, drep,
3111 		dissect_NOTIFY_OPTIONS_ARRAY_CTR, NDR_POINTER_UNIQUE,
3112 		"Notify Options Container", -1);
3113 
3114 	return offset;
3115 }
3116 
3117 static int
SpoolssRFFPCNEX_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3118 SpoolssRFFPCNEX_r(tvbuff_t *tvb, int offset,
3119 			     packet_info *pinfo, proto_tree *tree,
3120 			     dcerpc_info *di, guint8 *drep)
3121 {
3122 	/* Parse packet */
3123 
3124 	offset = dissect_doserror(
3125 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3126 
3127 	return offset;
3128 }
3129 
3130 /*
3131  * SpoolssReplyOpenPrinter
3132  */
3133 
3134 static int
SpoolssReplyOpenPrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3135 SpoolssReplyOpenPrinter_q(tvbuff_t *tvb, int offset,
3136 				     packet_info *pinfo, proto_tree *tree,
3137 				     dcerpc_info *di, guint8 *drep)
3138 {
3139 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3140 	guint32 printerlocal;
3141 	char *name;
3142 
3143 	/* Parse packet */
3144 	name=NULL;
3145 	offset = dissect_ndr_cvstring(
3146 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
3147 		hf_servername, TRUE, &name);
3148 	/* ReplyOpenPrinter() stores the printername in se_data */
3149 	if(!pinfo->fd->visited){
3150 		if(!dcv->se_data){
3151 			if(name){
3152 				dcv->se_data = wmem_strdup(wmem_file_scope(), name);
3153 			}
3154 		}
3155 	}
3156 
3157 	if (name)
3158 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", name);
3159 
3160 	offset = dissect_ndr_uint32(
3161 		tvb, offset, pinfo, tree, di, drep, hf_printerlocal,
3162 		&printerlocal);
3163 
3164 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
3165 				    hf_printerdata_type, NULL);
3166 
3167 	offset = dissect_ndr_uint32(
3168 		tvb, offset, pinfo, tree, di, drep, hf_replyopenprinter_unk0,
3169 		NULL);
3170 
3171 	offset = dissect_ndr_uint32(
3172 		tvb, offset, pinfo, tree, di, drep, hf_replyopenprinter_unk1,
3173 		NULL);
3174 
3175 	return offset;
3176 }
3177 
3178 static int
SpoolssReplyOpenPrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3179 SpoolssReplyOpenPrinter_r(tvbuff_t *tvb, int offset,
3180 				     packet_info *pinfo, proto_tree *tree,
3181 				     dcerpc_info *di, guint8 *drep)
3182 {
3183 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3184 	e_ctx_hnd policy_hnd;
3185 	proto_item *hnd_item;
3186 	guint32 status;
3187 
3188 	/* Parse packet */
3189 
3190 	offset = dissect_nt_policy_hnd(
3191 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, &hnd_item,
3192 		TRUE, FALSE);
3193 
3194 	offset = dissect_doserror(
3195 		tvb, offset, pinfo, tree, di, drep, hf_rc, &status);
3196 
3197 	if( status == 0 ){
3198 		const char *pol_name;
3199 
3200 		if (dcv->se_data){
3201 			pol_name = wmem_strdup_printf(pinfo->pool,
3202 				"ReplyOpenPrinter(%s)", (char *)dcv->se_data);
3203 		} else {
3204 			pol_name = "Unknown ReplyOpenPrinter() handle";
3205 		}
3206 		if(!pinfo->fd->visited){
3207 			dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
3208 		}
3209 
3210 		if(hnd_item)
3211 			proto_item_append_text(hnd_item, ": %s", pol_name);
3212 	}
3213 
3214 	return offset;
3215 }
3216 
3217 /*
3218  * SpoolssGetPrinter
3219  */
3220 
3221 
3222 static int
SpoolssGetPrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3223 SpoolssGetPrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
3224 			       proto_tree *tree, dcerpc_info *di, guint8 *drep )
3225 {
3226 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3227 	guint32 level;
3228 
3229 	/* Parse packet */
3230 
3231 	offset = dissect_nt_policy_hnd(
3232 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3233  		FALSE, FALSE);
3234 
3235 	offset = dissect_ndr_uint32(
3236 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
3237 
3238 	/* GetPrinter() stores the level in se_data */
3239 	if(!pinfo->fd->visited){
3240 			dcv->se_data = GINT_TO_POINTER((int)level);
3241 	}
3242 
3243 
3244 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3245 
3246 	offset = dissect_spoolss_buffer(
3247 		tvb, offset, pinfo, tree, di, drep, NULL);
3248 
3249 	offset = dissect_ndr_uint32(
3250 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
3251 
3252 	return offset;
3253 }
3254 
3255 static gint ett_PRINTER_INFO = -1;
3256 
3257 static int
SpoolssGetPrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3258 SpoolssGetPrinter_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
3259 				proto_tree *tree, dcerpc_info *di, guint8 *drep)
3260 {
3261 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3262 	BUFFER buffer;
3263 	gint16 level = GPOINTER_TO_INT(dcv->se_data);
3264 	proto_item *item = NULL;
3265 	proto_tree *subtree = NULL;
3266 
3267 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3268 
3269 	/* Parse packet */
3270 
3271 	offset = dissect_spoolss_buffer(
3272 		tvb, offset, pinfo, tree, di, drep, &buffer);
3273 
3274 	if (buffer.tvb) {
3275 		subtree = proto_tree_add_subtree_format( buffer.tree, buffer.tvb, 0, -1, ett_PRINTER_INFO, &item, "Print info level %d", level);
3276 
3277 		switch(level) {
3278 		case 0:
3279 			dissect_PRINTER_INFO_0(
3280 				buffer.tvb, 0, pinfo, subtree, di, drep);
3281 			break;
3282 		case 1:
3283 			dissect_PRINTER_INFO_1(
3284 				buffer.tvb, 0, pinfo, subtree, di, drep);
3285 			break;
3286 		case 2:
3287 			dissect_PRINTER_INFO_2(
3288 				buffer.tvb, 0, pinfo, subtree, di, drep);
3289 			break;
3290 		case 3:
3291 			dissect_PRINTER_INFO_3(
3292 				buffer.tvb, 0, pinfo, subtree, di, drep);
3293 			break;
3294 		case 5:
3295 			dissect_PRINTER_INFO_5(
3296 				buffer.tvb, 0, pinfo, subtree, di, drep);
3297 			break;
3298 		case 7:
3299 			dissect_PRINTER_INFO_7(
3300 				buffer.tvb, 0, pinfo, subtree, di, drep);
3301 			break;
3302 		default:
3303 			expert_add_info(pinfo, item, &ei_printer_info_level);
3304 			break;
3305 		}
3306 	}
3307 
3308 	offset = dissect_ndr_uint32(
3309 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
3310 
3311 	offset = dissect_doserror(
3312 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3313 
3314 	return offset;
3315 }
3316 
3317 /*
3318  * SEC_DESC_BUF
3319  */
3320 
3321 static gint ett_SEC_DESC_BUF = -1;
3322 
3323 static int hf_secdescbuf_maxlen = -1;
3324 static int hf_secdescbuf_undoc = -1;
3325 static int hf_secdescbuf_len = -1;
3326 
3327 static int
dissect_SEC_DESC_BUF(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3328 dissect_SEC_DESC_BUF(tvbuff_t *tvb, int offset, packet_info *pinfo,
3329 		     proto_tree *tree, dcerpc_info *di, guint8 *drep)
3330 {
3331 	proto_tree *subtree;
3332 	guint32 len;
3333 
3334 	/* XXX: I think this is really a array of bytes which can be
3335 	   dissected using dissect_ndr_cvstring().  The dissected data
3336 	   can be passed to dissect_nt_sec_desc().  The problem is that
3337 	   dissect_nt_cvstring() passes back a char * where it really
3338 	   should pass back a tvb. */
3339 
3340 	subtree = proto_tree_add_subtree(
3341 		tree, tvb, offset, 0, ett_SEC_DESC_BUF, NULL, "Security descriptor buffer");
3342 
3343 	offset = dissect_ndr_uint32(
3344 		tvb, offset, pinfo, subtree, di, drep,
3345 		hf_secdescbuf_maxlen, NULL);
3346 
3347 	offset = dissect_ndr_uint32(
3348 		tvb, offset, pinfo, subtree, di, drep,
3349 		hf_secdescbuf_undoc, NULL);
3350 
3351 	offset = dissect_ndr_uint32(
3352 		tvb, offset, pinfo, subtree, di, drep,
3353 		hf_secdescbuf_len, &len);
3354 
3355 	dissect_nt_sec_desc(
3356 		tvb, offset, pinfo, subtree, drep, TRUE, len,
3357 		&spoolss_printer_access_mask_info);
3358 
3359 	offset += len;
3360 
3361 	return offset;
3362 }
3363 
3364 /*
3365  * SPOOL_PRINTER_INFO_LEVEL
3366  */
3367 
3368 static gint ett_SPOOL_PRINTER_INFO_LEVEL = -1;
3369 
3370 /* spool printer info */
3371 
3372 static int hf_spool_printer_info_devmode_ptr = -1;
3373 static int hf_spool_printer_info_secdesc_ptr = -1;
3374 
3375 int
dissect_SPOOL_PRINTER_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3376 dissect_SPOOL_PRINTER_INFO(tvbuff_t *tvb, int offset, packet_info *pinfo,
3377 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
3378 {
3379 	proto_tree *subtree;
3380 	guint32 level;
3381 	proto_tree *item;
3382 
3383 	subtree = proto_tree_add_subtree(
3384 		tree, tvb, offset, 0, ett_SPOOL_PRINTER_INFO_LEVEL, &item, "Spool printer info level");
3385 
3386 	offset = dissect_ndr_uint32(
3387 		tvb, offset, pinfo, subtree, di, drep, hf_level, &level);
3388 
3389 	switch(level) {
3390 	case 3: {
3391 		guint32 devmode_ptr, secdesc_ptr;
3392 
3393 		/* I can't seem to get this working with the correct
3394 		   dissect_ndr_pointer() function so let's cheat and
3395 		   dissect the pointers by hand. )-: */
3396 
3397 		offset = dissect_ndr_uint32(
3398 			tvb, offset, pinfo, subtree, di, drep,
3399 			hf_spool_printer_info_devmode_ptr,
3400 			&devmode_ptr);
3401 
3402 		offset = dissect_ndr_uint32(
3403 			tvb, offset, pinfo, subtree, di, drep,
3404 			hf_spool_printer_info_secdesc_ptr,
3405 			&secdesc_ptr);
3406 
3407 		if (devmode_ptr)
3408 			offset = dissect_DEVMODE_CTR(
3409 				tvb, offset, pinfo, subtree, di, drep);
3410 
3411 		if (secdesc_ptr)
3412 			offset = dissect_SEC_DESC_BUF(
3413 				tvb, offset, pinfo, subtree, di, drep);
3414 
3415 	break;
3416 	}
3417 	case 2:
3418 	default:
3419 		expert_add_info_format(pinfo, item, &ei_spool_printer_info_level, "Unknown spool printer info level %d", level);
3420 		break;
3421 	}
3422 
3423 	return offset;
3424 }
3425 
3426 /*
3427  * SpoolssSetPrinter
3428  */
3429 
3430 static int hf_setprinter_cmd = -1;
3431 
3432 static const value_string setprinter_cmd_vals[] = {
3433 	{ SPOOLSS_PRINTER_CONTROL_UNPAUSE, "Unpause" },
3434 	{ SPOOLSS_PRINTER_CONTROL_PAUSE, "Pause" },
3435 	{ SPOOLSS_PRINTER_CONTROL_RESUME, "Resume" },
3436 	{ SPOOLSS_PRINTER_CONTROL_PURGE, "Purge" },
3437 	{ SPOOLSS_PRINTER_CONTROL_SET_STATUS, "Set status" },
3438 	{ 0, NULL }
3439 };
3440 
3441 static int
SpoolssSetPrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3442 SpoolssSetPrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
3443 			       proto_tree *tree, dcerpc_info *di, guint8 *drep)
3444 {
3445 	guint32 level;
3446 
3447 	/* Parse packet */
3448 
3449 	offset = dissect_nt_policy_hnd(
3450 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3451 		FALSE, FALSE);
3452 
3453 	offset = dissect_ndr_uint32(
3454 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
3455 
3456 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3457 
3458 	offset = dissect_SPOOL_PRINTER_INFO(
3459 		tvb, offset, pinfo, tree, di, drep);
3460 
3461 	offset = dissect_ndr_uint32(
3462 		tvb, offset, pinfo, tree, di, drep,
3463 		hf_setprinter_cmd, NULL);
3464 
3465 	return offset;
3466 }
3467 
3468 static int
SpoolssSetPrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3469 SpoolssSetPrinter_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
3470 				proto_tree *tree, dcerpc_info *di, guint8 *drep)
3471 {
3472 	/* Parse packet */
3473 
3474 	offset = dissect_doserror(
3475 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3476 
3477 	return offset;
3478 }
3479 
3480 /*
3481  * FORM_REL
3482  */
3483 
3484 static const value_string form_type_vals[] =
3485 {
3486 	{ SPOOLSS_FORM_USER, "User" },
3487 	{ SPOOLSS_FORM_BUILTIN, "Builtin" },
3488 	{ SPOOLSS_FORM_PRINTER, "Printer" },
3489 	{ 0, NULL }
3490 };
3491 
3492 static gint ett_FORM_REL = -1;
3493 
3494 static int
dissect_FORM_REL(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int struct_start)3495 dissect_FORM_REL(tvbuff_t *tvb, int offset, packet_info *pinfo,
3496 			    proto_tree *tree, dcerpc_info *di, guint8 *drep, int struct_start)
3497 {
3498 	proto_item *item;
3499 	proto_tree *subtree;
3500 	guint32 flags;
3501 	int item_start = offset;
3502 	char *name = NULL;
3503 
3504 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_FORM_REL, &item, "Form");
3505 
3506 	offset = dissect_ndr_uint32(
3507 		tvb, offset, pinfo, subtree, di, drep, hf_form_flags, &flags);
3508 
3509 	offset = dissect_spoolss_relstr(
3510 		tvb, offset, pinfo, subtree, di, drep, hf_form_name,
3511 		struct_start, &name);
3512 
3513 	if (name) {
3514 		proto_item_append_text(item, ": %s", name);
3515 	}
3516 
3517 	offset = dissect_ndr_uint32(
3518 		tvb, offset, pinfo, subtree, di, drep,
3519 		hf_form_width, NULL);
3520 
3521 	offset = dissect_ndr_uint32(
3522 		tvb, offset, pinfo, subtree, di, drep,
3523 		hf_form_height, NULL);
3524 
3525 	offset = dissect_ndr_uint32(
3526 		tvb, offset, pinfo, subtree, di, drep,
3527 		hf_form_left_margin, NULL);
3528 
3529 	offset = dissect_ndr_uint32(
3530 		tvb, offset, pinfo, subtree, di, drep,
3531 		hf_form_top_margin, NULL);
3532 
3533 	offset = dissect_ndr_uint32(
3534 		tvb, offset, pinfo, subtree, di, drep,
3535 		hf_form_horiz_len, NULL);
3536 
3537 	offset = dissect_ndr_uint32(
3538 		tvb, offset, pinfo, subtree, di, drep,
3539 		hf_form_vert_len, NULL);
3540 
3541 	proto_item_set_len(item, offset - item_start);
3542 
3543 	return offset;
3544 }
3545 
3546 /*
3547  * SpoolssEnumForms
3548  */
3549 
3550 static int
SpoolssEnumForms_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3551 SpoolssEnumForms_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
3552 			      proto_tree *tree, dcerpc_info *di, guint8 *drep)
3553 {
3554 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3555 	guint32 level;
3556 	proto_item *hidden_item;
3557 
3558 	hidden_item = proto_tree_add_uint(
3559 		tree, hf_form, tvb, offset, 0, 1);
3560 	proto_item_set_hidden(hidden_item);
3561 
3562 	/* Parse packet */
3563 
3564 	offset = dissect_nt_policy_hnd(
3565 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3566 		FALSE, FALSE);
3567 
3568 	offset = dissect_ndr_uint32(
3569 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
3570 
3571 	/* EnumForms() stores the level in se_data */
3572 	if(!pinfo->fd->visited){
3573 			dcv->se_data = GINT_TO_POINTER((int)level);
3574 	}
3575 
3576 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3577 
3578 	offset = dissect_spoolss_buffer(
3579 		tvb, offset, pinfo, tree, di, drep, NULL);
3580 
3581 	offset = dissect_ndr_uint32(
3582 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
3583 
3584 	return offset;
3585 }
3586 
3587 static int
SpoolssEnumForms_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3588 SpoolssEnumForms_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
3589 			      proto_tree *tree, dcerpc_info *di, guint8 *drep)
3590 {
3591 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3592 	BUFFER buffer;
3593 	guint32 level = GPOINTER_TO_UINT(dcv->se_data), i, count;
3594 	int buffer_offset;
3595 	proto_item *hidden_item;
3596 
3597 	hidden_item = proto_tree_add_uint(
3598 		tree, hf_form, tvb, offset, 0, 1);
3599 	proto_item_set_hidden(hidden_item);
3600 
3601 	/* Parse packet */
3602 
3603 	offset = dissect_spoolss_buffer(
3604 		tvb, offset, pinfo, tree, di, drep, &buffer);
3605 
3606 	offset = dissect_ndr_uint32(
3607 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
3608 
3609 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3610 
3611 	offset = dissect_ndr_uint32(
3612 		tvb, offset, pinfo, tree, di, drep, hf_enumforms_num, &count);
3613 
3614 	/* Unfortunately this array isn't in NDR format so we can't
3615 	   use prs_array().  The other weird thing is the
3616 	   struct_start being inside the loop rather than outside.
3617 	   Very strange. */
3618 
3619 	buffer_offset = 0;
3620 
3621 	for (i = 0; i < count; i++) {
3622 		int struct_start = buffer_offset;
3623 
3624 		buffer_offset = dissect_FORM_REL(
3625 			buffer.tvb, buffer_offset, pinfo, buffer.tree, di, drep,
3626 			struct_start);
3627 	}
3628 
3629 	offset = dissect_doserror(
3630 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3631 
3632 	return offset;
3633 }
3634 
3635 /*
3636  * SpoolssDeletePrinter
3637  */
3638 
3639 static int
SpoolssDeletePrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3640 SpoolssDeletePrinter_q(tvbuff_t *tvb, int offset,
3641 				  packet_info *pinfo, proto_tree *tree,
3642 				  dcerpc_info *di, guint8 *drep)
3643 {
3644 	/* Parse packet */
3645 
3646 	offset = dissect_nt_policy_hnd(
3647 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3648 		FALSE, FALSE);
3649 
3650 	return offset;
3651 }
3652 
3653 static int
SpoolssDeletePrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3654 SpoolssDeletePrinter_r(tvbuff_t *tvb, int offset,
3655 				  packet_info *pinfo, proto_tree *tree,
3656 				  dcerpc_info *di, guint8 *drep)
3657 {
3658 	/* Parse packet */
3659 
3660 	offset = dissect_nt_policy_hnd(
3661 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3662 		FALSE, FALSE);
3663 
3664 	offset = dissect_doserror(
3665 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3666 
3667 	return offset;
3668 }
3669 
3670 static int
SpoolssAddPrinterEx_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3671 SpoolssAddPrinterEx_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
3672 				 proto_tree *tree, dcerpc_info *di, guint8 *drep)
3673 {
3674 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3675 	e_ctx_hnd policy_hnd;
3676 	proto_item *hnd_item;
3677 	guint32 status;
3678 
3679 	/* Parse packet */
3680 
3681 	offset = dissect_nt_policy_hnd(
3682 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, &hnd_item,
3683 		TRUE, FALSE);
3684 
3685 	offset = dissect_doserror(
3686 		tvb, offset, pinfo, tree, di, drep, hf_rc, &status);
3687 
3688 	if( status == 0 ){
3689 		const char *pol_name;
3690 
3691 		if (dcv->se_data){
3692 			pol_name = wmem_strdup_printf(pinfo->pool,
3693 				"AddPrinterEx(%s)", (char *)dcv->se_data);
3694 		} else {
3695 			pol_name = "Unknown AddPrinterEx() handle";
3696 		}
3697 		if(!pinfo->fd->visited){
3698 			dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
3699 		}
3700 
3701 		if(hnd_item)
3702 			proto_item_append_text(hnd_item, ": %s", pol_name);
3703 	}
3704 
3705 	return offset;
3706 }
3707 
3708 /*
3709  * SpoolssEnumPrinterData
3710  */
3711 
3712 static int hf_enumprinterdata_enumindex = -1;
3713 static int hf_enumprinterdata_value_offered = -1;
3714 static int hf_enumprinterdata_data_offered = -1;
3715 static int hf_enumprinterdata_value_len = -1;
3716 static int hf_enumprinterdata_value_needed = -1;
3717 static int hf_enumprinterdata_data_needed = -1;
3718 
3719 static int
SpoolssEnumPrinterData_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3720 SpoolssEnumPrinterData_q(tvbuff_t *tvb, int offset,
3721 				    packet_info *pinfo, proto_tree *tree,
3722 				    dcerpc_info *di, guint8 *drep)
3723 {
3724 	guint32 ndx;
3725 	proto_item *hidden_item;
3726 
3727 	hidden_item = proto_tree_add_uint(
3728 		tree, hf_printerdata, tvb, offset, 0, 1);
3729 	proto_item_set_hidden(hidden_item);
3730 
3731 	/* Parse packet */
3732 
3733 	offset = dissect_nt_policy_hnd(
3734 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
3735 		FALSE, FALSE);
3736 
3737 	offset = dissect_ndr_uint32(
3738 		tvb, offset, pinfo, tree, di, drep,
3739 		hf_enumprinterdata_enumindex, &ndx);
3740 
3741 	col_append_fstr(pinfo->cinfo, COL_INFO, ", index %d", ndx);
3742 
3743 	offset = dissect_ndr_uint32(
3744 		tvb, offset, pinfo, tree, di, drep,
3745 		hf_enumprinterdata_value_offered, NULL);
3746 
3747 	offset = dissect_ndr_uint32(
3748 		tvb, offset, pinfo, tree, di, drep,
3749 		hf_enumprinterdata_data_offered, NULL);
3750 
3751 	return offset;
3752 }
3753 
3754 static int
SpoolssEnumPrinterData_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3755 SpoolssEnumPrinterData_r(tvbuff_t *tvb, int offset,
3756 				    packet_info *pinfo, proto_tree *tree,
3757 				    dcerpc_info *di, guint8 *drep)
3758 {
3759 	guint32 value_len, type;
3760 	char *value;
3761 	proto_item *value_item;
3762 	proto_tree *value_subtree;
3763 	proto_item *hidden_item;
3764 
3765 	hidden_item = proto_tree_add_uint(
3766 		tree, hf_printerdata, tvb, offset, 0, 1);
3767 	proto_item_set_hidden(hidden_item);
3768 
3769 	/* Parse packet */
3770 
3771 	value_subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_printerdata_value, &value_item, "Value");
3772 
3773 	offset = dissect_ndr_uint32(
3774 		tvb, offset, pinfo, value_subtree, di, drep,
3775 		hf_enumprinterdata_value_len, &value_len);
3776 
3777 	if (value_len) {
3778 		dissect_spoolss_uint16uni(
3779 			tvb, offset, pinfo, value_subtree, drep, &value, hf_value_name);
3780 
3781 		offset += value_len * 2;
3782 
3783 		if (value && value[0])
3784 			col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", value);
3785 
3786 		proto_item_append_text(value_item, ": %s", value);
3787 
3788 		hidden_item = proto_tree_add_string(
3789 			tree, hf_printerdata_value, tvb, offset, 0, value);
3790 		proto_item_set_hidden(hidden_item);
3791 	}
3792 
3793 	proto_item_set_len(value_item, value_len * 2 + 4);
3794 
3795 	offset = dissect_ndr_uint32(
3796 		tvb, offset, pinfo, value_subtree, di, drep,
3797 		hf_enumprinterdata_value_needed, NULL);
3798 
3799 	offset = dissect_ndr_uint32(
3800 		tvb, offset, pinfo, tree, di, drep, hf_printerdata_type, &type);
3801 
3802 	offset = dissect_printerdata_data(
3803 		tvb, offset, pinfo, tree, di, drep, type);
3804 
3805 	offset = dissect_ndr_uint32(
3806 		tvb, offset, pinfo, tree, di, drep,
3807 		hf_enumprinterdata_data_needed, NULL);
3808 
3809 	offset = dissect_doserror(
3810 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3811 
3812 	return offset;
3813 }
3814 
3815 /*
3816  * SpoolssEnumPrinters
3817  */
3818 
3819 static gint ett_enumprinters_flags = -1;
3820 
3821 static int hf_enumprinters_flags = -1;
3822 static int hf_enumprinters_flags_local = -1;
3823 static int hf_enumprinters_flags_name = -1;
3824 static int hf_enumprinters_flags_shared = -1;
3825 static int hf_enumprinters_flags_default = -1;
3826 static int hf_enumprinters_flags_connections = -1;
3827 static int hf_enumprinters_flags_network = -1;
3828 static int hf_enumprinters_flags_remote = -1;
3829 
3830 static int
SpoolssEnumPrinters_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3831 SpoolssEnumPrinters_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
3832 				 proto_tree *tree, dcerpc_info *di, guint8 *drep)
3833 {
3834 	guint32 level, flags;
3835 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3836 	static int * const hf_flags[] = {
3837 		&hf_enumprinters_flags_network,
3838 		&hf_enumprinters_flags_shared,
3839 		&hf_enumprinters_flags_remote,
3840 		&hf_enumprinters_flags_name,
3841 		&hf_enumprinters_flags_connections,
3842 		&hf_enumprinters_flags_local,
3843 		&hf_enumprinters_flags_default,
3844 		NULL
3845 	};
3846 
3847 	/* Parse packet */
3848 
3849 	offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, di, drep, -1, &flags);
3850 
3851 	proto_tree_add_bitmask_value(tree, tvb, offset - 4, hf_enumprinters_flags,
3852 					ett_enumprinters_flags, hf_flags, flags);
3853 
3854 	offset = dissect_ndr_str_pointer_item(
3855 		tvb, offset, pinfo, tree, di, drep,
3856 		NDR_POINTER_UNIQUE, "Server name", hf_servername, 0);
3857 
3858 	offset = dissect_ndr_uint32(
3859 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
3860 
3861 	/* GetPrinter() stores the level in se_data */
3862 	if(!pinfo->fd->visited){
3863 		dcv->se_data = GINT_TO_POINTER((int)level);
3864 	}
3865 
3866 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3867 
3868 	offset = dissect_spoolss_buffer(
3869 		tvb, offset, pinfo, tree, di, drep, NULL);
3870 
3871 	offset = dissect_ndr_uint32(
3872 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
3873 
3874 	return offset;
3875 }
3876 
3877 static int
SpoolssEnumPrinters_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3878 SpoolssEnumPrinters_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
3879 				 proto_tree *tree, dcerpc_info *di, guint8 *drep)
3880 {
3881 	guint32 num_drivers;
3882 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
3883 	gint16 level = GPOINTER_TO_INT(dcv->se_data);
3884 	BUFFER buffer;
3885 	proto_item *item;
3886 	proto_tree *subtree = NULL;
3887 
3888 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
3889 
3890 	/* Parse packet */
3891 
3892 	offset = dissect_spoolss_buffer(
3893 		tvb, offset, pinfo, tree, di, drep, &buffer);
3894 
3895 	if (buffer.tvb) {
3896 		subtree = proto_tree_add_subtree_format( buffer.tree, buffer.tvb, 0, -1, ett_PRINTER_INFO, &item, "Print info level %d", level);
3897 
3898 		switch(level) {
3899 		case 0:
3900 			dissect_PRINTER_INFO_0(
3901 				buffer.tvb, 0, pinfo, subtree, di, drep);
3902 			break;
3903 		case 1:
3904 			dissect_PRINTER_INFO_1(
3905 				buffer.tvb, 0, pinfo, subtree, di, drep);
3906 			break;
3907 		case 2:
3908 			dissect_PRINTER_INFO_2(
3909 				buffer.tvb, 0, pinfo, subtree, di, drep);
3910 			break;
3911 		case 3:
3912 			dissect_PRINTER_INFO_3(
3913 				buffer.tvb, 0, pinfo, subtree, di, drep);
3914 			break;
3915 		case 5:
3916 			dissect_PRINTER_INFO_5(
3917 				buffer.tvb, 0, pinfo, subtree, di, drep);
3918 			break;
3919 		case 7:
3920 			dissect_PRINTER_INFO_7(
3921 				buffer.tvb, 0, pinfo, subtree, di, drep);
3922 			break;
3923 		default:
3924 			expert_add_info(pinfo, item, &ei_printer_info_level);
3925 			break;
3926 		}
3927 	}
3928 
3929 	offset = dissect_ndr_uint32(
3930 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
3931 
3932 	offset = dissect_ndr_uint32(
3933 		tvb, offset, pinfo, tree, di, drep, hf_returned,
3934 		&num_drivers);
3935 
3936 	offset = dissect_doserror(
3937 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3938 
3939 	return offset;
3940 }
3941 
3942 /*
3943  * AddPrinterDriver
3944  */
3945 static int
SpoolssAddPrinterDriver_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3946 SpoolssAddPrinterDriver_r(tvbuff_t *tvb, int offset,
3947 				     packet_info *pinfo, proto_tree *tree,
3948 				     dcerpc_info *di, guint8 *drep)
3949 {
3950 	/* Parse packet */
3951 
3952 	offset = dissect_doserror(
3953 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
3954 
3955 	return offset;
3956 }
3957 
3958 /*
3959  * FORM_1
3960  */
3961 
3962 static gint ett_FORM_1 = -1;
3963 
3964 static int
dissect_FORM_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)3965 dissect_FORM_1(tvbuff_t *tvb, int offset, packet_info *pinfo,
3966 			  proto_tree *tree, dcerpc_info *di, guint8 *drep)
3967 {
3968 	proto_tree *subtree;
3969 	guint32 flags;
3970 
3971 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_FORM_1, NULL, "Form level 1");
3972 
3973 	offset = dissect_ndr_str_pointer_item(
3974 		tvb, offset, pinfo, subtree, di, drep, NDR_POINTER_UNIQUE,
3975 		"Name", hf_form_name, 0);
3976 
3977 	/* Eek - we need to know whether this pointer was NULL or not.
3978 	   Currently there is not any way to do this. */
3979 
3980 	if (tvb_reported_length_remaining(tvb, offset) <= 0)
3981 		goto done;
3982 
3983 	offset = dissect_ndr_uint32(
3984 		tvb, offset, pinfo, subtree, di, drep, hf_form_flags, &flags);
3985 
3986 	offset = dissect_ndr_uint32(
3987 		tvb, offset, pinfo, subtree, di, drep,
3988 		hf_form_unknown, NULL);
3989 
3990 	offset = dissect_ndr_uint32(
3991 		tvb, offset, pinfo, subtree, di, drep,
3992 		hf_form_width, NULL);
3993 
3994 	offset = dissect_ndr_uint32(
3995 		tvb, offset, pinfo, subtree, di, drep,
3996 		hf_form_height, NULL);
3997 
3998 	offset = dissect_ndr_uint32(
3999 		tvb, offset, pinfo, subtree, di, drep,
4000 		hf_form_left_margin, NULL);
4001 
4002 	offset = dissect_ndr_uint32(
4003 		tvb, offset, pinfo, subtree, di, drep,
4004 		hf_form_top_margin, NULL);
4005 
4006 	offset = dissect_ndr_uint32(
4007 		tvb, offset, pinfo, subtree, di, drep,
4008 		hf_form_horiz_len, NULL);
4009 
4010 	offset = dissect_ndr_uint32(
4011 		tvb, offset, pinfo, subtree, di, drep,
4012 		hf_form_vert_len, NULL);
4013 
4014  done:
4015 	return offset;
4016 }
4017 
4018 /*
4019  * FORM_CTR
4020  */
4021 
4022 static gint ett_FORM_CTR = -1;
4023 
4024 int
dissect_FORM_CTR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4025 dissect_FORM_CTR(tvbuff_t *tvb, int offset,
4026 			    packet_info *pinfo, proto_tree *tree,
4027 			    dcerpc_info *di, guint8 *drep)
4028 {
4029 	proto_tree *subtree;
4030 	proto_item *item;
4031 	guint32 level;
4032 
4033 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_FORM_CTR, &item, "Form container");
4034 
4035 	offset = dissect_ndr_uint32(
4036 		tvb, offset, pinfo, subtree, di, drep, hf_form_level, &level);
4037 
4038 	switch(level) {
4039 	case 1:
4040 		offset = dissect_FORM_1(tvb, offset, pinfo, subtree, di, drep);
4041 		break;
4042 
4043 	default:
4044 		expert_add_info_format(pinfo, item, &ei_form_level, "Unknown form info level %d", level);
4045 		break;
4046 	}
4047 
4048 	return offset;
4049 }
4050 
4051 /*
4052  * AddForm
4053  */
4054 
4055 static int
SpoolssAddForm_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4056 SpoolssAddForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4057 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4058 {
4059 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4060 	guint32 level;
4061 	proto_item *hidden_item;
4062 
4063 	hidden_item = proto_tree_add_uint(
4064 		tree, hf_form, tvb, offset, 0, 1);
4065 	proto_item_set_hidden(hidden_item);
4066 
4067 	/* Parse packet */
4068 
4069 	offset = dissect_nt_policy_hnd(
4070 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
4071 		FALSE, FALSE);
4072 
4073 	offset = dissect_ndr_uint32(
4074 		tvb, offset, pinfo, tree, di, drep, hf_form_level, &level);
4075 
4076 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
4077 
4078 	/* AddForm() stores the level in se_data */
4079 	if(!pinfo->fd->visited){
4080 			dcv->se_data = GUINT_TO_POINTER((int)level);
4081 	}
4082 
4083 	offset = dissect_FORM_CTR(tvb, offset, pinfo, tree, di, drep);
4084 
4085 	return offset;
4086 }
4087 
4088 static int
SpoolssAddForm_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4089 SpoolssAddForm_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4090 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4091 {
4092 	proto_item *hidden_item;
4093 
4094 	hidden_item = proto_tree_add_uint(
4095 		tree, hf_form, tvb, offset, 0, 1);
4096 	proto_item_set_hidden(hidden_item);
4097 
4098 	/* Parse packet */
4099 
4100 	offset = dissect_doserror(
4101 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4102 
4103 	return offset;
4104 }
4105 
4106 /*
4107  * DeleteForm
4108  */
4109 
4110 static int
SpoolssDeleteForm_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4111 SpoolssDeleteForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4112 			       proto_tree *tree, dcerpc_info *di, guint8 *drep)
4113 {
4114 	proto_item *hidden_item;
4115 	char *name = NULL;
4116 
4117 	hidden_item = proto_tree_add_uint(
4118 		tree, hf_form, tvb, offset, 0, 1);
4119 	proto_item_set_hidden(hidden_item);
4120 
4121 	/* Parse packet */
4122 
4123 	offset = dissect_nt_policy_hnd(
4124 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
4125 		FALSE, FALSE);
4126 
4127 	offset = dissect_ndr_cvstring(
4128 		tvb, offset, pinfo, tree, di, drep,
4129 		sizeof(guint16), hf_form_name, TRUE, &name);
4130 
4131 	if (name)
4132 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", name);
4133 
4134 	return offset;
4135 }
4136 
4137 static int
SpoolssDeleteForm_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4138 SpoolssDeleteForm_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4139 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4140 {
4141 	proto_item *hidden_item;
4142 
4143 	hidden_item = proto_tree_add_uint(
4144 		tree, hf_form, tvb, offset, 0, 1);
4145 	proto_item_set_hidden(hidden_item);
4146 
4147 	/* Parse packet */
4148 
4149 	offset = dissect_doserror(
4150 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4151 
4152 	return offset;
4153 }
4154 
4155 /*
4156  * SetForm
4157  */
4158 
4159 static int
SpoolssSetForm_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4160 SpoolssSetForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4161 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4162 {
4163 	char *name = NULL;
4164 	guint32 level;
4165 	proto_item *hidden_item;
4166 
4167 	hidden_item = proto_tree_add_uint(
4168 		tree, hf_form, tvb, offset, 0, 1);
4169 	proto_item_set_hidden(hidden_item);
4170 
4171 	/* Parse packet */
4172 
4173 	offset = dissect_nt_policy_hnd(
4174 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
4175 		FALSE, FALSE);
4176 
4177 	offset = dissect_ndr_cvstring(
4178 		tvb, offset, pinfo, tree, di, drep,
4179 		sizeof(guint16), hf_form_name, TRUE, &name);
4180 
4181 	if (name)
4182 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", name);
4183 
4184 	offset = dissect_ndr_uint32(
4185 		tvb, offset, pinfo, tree, di, drep, hf_form_level, &level);
4186 
4187 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
4188 
4189 	offset = dissect_FORM_CTR(tvb, offset, pinfo, tree, di, drep);
4190 
4191 	return offset;
4192 }
4193 
4194 static int
SpoolssSetForm_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4195 SpoolssSetForm_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4196 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4197 {
4198 	proto_item *hidden_item;
4199 
4200 	hidden_item = proto_tree_add_uint(
4201 		tree, hf_form, tvb, offset, 0, 1);
4202 	proto_item_set_hidden(hidden_item);
4203 
4204 	/* Parse packet */
4205 
4206 	offset = dissect_doserror(
4207 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4208 
4209 	return offset;
4210 }
4211 
4212 /*
4213  * GetForm
4214  */
4215 
4216 static int
SpoolssGetForm_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4217 SpoolssGetForm_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4218 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4219 {
4220 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4221 	proto_item *hidden_item;
4222 	guint32 level;
4223 	char *name;
4224 
4225 	hidden_item = proto_tree_add_uint(
4226 		tree, hf_form, tvb, offset, 0, 1);
4227 	proto_item_set_hidden(hidden_item);
4228 
4229 	/* Parse packet */
4230 
4231 	offset = dissect_nt_policy_hnd(
4232 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
4233 		FALSE, FALSE);
4234 
4235 	offset = dissect_ndr_cvstring(
4236 		tvb, offset, pinfo, tree, di, drep,
4237 		sizeof(guint16), hf_form_name, TRUE, &name);
4238 
4239 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", name);
4240 
4241 	offset = dissect_ndr_uint32(
4242 		tvb, offset, pinfo, tree, di, drep, hf_form_level, &level);
4243 
4244 	/* GetForm() stores the level in se_data */
4245 	if(!pinfo->fd->visited){
4246 			dcv->se_data = GUINT_TO_POINTER((int)level);
4247 	}
4248 
4249 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d",
4250 				level);
4251 
4252 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep, NULL);
4253 
4254 	offset = dissect_ndr_uint32(
4255 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
4256 
4257 	return offset;
4258 }
4259 
4260 static int
SpoolssGetForm_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4261 SpoolssGetForm_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4262 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4263 {
4264 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4265 	BUFFER buffer;
4266 	guint32 level = GPOINTER_TO_UINT(dcv->se_data);
4267 	proto_item *hidden_item;
4268 
4269 	hidden_item = proto_tree_add_uint(
4270 		tree, hf_form, tvb, offset, 0, 1);
4271 	proto_item_set_hidden(hidden_item);
4272 
4273 	/* Parse packet */
4274 
4275 	offset = dissect_spoolss_buffer(
4276 		tvb, offset, pinfo, tree, di, drep, &buffer);
4277 
4278 	offset = dissect_ndr_uint32(
4279 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
4280 
4281 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
4282 
4283 	if (buffer.tvb) {
4284 		int buffer_offset = 0;
4285 
4286 		switch(level) {
4287 		case 1: {
4288 			int struct_start = buffer_offset;
4289 
4290 			/*buffer_offset = */dissect_FORM_REL(
4291 				buffer.tvb, buffer_offset, pinfo, tree, di, drep,
4292 				struct_start);
4293 			break;
4294 		}
4295 
4296 		default:
4297 			proto_tree_add_expert_format(buffer.tree, pinfo, &ei_form_level, buffer.tvb, buffer_offset, -1, "Unknown form info level %d", level);
4298 			break;
4299 		}
4300 	}
4301 
4302 	offset = dissect_doserror(
4303 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4304 
4305 	return offset;
4306 }
4307 
4308 
4309 /* A generic reply function that just parses the status code.  Useful for
4310    unimplemented dissectors so the status code can be inserted into the
4311    INFO column. */
4312 
4313 static int
SpoolssGeneric_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4314 SpoolssGeneric_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4315 			    proto_tree *tree, dcerpc_info *di, guint8 *drep)
4316 {
4317 	int len = tvb_reported_length(tvb);
4318 
4319 	proto_tree_add_expert(tree, pinfo, &ei_unimplemented_dissector, tvb, offset, 0);
4320 
4321 	offset = dissect_doserror(
4322 		tvb, len - 4, pinfo, tree, di, drep, hf_rc, NULL);
4323 
4324 	return offset;
4325 }
4326 
4327 /*
4328  * JOB_INFO_1
4329  */
4330 
4331 static gint ett_JOB_INFO_1 = -1;
4332 
4333 static int
dissect_spoolss_JOB_INFO_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4334 dissect_spoolss_JOB_INFO_1(tvbuff_t *tvb, int offset, packet_info *pinfo,
4335 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
4336 {
4337 	proto_item *item;
4338 	proto_tree *subtree;
4339 	int struct_start = offset;
4340 	char *document_name;
4341 
4342 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_JOB_INFO_1, &item, "Job info level 1");
4343 
4344 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
4345 				    hf_job_id, NULL);
4346 
4347 	offset = dissect_spoolss_relstr(
4348 		tvb, offset, pinfo, subtree, di, drep, hf_printername,
4349 		struct_start, NULL);
4350 
4351 	offset = dissect_spoolss_relstr(
4352 		tvb, offset, pinfo, subtree, di, drep, hf_servername,
4353 		struct_start, NULL);
4354 
4355 	offset = dissect_spoolss_relstr(
4356 		tvb, offset, pinfo, subtree, di, drep, hf_username,
4357 		struct_start, NULL);
4358 
4359 	offset = dissect_spoolss_relstr(
4360 		tvb, offset, pinfo, subtree, di, drep, hf_documentname,
4361 		struct_start, &document_name);
4362 
4363 	proto_item_append_text(item, ": %s", document_name);
4364 
4365 	offset = dissect_spoolss_relstr(
4366 		tvb, offset, pinfo, subtree, di, drep, hf_datatype,
4367 		struct_start, NULL);
4368 
4369 	offset = dissect_spoolss_relstr(
4370 		tvb, offset, pinfo, subtree, di, drep, hf_textstatus,
4371 		struct_start, NULL);
4372 
4373 	offset = dissect_job_status(tvb, offset, pinfo, subtree, di, drep);
4374 
4375 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
4376 				    hf_job_priority, NULL);
4377 
4378 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
4379 				    hf_job_position, NULL);
4380 
4381 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
4382 				    hf_job_totalpages, NULL);
4383 
4384 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
4385 				    hf_job_pagesprinted, NULL);
4386 
4387 	offset = dissect_SYSTEM_TIME(
4388 		tvb, offset, pinfo, subtree, di, drep, "Job Submission Time",
4389 		TRUE, NULL);
4390 
4391 	proto_item_set_len(item, offset - struct_start);
4392 
4393 	return offset;
4394 }
4395 
4396 /*
4397  * JOB_INFO_2
4398  */
4399 
4400 static gint ett_JOB_INFO_2 = -1;
4401 
4402 static int
dissect_spoolss_JOB_INFO_2(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4403 dissect_spoolss_JOB_INFO_2(tvbuff_t *tvb, int offset, packet_info *pinfo,
4404 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
4405 {
4406 	proto_item *item;
4407 	proto_tree *subtree;
4408 	int struct_start = offset;
4409 	char *document_name;
4410 	guint32 devmode_offset, secdesc_offset;
4411 
4412 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_JOB_INFO_2, &item, "Job info level 2");
4413 
4414 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
4415 				    hf_job_id, NULL);
4416 
4417 	offset = dissect_spoolss_relstr(
4418 		tvb, offset, pinfo, subtree, di, drep, hf_printername,
4419 		struct_start, NULL);
4420 
4421 	offset = dissect_spoolss_relstr(
4422 		tvb, offset, pinfo, subtree, di, drep, hf_machinename,
4423 		struct_start, NULL);
4424 
4425 	offset = dissect_spoolss_relstr(
4426 		tvb, offset, pinfo, subtree, di, drep, hf_username,
4427 		struct_start, NULL);
4428 
4429 	offset = dissect_spoolss_relstr(
4430 		tvb, offset, pinfo, subtree, di, drep, hf_documentname,
4431 		struct_start, &document_name);
4432 
4433 	proto_item_append_text(item, ": %s", document_name);
4434 
4435 	offset = dissect_spoolss_relstr(
4436 		tvb, offset, pinfo, subtree, di, drep, hf_notifyname,
4437 		struct_start, NULL);
4438 
4439 	offset = dissect_spoolss_relstr(
4440 		tvb, offset, pinfo, subtree, di, drep, hf_datatype,
4441 		struct_start, NULL);
4442 
4443 	offset = dissect_spoolss_relstr(
4444 		tvb, offset, pinfo, subtree, di, drep, hf_printprocessor,
4445 		struct_start, NULL);
4446 
4447 	offset = dissect_spoolss_relstr(
4448 		tvb, offset, pinfo, subtree, di, drep, hf_parameters,
4449 		struct_start, NULL);
4450 
4451 	offset = dissect_spoolss_relstr(
4452 		tvb, offset, pinfo, subtree, di, drep, hf_drivername,
4453 		struct_start, NULL);
4454 
4455 	offset = dissect_ndr_uint32(
4456 		tvb, offset, pinfo, NULL, di, drep, hf_offset,
4457 		&devmode_offset);
4458 
4459 	dissect_DEVMODE(
4460 		tvb, devmode_offset - 4 + struct_start, pinfo, subtree, di, drep);
4461 
4462 	offset = dissect_spoolss_relstr(
4463 		tvb, offset, pinfo, subtree, di, drep, hf_textstatus,
4464 		struct_start, NULL);
4465 
4466 	offset = dissect_ndr_uint32(
4467 		tvb, offset, pinfo, NULL, di, drep, hf_offset,
4468 		&secdesc_offset);
4469 
4470 	dissect_nt_sec_desc(
4471 		tvb, secdesc_offset, pinfo, subtree, drep,
4472 		FALSE, -1,
4473 		&spoolss_job_access_mask_info);
4474 
4475 	offset = dissect_job_status(tvb, offset, pinfo, subtree, di, drep);
4476 
4477 	offset = dissect_ndr_uint32(
4478 		tvb, offset, pinfo, subtree, di, drep, hf_job_priority, NULL);
4479 
4480 	offset = dissect_ndr_uint32(
4481 		tvb, offset, pinfo, subtree, di, drep, hf_job_position, NULL);
4482 
4483 	offset = dissect_ndr_uint32(
4484 		tvb, offset, pinfo, NULL, di, drep, hf_start_time, NULL);
4485 
4486 	offset = dissect_ndr_uint32(
4487 		tvb, offset, pinfo, NULL, di, drep, hf_end_time, NULL);
4488 
4489 	offset = dissect_ndr_uint32(
4490 		tvb, offset, pinfo, subtree, di, drep, hf_job_totalpages, NULL);
4491 
4492 	offset = dissect_ndr_uint32(
4493 		tvb, offset, pinfo, subtree, di, drep, hf_job_size, NULL);
4494 
4495 	offset = dissect_SYSTEM_TIME(
4496 		tvb, offset, pinfo, subtree, di, drep, "Job Submission Time",
4497 		TRUE, NULL);
4498 
4499 	offset = dissect_ndr_uint32(
4500 		tvb, offset, pinfo, NULL, di, drep, hf_elapsed_time, NULL);
4501 
4502 	offset = dissect_ndr_uint32(
4503 		tvb, offset, pinfo, subtree, di, drep, hf_job_pagesprinted, NULL);
4504 
4505 	proto_item_set_len(item, offset - struct_start);
4506 
4507 	return offset;
4508 }
4509 
4510 /*
4511  * EnumJobs
4512  */
4513 
4514 static int hf_enumjobs_firstjob = -1;
4515 static int hf_enumjobs_numjobs = -1;
4516 
4517 static int
SpoolssEnumJobs_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4518 SpoolssEnumJobs_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4519 			     proto_tree *tree, dcerpc_info *di, guint8 *drep)
4520 {
4521 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4522 	guint32 level;
4523 
4524 	/* Parse packet */
4525 
4526 	offset = dissect_nt_policy_hnd(
4527 		tvb, offset, pinfo, tree, di, drep,
4528 		hf_hnd, NULL, NULL, FALSE, FALSE);
4529 
4530 	offset = dissect_ndr_uint32(
4531 		tvb, offset, pinfo, tree, di, drep, hf_enumjobs_firstjob, NULL);
4532 
4533 	offset = dissect_ndr_uint32(
4534 		tvb, offset, pinfo, tree, di, drep, hf_enumjobs_numjobs, NULL);
4535 
4536 	offset = dissect_ndr_uint32(
4537 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
4538 
4539 	/* EnumJobs() stores the level in se_data */
4540 	if(!pinfo->fd->visited){
4541 			dcv->se_data = GUINT_TO_POINTER((int)level);
4542 	}
4543 
4544 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
4545 
4546 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep, NULL);
4547 
4548 	offset = dissect_ndr_uint32(
4549 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
4550 
4551 	return offset;
4552 }
4553 
4554 static int
SpoolssEnumJobs_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4555 SpoolssEnumJobs_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4556 			     proto_tree *tree, dcerpc_info *di, guint8 *drep)
4557 {
4558 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4559 	gint16 level = GPOINTER_TO_UINT(dcv->se_data);
4560 	BUFFER buffer;
4561 	guint32 num_jobs, i;
4562 	int buffer_offset;
4563 
4564 	/* Parse packet */
4565 
4566 	offset = dissect_spoolss_buffer(
4567 		tvb, offset, pinfo, tree, di, drep, &buffer);
4568 
4569 	offset = dissect_ndr_uint32(
4570 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
4571 
4572 	offset = dissect_ndr_uint32(
4573 		tvb, offset, pinfo, tree, di, drep, hf_enumjobs_numjobs,
4574 		&num_jobs);
4575 
4576 	buffer_offset = 0;
4577 
4578 	for (i = 0; i < num_jobs; i++) {
4579 		switch(level) {
4580 		case 1:
4581 			buffer_offset = dissect_spoolss_JOB_INFO_1(
4582 				buffer.tvb, buffer_offset, pinfo,
4583 				buffer.tree, di, drep);
4584 			break;
4585 		case 2:
4586 			buffer_offset = dissect_spoolss_JOB_INFO_2(
4587 				buffer.tvb, buffer_offset, pinfo,
4588 				buffer.tree, di, drep);
4589 			break;
4590 		default:
4591 			proto_tree_add_expert_format( buffer.tree, pinfo, &ei_job_info_level, buffer.tvb, 0, -1, "Unknown job info level %d", level);
4592 			break;
4593 		}
4594 
4595 	}
4596 
4597 	offset = dissect_doserror(
4598 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4599 
4600 	return offset;
4601 }
4602 
4603 /*
4604  * SetJob
4605  */
4606 
4607 static const value_string setjob_commands[] = {
4608 	{ JOB_CONTROL_PAUSE, "Pause" },
4609 	{ JOB_CONTROL_RESUME, "Resume" },
4610 	{ JOB_CONTROL_CANCEL, "Cancel" },
4611 	{ JOB_CONTROL_RESTART, "Restart" },
4612 	{ JOB_CONTROL_DELETE, "Delete" },
4613 	{ 0, NULL }
4614 };
4615 
4616 static int hf_setjob_cmd = -1;
4617 
4618 static int
SpoolssSetJob_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4619 SpoolssSetJob_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4620 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
4621 {
4622 	guint32 jobid, cmd;
4623 
4624 	/* Parse packet */
4625 
4626 	offset = dissect_nt_policy_hnd(
4627 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
4628 		FALSE, FALSE);
4629 
4630 	offset = dissect_ndr_uint32(
4631 		tvb, offset, pinfo, tree, di, drep, hf_job_id, &jobid);
4632 
4633 	offset = dissect_ndr_uint32(
4634 		tvb, offset, pinfo, tree, di, drep, hf_level, NULL);
4635 
4636 	offset = dissect_ndr_uint32(
4637 		tvb, offset, pinfo, tree, di, drep, hf_setjob_cmd, &cmd);
4638 
4639 	col_append_fstr(
4640 			pinfo->cinfo, COL_INFO, ", %s jobid %d",
4641 			val_to_str(cmd, setjob_commands, "Unknown (%d)"),
4642 			jobid);
4643 
4644 	return offset;
4645 }
4646 
4647 static int
SpoolssSetJob_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4648 SpoolssSetJob_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4649 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
4650 {
4651 	/* Parse packet */
4652 
4653 	offset = dissect_doserror(
4654 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4655 
4656 	return offset;
4657 }
4658 
4659 /*
4660  * GetJob
4661  */
4662 
4663 static int
SpoolssGetJob_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4664 SpoolssGetJob_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
4665 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
4666 {
4667 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4668 	guint32 level, jobid;
4669 
4670 	/* Parse packet */
4671 
4672 	offset = dissect_nt_policy_hnd(
4673 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
4674 		FALSE, FALSE);
4675 
4676 	offset = dissect_ndr_uint32(
4677 		tvb, offset, pinfo, tree, di, drep, hf_job_id, &jobid);
4678 
4679 	offset = dissect_ndr_uint32(
4680 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
4681 
4682 	/* GetJob() stores the level in se_data */
4683 	if(!pinfo->fd->visited){
4684 			dcv->se_data = GUINT_TO_POINTER((int)level);
4685 	}
4686 
4687 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d, jobid %d",
4688 				level, jobid);
4689 
4690 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep, NULL);
4691 
4692 	offset = dissect_ndr_uint32(
4693 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
4694 
4695 	return offset;
4696 }
4697 
4698 static int
SpoolssGetJob_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4699 SpoolssGetJob_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
4700 			proto_tree *tree, dcerpc_info *di, guint8 *drep)
4701 {
4702 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
4703 	gint32 level = GPOINTER_TO_UINT(dcv->se_data);
4704 	BUFFER buffer;
4705 
4706 	/* Parse packet */
4707 
4708 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep,
4709 					&buffer);
4710 
4711 	if (buffer.tvb) {
4712 		int buffer_offset = 0;
4713 
4714 		switch(level) {
4715 		case 1:
4716 			/*buffer_offset = */dissect_spoolss_JOB_INFO_1(
4717 				buffer.tvb, buffer_offset, pinfo,
4718 				buffer.tree, di, drep);
4719 			break;
4720 		case 2:
4721 		default:
4722 			proto_tree_add_expert_format( buffer.tree, pinfo, &ei_job_info_level, buffer.tvb, buffer_offset, -1, "Unknown job info level %d", level);
4723 			break;
4724 		}
4725 	}
4726 
4727 	offset = dissect_ndr_uint32(
4728 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
4729 
4730 	offset = dissect_doserror(
4731 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4732 
4733 	return offset;
4734 }
4735 
4736 /*
4737  * StartPagePrinter
4738  */
4739 
4740 static int
SpoolssStartPagePrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4741 SpoolssStartPagePrinter_q(tvbuff_t *tvb, int offset,
4742 				     packet_info *pinfo, proto_tree *tree,
4743 				     dcerpc_info *di, guint8 *drep)
4744 {
4745 	e_ctx_hnd policy_hnd;
4746 	char *pol_name;
4747 
4748 	/* Parse packet */
4749 
4750 	offset = dissect_nt_policy_hnd(
4751 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
4752 		FALSE, FALSE);
4753 
4754 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
4755 			     pinfo->num);
4756 
4757 	if (pol_name)
4758 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
4759 				pol_name);
4760 
4761 	return offset;
4762 }
4763 
4764 static int
SpoolssStartPagePrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4765 SpoolssStartPagePrinter_r(tvbuff_t *tvb, int offset,
4766 				     packet_info *pinfo, proto_tree *tree,
4767 				     dcerpc_info *di, guint8 *drep)
4768 {
4769 	/* Parse packet */
4770 
4771 	offset = dissect_doserror(
4772 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4773 
4774 	return offset;
4775 }
4776 
4777 /*
4778  * EndPagePrinter
4779  */
4780 
4781 static int
SpoolssEndPagePrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4782 SpoolssEndPagePrinter_q(tvbuff_t *tvb, int offset,
4783 				   packet_info *pinfo, proto_tree *tree,
4784 				   dcerpc_info *di, guint8 *drep)
4785 {
4786 	e_ctx_hnd policy_hnd;
4787 	char *pol_name;
4788 
4789 	/* Parse packet */
4790 
4791 	offset = dissect_nt_policy_hnd(
4792 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
4793 		FALSE, FALSE);
4794 
4795 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
4796 			     pinfo->num);
4797 
4798 	if (pol_name)
4799 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
4800 				pol_name);
4801 
4802 	return offset;
4803 }
4804 
4805 static int
SpoolssEndPagePrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4806 SpoolssEndPagePrinter_r(tvbuff_t *tvb, int offset,
4807 				   packet_info *pinfo, proto_tree *tree,
4808 				   dcerpc_info *di, guint8 *drep)
4809 {
4810 	/* Parse packet */
4811 
4812 	offset = dissect_doserror(
4813 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4814 
4815 	return offset;
4816 }
4817 
4818 /*
4819  * DOC_INFO_1
4820  */
4821 
4822 static gint ett_DOC_INFO_1 = -1;
4823 
4824 static int
dissect_spoolss_doc_info_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4825 dissect_spoolss_doc_info_1(tvbuff_t *tvb, int offset, packet_info *pinfo,
4826 			   proto_tree *tree, dcerpc_info *di, guint8 *drep)
4827 {
4828 	proto_tree *subtree;
4829 
4830 	subtree = proto_tree_add_subtree(
4831 		tree, tvb, offset, 0, ett_DOC_INFO_1, NULL, "Document info level 1");
4832 
4833 	offset = dissect_ndr_str_pointer_item(
4834 		tvb, offset, pinfo, subtree, di, drep, NDR_POINTER_UNIQUE,
4835 		"Document name", hf_documentname, 0);
4836 
4837 	offset = dissect_ndr_str_pointer_item(
4838 		tvb, offset, pinfo, subtree, di, drep, NDR_POINTER_UNIQUE,
4839 		"Output file", hf_outputfile, 0);
4840 
4841 	offset = dissect_ndr_str_pointer_item(
4842 		tvb, offset, pinfo, subtree, di, drep, NDR_POINTER_UNIQUE,
4843 		"Data type", hf_datatype, 0);
4844 
4845 	return offset;
4846 }
4847 
4848 static int
dissect_spoolss_doc_info_data(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4849 dissect_spoolss_doc_info_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
4850 			      proto_tree *tree, dcerpc_info *di, guint8 *drep)
4851 {
4852 	if (di->conformant_run)
4853 		return offset;
4854 
4855 	return dissect_spoolss_doc_info_1(tvb, offset, pinfo, tree, di, drep);
4856 }
4857 
4858 /*
4859  * DOC_INFO
4860  */
4861 
4862 static gint ett_DOC_INFO = -1;
4863 
4864 static int
dissect_spoolss_doc_info(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4865 dissect_spoolss_doc_info(tvbuff_t *tvb, int offset, packet_info *pinfo,
4866 			 proto_tree *tree, dcerpc_info *di, guint8 *drep)
4867 {
4868 	proto_tree *subtree;
4869 	guint32 level;
4870 
4871 	subtree = proto_tree_add_subtree(
4872 		tree, tvb, offset, 0, ett_DOC_INFO, NULL, "Document info");
4873 
4874 	offset = dissect_ndr_uint32(
4875 		tvb, offset, pinfo, subtree, di, drep, hf_level, &level);
4876 
4877 	offset = dissect_ndr_pointer(
4878 		tvb, offset, pinfo, subtree, di, drep,
4879 		dissect_spoolss_doc_info_data,
4880 		NDR_POINTER_UNIQUE, "Document info", -1);
4881 
4882 	return offset;
4883 }
4884 
4885 /*
4886  * DOC_INFO_CTR
4887  */
4888 
4889 static gint ett_DOC_INFO_CTR = -1;
4890 
4891 int
dissect_spoolss_doc_info_ctr(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4892 dissect_spoolss_doc_info_ctr(tvbuff_t *tvb, int offset, packet_info *pinfo,
4893 			     proto_tree *tree, dcerpc_info *di, guint8 *drep)
4894 {
4895 	proto_tree *subtree;
4896 
4897 	subtree = proto_tree_add_subtree(
4898 		tree, tvb, offset, 0, ett_DOC_INFO_CTR, NULL, "Document info container");
4899 
4900 	offset = dissect_ndr_uint32(
4901 		tvb, offset, pinfo, subtree, di, drep, hf_level, NULL);
4902 
4903 	offset = dissect_spoolss_doc_info(
4904 		tvb, offset, pinfo, subtree, di, drep);
4905 
4906 	return offset;
4907 }
4908 
4909 /*
4910  * StartDocPrinter
4911  */
4912 
4913 static int
SpoolssStartDocPrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4914 SpoolssStartDocPrinter_q(tvbuff_t *tvb, int offset,
4915 				    packet_info *pinfo, proto_tree *tree,
4916 				    dcerpc_info *di, guint8 *drep)
4917 {
4918 	e_ctx_hnd policy_hnd;
4919 	char *pol_name;
4920 
4921 	/* Parse packet */
4922 
4923 	offset = dissect_nt_policy_hnd(
4924 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
4925 		FALSE, FALSE);
4926 
4927 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
4928 			     pinfo->num);
4929 
4930 	if (pol_name)
4931 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
4932 				pol_name);
4933 
4934 	offset = dissect_spoolss_doc_info_ctr(tvb, offset, pinfo, tree, di, drep);
4935 
4936 	return offset;
4937 }
4938 
4939 static int
SpoolssStartDocPrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4940 SpoolssStartDocPrinter_r(tvbuff_t *tvb, int offset,
4941 				    packet_info *pinfo, proto_tree *tree,
4942 				    dcerpc_info *di, guint8 *drep)
4943 {
4944 	/* Parse packet */
4945 
4946 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
4947 				    hf_job_id, NULL);
4948 
4949 	offset = dissect_doserror(
4950 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4951 
4952 	return offset;
4953 }
4954 
4955 /*
4956  * EndDocPrinter
4957  */
4958 
4959 static int
SpoolssEndDocPrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4960 SpoolssEndDocPrinter_q(tvbuff_t *tvb, int offset,
4961 				  packet_info *pinfo, proto_tree *tree,
4962 				  dcerpc_info *di, guint8 *drep)
4963 {
4964 	e_ctx_hnd policy_hnd;
4965 	char *pol_name;
4966 
4967 	/* Parse packet */
4968 
4969 	offset = dissect_nt_policy_hnd(
4970 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
4971 		FALSE, FALSE);
4972 
4973 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
4974 			     pinfo->num);
4975 
4976 	if (pol_name)
4977 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
4978 				pol_name);
4979 
4980 
4981 	return offset;
4982 }
4983 
4984 static int
SpoolssEndDocPrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)4985 SpoolssEndDocPrinter_r(tvbuff_t *tvb, int offset,
4986 				  packet_info *pinfo, proto_tree *tree,
4987 				  dcerpc_info *di, guint8 *drep)
4988 {
4989 	/* Parse packet */
4990 
4991 	offset = dissect_doserror(
4992 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
4993 
4994 	return offset;
4995 }
4996 
4997 /*
4998  * WritePrinter
4999  */
5000 
5001 static gint ett_writeprinter_buffer = -1;
5002 
5003 static int hf_writeprinter_numwritten = -1;
5004 
5005 static int
SpoolssWritePrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5006 SpoolssWritePrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
5007 				 proto_tree *tree, dcerpc_info *di, guint8 *drep)
5008 {
5009 	e_ctx_hnd policy_hnd;
5010 	char *pol_name;
5011 	guint32 size;
5012 	proto_item *item;
5013 	proto_tree *subtree;
5014 
5015 	/* Parse packet */
5016 
5017 	offset = dissect_nt_policy_hnd(
5018 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
5019 		FALSE, FALSE);
5020 
5021 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
5022 			     pinfo->num);
5023 
5024 	if (pol_name)
5025 		col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
5026 				pol_name);
5027 
5028 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5029 				    hf_buffer_size, &size);
5030 
5031 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %d bytes", size);
5032 
5033 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_writeprinter_buffer, &item, "Buffer");
5034 
5035 	offset = dissect_ndr_uint8s(tvb, offset, pinfo, subtree, di, drep,
5036 				    hf_buffer_data, size, NULL);
5037 
5038 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5039 				    hf_buffer_size, NULL);
5040 
5041 	proto_item_set_len(item, size + 4);
5042 
5043 	return offset;
5044 }
5045 
5046 static int
SpoolssWritePrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5047 SpoolssWritePrinter_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
5048 				 proto_tree *tree, dcerpc_info *di, guint8 *drep)
5049 {
5050 	guint32 size;
5051 
5052 	/* Parse packet */
5053 
5054 	offset = dissect_ndr_uint32(
5055 		tvb, offset, pinfo, tree, di, drep, hf_writeprinter_numwritten,
5056 		&size);
5057 
5058 	col_append_fstr(
5059 			pinfo->cinfo, COL_INFO, ", %d bytes written", size);
5060 
5061 	offset = dissect_doserror(
5062 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
5063 
5064 	return offset;
5065 }
5066 
5067 /*
5068  * DeletePrinterData
5069  */
5070 
5071 static int
SpoolssDeletePrinterData_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5072 SpoolssDeletePrinterData_q(tvbuff_t *tvb, int offset,
5073 				      packet_info *pinfo, proto_tree *tree,
5074 				      dcerpc_info *di, guint8 *drep)
5075 {
5076 	char *value_name;
5077 	proto_item *hidden_item;
5078 
5079 	hidden_item = proto_tree_add_uint(
5080 		tree, hf_printerdata, tvb, offset, 0, 1);
5081 	proto_item_set_hidden(hidden_item);
5082 
5083 	/* Parse packet */
5084 
5085 	offset = dissect_nt_policy_hnd(
5086 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
5087 		FALSE, FALSE);
5088 
5089 	offset = dissect_ndr_cvstring(
5090 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
5091 		hf_printerdata_value, TRUE, &value_name);
5092 
5093 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", value_name);
5094 
5095 	return offset;
5096 }
5097 
5098 static int
SpoolssDeletePrinterData_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5099 SpoolssDeletePrinterData_r(tvbuff_t *tvb, int offset,
5100 				      packet_info *pinfo, proto_tree *tree,
5101 				      dcerpc_info *di, guint8 *drep)
5102 {
5103 	proto_item *hidden_item;
5104 
5105 	hidden_item = proto_tree_add_uint(
5106 		tree, hf_printerdata, tvb, offset, 0, 1);
5107 	proto_item_set_hidden(hidden_item);
5108 
5109 	/* Parse packet */
5110 
5111 	offset = dissect_doserror(
5112 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
5113 
5114 	return offset;
5115 }
5116 
5117 /*
5118  * DRIVER_INFO_1
5119  */
5120 
5121 static gint ett_DRIVER_INFO_1 = -1;
5122 
5123 static int
dissect_DRIVER_INFO_1(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5124 dissect_DRIVER_INFO_1(tvbuff_t *tvb, int offset,
5125 				 packet_info *pinfo, proto_tree *tree,
5126 				 dcerpc_info *di, guint8 *drep)
5127 {
5128 	proto_tree *subtree;
5129 	int struct_start = offset;
5130 
5131 	subtree = proto_tree_add_subtree(
5132 		tree, tvb, offset, 0, ett_DRIVER_INFO_1, NULL, "Driver info level 1");
5133 
5134 	offset = dissect_spoolss_relstr(
5135 		tvb, offset, pinfo, subtree, di, drep, hf_drivername,
5136 		struct_start, NULL);
5137 
5138 	return offset;
5139 }
5140 
5141 /*
5142  * DRIVER_INFO_2
5143  */
5144 
5145 static const value_string driverinfo_cversion_vals[] =
5146 {
5147 	{ 0, "Windows 95/98/Me" },
5148 	{ 2, "Windows NT 4.0" },
5149 	{ 3, "Windows 2000/XP" },
5150 	{ 0, NULL }
5151 };
5152 
5153 static gint ett_DRIVER_INFO_2 = -1;
5154 
5155 static int
dissect_DRIVER_INFO_2(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5156 dissect_DRIVER_INFO_2(tvbuff_t *tvb, int offset,
5157 	 packet_info *pinfo, proto_tree *tree,
5158 	 dcerpc_info *di, guint8 *drep)
5159 {
5160 	proto_tree *subtree;
5161 	int struct_start = offset;
5162 
5163 	subtree = proto_tree_add_subtree(
5164 			tree, tvb, offset, 0, ett_DRIVER_INFO_2, NULL, "Driver info level 2");
5165 
5166 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5167 			hf_driverinfo_cversion, NULL);
5168 
5169 	offset = dissect_spoolss_relstr(
5170 			tvb, offset, pinfo, subtree, di, drep, hf_drivername,
5171 			struct_start, NULL);
5172 
5173 	offset = dissect_spoolss_relstr(
5174 			tvb, offset, pinfo, subtree, di, drep, hf_environment,
5175 			struct_start, NULL);
5176 
5177 	offset = dissect_spoolss_relstr(
5178 			tvb, offset, pinfo, subtree, di, drep, hf_driverpath,
5179 			struct_start, NULL);
5180 
5181 	offset = dissect_spoolss_relstr(
5182 			tvb, offset, pinfo, subtree, di, drep, hf_datafile,
5183 			struct_start, NULL);
5184 
5185 	offset = dissect_spoolss_relstr(
5186 			tvb, offset, pinfo, subtree, di, drep, hf_configfile,
5187 			struct_start, NULL);
5188 
5189 	return offset;
5190 }
5191 
5192 /*
5193  * DRIVER_INFO_3
5194  */
5195 
5196 static gint ett_DRIVER_INFO_3 = -1;
5197 
5198 static int
dissect_DRIVER_INFO_3(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5199 dissect_DRIVER_INFO_3(tvbuff_t *tvb, int offset,
5200 				 packet_info *pinfo, proto_tree *tree,
5201 				 dcerpc_info *di, guint8 *drep)
5202 {
5203 	proto_tree *subtree;
5204 	int struct_start = offset;
5205 
5206 	subtree = proto_tree_add_subtree(
5207 		tree, tvb, offset, 0, ett_DRIVER_INFO_3, NULL, "Driver info level 3");
5208 
5209 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5210 				    hf_driverinfo_cversion, NULL);
5211 
5212 	offset = dissect_spoolss_relstr(
5213 		tvb, offset, pinfo, subtree, di, drep, hf_drivername,
5214 		struct_start, NULL);
5215 
5216 	offset = dissect_spoolss_relstr(
5217 		tvb, offset, pinfo, subtree, di, drep, hf_environment,
5218 		struct_start, NULL);
5219 
5220 	offset = dissect_spoolss_relstr(
5221 		tvb, offset, pinfo, subtree, di, drep, hf_driverpath,
5222 		struct_start, NULL);
5223 
5224 	offset = dissect_spoolss_relstr(
5225 		tvb, offset, pinfo, subtree, di, drep, hf_datafile,
5226 		struct_start, NULL);
5227 
5228 	offset = dissect_spoolss_relstr(
5229 		tvb, offset, pinfo, subtree, di, drep, hf_configfile,
5230 		struct_start, NULL);
5231 
5232 	offset = dissect_spoolss_relstr(
5233 		tvb, offset, pinfo, subtree, di, drep, hf_helpfile,
5234 		struct_start, NULL);
5235 
5236 	offset = dissect_spoolss_relstrarray(
5237 		tvb, offset, pinfo, subtree, di, drep, hf_dependentfiles,
5238 		struct_start, NULL);
5239 
5240 	offset = dissect_spoolss_relstr(
5241 		tvb, offset, pinfo, subtree, di, drep, hf_monitorname,
5242 		struct_start, NULL);
5243 
5244 	offset = dissect_spoolss_relstr(
5245 		tvb, offset, pinfo, subtree, di, drep, hf_defaultdatatype,
5246 		struct_start, NULL);
5247 
5248 	return offset;
5249 }
5250 
5251 
5252 /*
5253 	DRIVER_INFO_6
5254 */
5255 
5256 static gint ett_DRIVER_INFO_6 = -1;
5257 
5258 static int
dissect_DRIVER_INFO_6(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5259 dissect_DRIVER_INFO_6(tvbuff_t *tvb, int offset,
5260 				 packet_info *pinfo, proto_tree *tree,
5261 				 dcerpc_info *di, guint8 *drep)
5262 {
5263 	proto_tree *subtree;
5264 	int struct_start = offset;
5265 
5266 	subtree = proto_tree_add_subtree(
5267 			tree, tvb, offset, 0, ett_DRIVER_INFO_6, NULL, "Driver info level 6");
5268 
5269 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5270 			hf_driverinfo_cversion, NULL);
5271 
5272 	offset = dissect_spoolss_relstr(
5273 			tvb, offset, pinfo, subtree, di, drep, hf_drivername,
5274 			struct_start, NULL);
5275 
5276 	offset = dissect_spoolss_relstr(
5277 			tvb, offset, pinfo, subtree, di, drep, hf_environment,
5278 			struct_start, NULL);
5279 
5280 	offset = dissect_spoolss_relstr(
5281 			tvb, offset, pinfo, subtree, di, drep, hf_driverpath,
5282 			struct_start, NULL);
5283 
5284 	offset = dissect_spoolss_relstr(
5285 			tvb, offset, pinfo, subtree, di, drep, hf_datafile,
5286 			struct_start, NULL);
5287 
5288 	offset = dissect_spoolss_relstr(
5289 			tvb, offset, pinfo, subtree, di, drep, hf_configfile,
5290 			struct_start, NULL);
5291 
5292 	offset = dissect_spoolss_relstr(
5293 			tvb, offset, pinfo, subtree, di, drep, hf_helpfile,
5294 			struct_start, NULL);
5295 
5296 	offset = dissect_spoolss_relstr(
5297 			tvb, offset, pinfo, subtree, di, drep, hf_monitorname,
5298 			struct_start, NULL);
5299 
5300 	offset = dissect_spoolss_relstr(
5301 			tvb, offset, pinfo, subtree, di, drep, hf_defaultdatatype,
5302 			struct_start, NULL);
5303 
5304 	offset = dissect_spoolss_relstrarray(
5305 			tvb, offset, pinfo, subtree, di, drep, hf_dependentfiles,
5306 			struct_start, NULL);
5307 
5308 	offset = dissect_spoolss_relstrarray(
5309 			tvb, offset, pinfo, subtree, di, drep, hf_previousdrivernames,
5310 			struct_start, NULL);
5311 
5312 	offset = dissect_ndr_nt_NTTIME (
5313 			tvb, offset, pinfo, subtree, di, drep,hf_driverdate);
5314 
5315 	offset = dissect_ndr_uint32(
5316 			tvb, offset, pinfo, subtree, di, drep, hf_padding,
5317 			NULL);
5318 
5319 	offset = dissect_ndr_uint32(
5320 			tvb, offset, pinfo, subtree, di, drep, hf_driver_version_low,
5321 			NULL);
5322 
5323 	offset = dissect_ndr_uint32(
5324 			tvb, offset, pinfo, subtree, di, drep, hf_driver_version_high,
5325 			NULL);
5326 
5327 	offset = dissect_spoolss_relstr(
5328 			tvb, offset, pinfo, subtree, di, drep, hf_mfgname,
5329 			struct_start, NULL);
5330 
5331 	offset = dissect_spoolss_relstr(
5332 			tvb, offset, pinfo, subtree, di, drep, hf_oemurl,
5333 			struct_start, NULL);
5334 
5335 	offset = dissect_spoolss_relstr(
5336 			tvb, offset, pinfo, subtree, di, drep, hf_hardwareid,
5337 			struct_start, NULL);
5338 
5339 	offset = dissect_spoolss_relstr(
5340 			tvb, offset, pinfo, subtree, di, drep, hf_provider,
5341 			struct_start, NULL);
5342 
5343 	return offset;
5344 }
5345 
5346 
5347 /*
5348 	DRIVER_INFO_8
5349 */
5350 
5351 static gint ett_DRIVER_INFO_8 = -1;
5352 
5353 static int
dissect_DRIVER_INFO_8(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5354 dissect_DRIVER_INFO_8(tvbuff_t *tvb, int offset,
5355 				 packet_info *pinfo, proto_tree *tree,
5356 				 dcerpc_info *di, guint8 *drep)
5357 {
5358 	proto_tree *subtree;
5359 	int struct_start = offset;
5360 
5361 	subtree = proto_tree_add_subtree(
5362 			tree, tvb, offset, 0, ett_DRIVER_INFO_8, NULL, "Driver info level 8");
5363 
5364 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5365 			hf_driverinfo_cversion, NULL);
5366 
5367 	offset = dissect_spoolss_relstr(
5368 			tvb, offset, pinfo, subtree, di, drep, hf_drivername,
5369 			struct_start, NULL);
5370 
5371 	offset = dissect_spoolss_relstr(
5372 			tvb, offset, pinfo, subtree, di, drep, hf_environment,
5373 			struct_start, NULL);
5374 
5375 	offset = dissect_spoolss_relstr(
5376 			tvb, offset, pinfo, subtree, di, drep, hf_driverpath,
5377 			struct_start, NULL);
5378 
5379 	offset = dissect_spoolss_relstr(
5380 			tvb, offset, pinfo, subtree, di, drep, hf_datafile,
5381 			struct_start, NULL);
5382 
5383 	offset = dissect_spoolss_relstr(
5384 			tvb, offset, pinfo, subtree, di, drep, hf_configfile,
5385 			struct_start, NULL);
5386 
5387 	offset = dissect_spoolss_relstr(
5388 			tvb, offset, pinfo, subtree, di, drep, hf_helpfile,
5389 			struct_start, NULL);
5390 
5391 	offset = dissect_spoolss_relstrarray(
5392 			tvb, offset, pinfo, subtree, di, drep, hf_dependentfiles,
5393 			struct_start, NULL);
5394 
5395 	offset = dissect_spoolss_relstr(
5396 			tvb, offset, pinfo, subtree, di, drep, hf_monitorname,
5397 			struct_start, NULL);
5398 
5399 	offset = dissect_spoolss_relstr(
5400 			tvb, offset, pinfo, subtree, di, drep, hf_defaultdatatype,
5401 			struct_start, NULL);
5402 
5403 	offset = dissect_spoolss_relstrarray(
5404 			tvb, offset, pinfo, subtree, di, drep, hf_previousdrivernames,
5405 			struct_start, NULL);
5406 
5407 	offset = dissect_ndr_nt_NTTIME (
5408 			tvb, offset, pinfo, subtree, di, drep, hf_driverdate);
5409 
5410 	offset = dissect_ndr_uint32(
5411 			tvb, offset, pinfo, subtree, di, drep, hf_padding,
5412 			NULL);
5413 
5414 	offset = dissect_ndr_uint32(
5415 			tvb, offset, pinfo, subtree, di, drep, hf_driver_version_low,
5416 			NULL);
5417 
5418 	offset = dissect_ndr_uint32(
5419 			tvb, offset, pinfo, subtree, di, drep, hf_driver_version_high,
5420 			NULL);
5421 
5422 	offset = dissect_spoolss_relstr(
5423 			tvb, offset, pinfo, subtree, di, drep, hf_mfgname,
5424 			struct_start, NULL);
5425 
5426 	offset = dissect_spoolss_relstr(
5427 			tvb, offset, pinfo, subtree, di, drep, hf_oemurl,
5428 			struct_start, NULL);
5429 
5430 	offset = dissect_spoolss_relstr(
5431 			tvb, offset, pinfo, subtree, di, drep, hf_hardwareid,
5432 			struct_start, NULL);
5433 
5434 	offset = dissect_spoolss_relstr(
5435 			tvb, offset, pinfo, subtree, di, drep, hf_provider,
5436 			struct_start, NULL);
5437 
5438 	offset = dissect_spoolss_relstr(
5439 			tvb, offset, pinfo, subtree, di, drep, hf_printprocessor,
5440 			struct_start, NULL);
5441 
5442 	offset = dissect_spoolss_relstr(
5443 			tvb, offset, pinfo, subtree, di, drep, hf_vendor_setup,
5444 			struct_start, NULL);
5445 
5446 	offset = dissect_spoolss_relstrarray(
5447 			tvb, offset, pinfo, subtree, di, drep, hf_color_profiles,
5448 			struct_start, NULL);
5449 
5450 	offset = dissect_spoolss_relstr(
5451 			tvb, offset, pinfo, subtree, di, drep, hf_inf_path,
5452 			struct_start, NULL);
5453 
5454 	offset = dissect_printer_driver_attributes(
5455 			tvb, offset, pinfo, subtree, di, drep);
5456 
5457 	offset = dissect_spoolss_relstrarray(
5458 			tvb, offset, pinfo, subtree, di, drep, hf_core_driver_dependencies,
5459 			struct_start, NULL);
5460 
5461 	offset = dissect_ndr_nt_NTTIME (
5462 			tvb, offset, pinfo, subtree, di, drep, hf_min_inbox_driverdate);
5463 
5464 	offset = dissect_ndr_uint32(
5465 			tvb, offset, pinfo, subtree, di, drep, hf_min_inbox_driver_version_low,
5466 			NULL);
5467 
5468 	offset = dissect_ndr_uint32(
5469 			tvb, offset, pinfo, subtree, di, drep, hf_min_inbox_driver_version_high,
5470 			NULL);
5471 
5472 	return offset;
5473 }
5474 
5475 
5476 static gint ett_DRIVER_INFO_101 = -1;
5477 
5478 static int
dissect_DRIVER_INFO_101(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5479 dissect_DRIVER_INFO_101(tvbuff_t *tvb, int offset,
5480 				 packet_info *pinfo, proto_tree *tree,
5481 				 dcerpc_info *di, guint8 *drep)
5482 {
5483 	proto_tree *subtree;
5484 	int struct_start = offset;
5485 
5486 	subtree = proto_tree_add_subtree(
5487 			tree, tvb, offset, 0, ett_DRIVER_INFO_101, NULL, "Driver info level 101");
5488 
5489 	offset = dissect_ndr_uint32(tvb, offset, pinfo, subtree, di, drep,
5490 			hf_driverinfo_cversion, NULL);
5491 
5492 	offset = dissect_spoolss_relstr(
5493 			tvb, offset, pinfo, subtree, di, drep, hf_drivername,
5494 			struct_start, NULL);
5495 
5496 	offset = dissect_spoolss_relstr(
5497 			tvb, offset, pinfo, subtree, di, drep, hf_environment,
5498 			struct_start, NULL);
5499 
5500 	proto_tree_add_expert(subtree, pinfo, &ei_unknown_data, tvb, offset, 0);
5501 
5502 	return offset;
5503 }
5504 
5505 /*
5506 	CORE_PRINTER_DRIVER
5507 */
5508 
5509 static gint ett_CORE_PRINTER_DRIVER = -1;
5510 
5511 static int
dissect_CORE_PRINTER_DRIVER(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5512 dissect_CORE_PRINTER_DRIVER(tvbuff_t *tvb, int offset,
5513 				 packet_info *pinfo, proto_tree *tree,
5514 				 dcerpc_info *di, guint8 *drep)
5515 {
5516 	proto_tree *subtree;
5517 
5518 	ALIGN_TO_5_BYTES;
5519 
5520 	subtree = proto_tree_add_subtree(
5521 		tree, tvb, offset, 0, ett_CORE_PRINTER_DRIVER, NULL, "Core Printer Driver");
5522 
5523 	offset = dissect_ndr_uuid_t(tvb, offset, pinfo, subtree, di, drep,
5524 		hf_core_driver_guid, NULL);
5525 
5526 	offset = dissect_ndr_nt_NTTIME(tvb, offset, pinfo, subtree, di, drep,
5527 		hf_driverdate);
5528 
5529 	offset = dissect_ndr_uint64(tvb, offset, pinfo, subtree, di, drep,
5530 		hf_driver_version, NULL);
5531 
5532 	/* The package id is stored in a 260-wchar buffer */
5533 
5534 	dissect_spoolss_uint16uni(tvb, offset, pinfo, subtree, drep, NULL,
5535 		hf_package_id);
5536 
5537 	offset += 520;
5538 
5539 	if (di->call_data->flags & DCERPC_IS_NDR64) {
5540 		ALIGN_TO_5_BYTES;
5541 	}
5542 
5543 	return offset;
5544 }
5545 
5546 
5547 /*
5548  * EnumPrinterDrivers
5549  */
5550 
5551 static int
SpoolssEnumPrinterDrivers_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5552 SpoolssEnumPrinterDrivers_q(tvbuff_t *tvb, int offset,
5553 				       packet_info *pinfo, proto_tree *tree,
5554 				       dcerpc_info *di, guint8 *drep)
5555 {
5556 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
5557 	guint32 level;
5558 
5559 	/* Parse packet */
5560 
5561 	offset = dissect_ndr_str_pointer_item(
5562 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
5563 		"Name", hf_servername, 0);
5564 
5565 	offset = dissect_ndr_str_pointer_item(
5566 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
5567 		"Environment", hf_environment, 0);
5568 
5569 	offset = dissect_ndr_uint32(
5570 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
5571 
5572 	/* EnumPrinterDrivers() stores the level in se_data */
5573 	if(!pinfo->fd->visited){
5574 			dcv->se_data = GUINT_TO_POINTER((int)level);
5575 	}
5576 
5577 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
5578 
5579 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep, NULL);
5580 
5581 	offset = dissect_ndr_uint32(
5582 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
5583 
5584 	return offset;
5585 }
5586 
5587 static int
SpoolssEnumPrinterDrivers_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5588 SpoolssEnumPrinterDrivers_r(tvbuff_t *tvb, int offset,
5589 				       packet_info *pinfo, proto_tree *tree,
5590 				       dcerpc_info *di, guint8 *drep)
5591 {
5592 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
5593 	guint32 level = GPOINTER_TO_UINT(dcv->se_data), num_drivers, i;
5594 	int buffer_offset;
5595 	BUFFER buffer;
5596 
5597 	/* Parse packet */
5598 
5599 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep,
5600 					&buffer);
5601 
5602 	offset = dissect_ndr_uint32(
5603 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
5604 
5605 	offset = dissect_ndr_uint32(
5606 		tvb, offset, pinfo, tree, di, drep, hf_returned,
5607 		&num_drivers);
5608 
5609 	buffer_offset = 0;
5610 
5611 	for (i = 0; i < num_drivers; i++) {
5612 		switch(level) {
5613 		case 1:
5614 			buffer_offset = dissect_DRIVER_INFO_1(
5615 				buffer.tvb, buffer_offset, pinfo,
5616 				buffer.tree, di, drep);
5617 			break;
5618 		case 2:
5619 			buffer_offset = dissect_DRIVER_INFO_2(
5620 				buffer.tvb, buffer_offset, pinfo,
5621 				buffer.tree, di, drep);
5622 			break;
5623 		case 3:
5624 			buffer_offset = dissect_DRIVER_INFO_3(
5625 				buffer.tvb, buffer_offset, pinfo,
5626 				buffer.tree, di, drep);
5627 			break;
5628 		case 6:
5629 			buffer_offset = dissect_DRIVER_INFO_6(
5630 				buffer.tvb, buffer_offset, pinfo,
5631 				buffer.tree, di, drep);
5632 			break;
5633 		case 8:
5634 			buffer_offset = dissect_DRIVER_INFO_8(
5635 				buffer.tvb, buffer_offset, pinfo,
5636 				buffer.tree, di, drep);
5637 			break;
5638 		case 101:
5639 			/*buffer_offset =*/ dissect_DRIVER_INFO_101(
5640 				buffer.tvb, buffer_offset, pinfo,
5641 				buffer.tree, di, drep);
5642 			/*break;*/
5643 			goto done; /*Not entirely imeplemented*/
5644 		default:
5645 			proto_tree_add_expert_format( buffer.tree, pinfo, &ei_driver_info_level, buffer.tvb, buffer_offset, -1, "Unknown driver info level %d", level);
5646 			goto done;
5647 		}
5648 	}
5649 
5650 done:
5651 	offset = dissect_doserror(
5652 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
5653 
5654 	return offset;
5655 }
5656 
5657 /*
5658  * GetPrinterDriver2
5659  */
5660 
5661 static int
SpoolssGetPrinterDriver2_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5662 SpoolssGetPrinterDriver2_q(tvbuff_t *tvb, int offset,
5663 				      packet_info *pinfo, proto_tree *tree,
5664 				      dcerpc_info *di, guint8 *drep)
5665 {
5666 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
5667 	e_ctx_hnd policy_hnd;
5668 	char *pol_name;
5669 	guint32 level;
5670 
5671 	/* Parse packet */
5672 
5673 	offset = dissect_nt_policy_hnd(
5674 		tvb, offset, pinfo, tree, di, drep, hf_hnd, &policy_hnd, NULL,
5675 		FALSE, FALSE);
5676 
5677 	dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
5678 			     pinfo->num);
5679 
5680 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
5681 				pol_name);
5682 
5683 	offset = dissect_ndr_str_pointer_item(
5684 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
5685 		"Environment", hf_environment, 0);
5686 
5687 	offset = dissect_ndr_uint32(
5688 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
5689 
5690 	/* GetPrinterDriver2() stores the level in se_data */
5691 	if(!pinfo->fd->visited){
5692 			dcv->se_data = GUINT_TO_POINTER((int)level);
5693 	}
5694 
5695 	col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
5696 
5697 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep, NULL);
5698 
5699 	offset = dissect_ndr_uint32(
5700 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
5701 
5702 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5703 				    hf_clientmajorversion, NULL);
5704 
5705 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5706 				    hf_clientminorversion, NULL);
5707 
5708 	return offset;
5709 }
5710 
5711 static int
SpoolssGetPrinterDriver2_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5712 SpoolssGetPrinterDriver2_r(tvbuff_t *tvb, int offset,
5713 				      packet_info *pinfo, proto_tree *tree,
5714 				      dcerpc_info *di, guint8 *drep)
5715 {
5716 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
5717 	guint32 level = GPOINTER_TO_UINT(dcv->se_data);
5718 	BUFFER buffer;
5719 
5720 	/* Parse packet */
5721 
5722 	offset = dissect_spoolss_buffer(tvb, offset, pinfo, tree, di, drep,
5723 					&buffer);
5724 
5725 	if (buffer.tvb) {
5726 		switch(level) {
5727 		case 1:
5728 			dissect_DRIVER_INFO_1(
5729 				buffer.tvb, 0, pinfo, buffer.tree, di, drep);
5730 			break;
5731 		case 2:
5732 			dissect_DRIVER_INFO_2(
5733 				buffer.tvb, 0, pinfo, buffer.tree, di, drep);
5734 			break;
5735 		case 3:
5736 			dissect_DRIVER_INFO_3(
5737 				buffer.tvb, 0, pinfo, buffer.tree, di, drep);
5738 			break;
5739 		case 6:
5740 			dissect_DRIVER_INFO_6(
5741 				buffer.tvb, 0, pinfo, buffer.tree, di, drep);
5742 			break;
5743 		case 8:
5744 			dissect_DRIVER_INFO_8(
5745 				buffer.tvb, 0, pinfo, buffer.tree, di, drep);
5746 			break;
5747 		case 101:
5748 			dissect_DRIVER_INFO_101(
5749 				buffer.tvb, 0, pinfo, buffer.tree, di, drep);
5750 			break;
5751 		default:
5752 			proto_tree_add_expert_format( buffer.tree, pinfo, &ei_driver_info_level, buffer.tvb, 0, -1, "Unknown driver info level %d", level);
5753 			break;
5754 		}
5755 	}
5756 
5757 	offset = dissect_ndr_uint32(
5758 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
5759 
5760 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5761 				    hf_servermajorversion, NULL);
5762 
5763 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
5764 				    hf_serverminorversion, NULL);
5765 
5766 	offset = dissect_doserror(
5767 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
5768 
5769 	return offset;
5770 }
5771 
5772 static int
dissect_notify_info_data_buffer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)5773 dissect_notify_info_data_buffer(tvbuff_t *tvb, int offset, packet_info *pinfo,
5774 				proto_tree *tree, dcerpc_info *di, guint8 *drep)
5775 {
5776 	guint32 len;
5777 
5778 	offset = dissect_ndr_uint32(
5779 		tvb, offset, pinfo, tree, di, drep,
5780 		hf_notify_info_data_buffer_len, &len);
5781 
5782 	offset = dissect_ndr_uint16s(
5783 		tvb, offset, pinfo, tree, di, drep,
5784 		hf_notify_info_data_buffer_data, len);
5785 
5786 	return offset;
5787 }
5788 
5789 static void
cb_notify_str_postprocess(packet_info * pinfo _U_,proto_tree * tree,proto_item * item,dcerpc_info * di _U_,tvbuff_t * tvb,int start_offset,int end_offset,void * callback_args)5790 cb_notify_str_postprocess(packet_info *pinfo _U_,
5791 				      proto_tree *tree,
5792 				      proto_item *item, dcerpc_info *di _U_, tvbuff_t *tvb,
5793 				      int start_offset, int end_offset,
5794 				      void *callback_args)
5795 {
5796 	gint levels, hf_index = GPOINTER_TO_INT(callback_args);
5797 	guint32 len;
5798 	char *s;
5799 	proto_item *hidden_item;
5800 
5801 	/* Align start_offset on 4-byte boundary. */
5802 
5803 	if (start_offset % 4)
5804 		start_offset += 4 - (start_offset % 4);
5805 
5806 	/* Get string length */
5807 
5808 	len = tvb_get_letohl(tvb, start_offset);
5809 
5810 	s = tvb_get_string_enc(pinfo->pool,
5811 		tvb, start_offset + 4, (end_offset - start_offset - 4), ENC_UTF_16|ENC_LITTLE_ENDIAN);
5812 
5813 	/* Append string to upper-level proto_items */
5814 
5815 	levels = 2;
5816 
5817 	if (levels > 0 && item && s && s[0]) {
5818 		proto_item_append_text(item, ": %s", s);
5819 		item = item->parent;
5820 		levels--;
5821 		if (levels > 0) {
5822 			proto_item_append_text(item, ": %s", s);
5823 			item = item->parent;
5824 			levels--;
5825 			while (levels > 0) {
5826 				proto_item_append_text(item, " %s", s);
5827 				item = item->parent;
5828 				levels--;
5829 			}
5830 		}
5831 	}
5832 
5833 	/* Add hidden field so filter brings up any notify data */
5834 
5835 	if (hf_index != -1) {
5836 		hidden_item = proto_tree_add_string(
5837 			tree, hf_index, tvb, start_offset, len, s);
5838 		proto_item_set_hidden(hidden_item);
5839 	}
5840 }
5841 
5842 /* Return the hf_index for a printer notify field.  This is used to
5843    add a hidden string to the display so that filtering will bring
5844    up relevant notify data. */
5845 
5846 static int
printer_notify_hf_index(int field)5847 printer_notify_hf_index(int field)
5848 {
5849 	int result = -1;
5850 
5851 	switch(field) {
5852 	case PRINTER_NOTIFY_SERVER_NAME:
5853 		result = hf_servername;
5854 		break;
5855 	case PRINTER_NOTIFY_PRINTER_NAME:
5856 		result = hf_printername;
5857 		break;
5858 	case PRINTER_NOTIFY_SHARE_NAME:
5859 		result = hf_sharename;
5860 		break;
5861 	case PRINTER_NOTIFY_PORT_NAME:
5862 		result = hf_portname;
5863 		break;
5864 	case PRINTER_NOTIFY_DRIVER_NAME:
5865 		result = hf_drivername;
5866 		break;
5867 	case PRINTER_NOTIFY_COMMENT:
5868 		result = hf_printercomment;
5869 		break;
5870 	case PRINTER_NOTIFY_LOCATION:
5871 		result = hf_printerlocation;
5872 		break;
5873 	case PRINTER_NOTIFY_SEPFILE:
5874 		result = hf_sepfile;
5875 		break;
5876 	case PRINTER_NOTIFY_PRINT_PROCESSOR:
5877 		result = hf_printprocessor;
5878 		break;
5879 	case PRINTER_NOTIFY_PARAMETERS:
5880 		result = hf_parameters;
5881 		break;
5882 	case PRINTER_NOTIFY_DATATYPE:
5883 		result = hf_parameters;
5884 		break;
5885 	}
5886 
5887 	return result;
5888 }
5889 
5890 static int
job_notify_hf_index(int field)5891 job_notify_hf_index(int field)
5892 {
5893 	int result = -1;
5894 
5895 	switch(field) {
5896 	case JOB_NOTIFY_PRINTER_NAME:
5897 		result = hf_printername;
5898 		break;
5899 	case JOB_NOTIFY_MACHINE_NAME:
5900 		result = hf_machinename;
5901 		break;
5902 	case JOB_NOTIFY_PORT_NAME:
5903 		result = hf_portname;
5904 		break;
5905 	case JOB_NOTIFY_USER_NAME:
5906 		result = hf_username;
5907 		break;
5908 	case JOB_NOTIFY_NOTIFY_NAME:
5909 		result = hf_notifyname;
5910 		break;
5911 	case JOB_NOTIFY_DATATYPE:
5912 		result = hf_datatype;
5913 		break;
5914 	case JOB_NOTIFY_PRINT_PROCESSOR:
5915 		result = hf_printprocessor;
5916 		break;
5917 	case JOB_NOTIFY_DRIVER_NAME:
5918 		result = hf_drivername;
5919 		break;
5920 	case JOB_NOTIFY_DOCUMENT:
5921 		result = hf_documentname;
5922 		break;
5923 	case JOB_NOTIFY_PRIORITY:
5924 		result = hf_job_priority;
5925 		break;
5926 	case JOB_NOTIFY_POSITION:
5927 		result = hf_job_position;
5928 		break;
5929 	case JOB_NOTIFY_TOTAL_PAGES:
5930 		result = hf_job_totalpages;
5931 		break;
5932 	case JOB_NOTIFY_PAGES_PRINTED:
5933 		result = hf_job_pagesprinted;
5934 		break;
5935 	case JOB_NOTIFY_TOTAL_BYTES:
5936 		result = hf_job_totalbytes;
5937 		break;
5938 	case JOB_NOTIFY_BYTES_PRINTED:
5939 		result = hf_job_bytesprinted;
5940 		break;
5941 	}
5942 
5943 	return result;
5944 }
5945 
5946 static int
dissect_NOTIFY_INFO_DATA_printer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,proto_item * item,dcerpc_info * di,guint8 * drep,guint16 field)5947 dissect_NOTIFY_INFO_DATA_printer(tvbuff_t *tvb, int offset, packet_info *pinfo,
5948 				 proto_tree *tree, proto_item *item,
5949 				 dcerpc_info *di, guint8 *drep, guint16 field)
5950 {
5951 	guint32 value1;
5952 
5953 	switch (field) {
5954 
5955 		/* String notify data */
5956 
5957 	case PRINTER_NOTIFY_SERVER_NAME:
5958 	case PRINTER_NOTIFY_PRINTER_NAME:
5959 	case PRINTER_NOTIFY_SHARE_NAME:
5960 	case PRINTER_NOTIFY_DRIVER_NAME:
5961 	case PRINTER_NOTIFY_COMMENT:
5962 	case PRINTER_NOTIFY_LOCATION:
5963 	case PRINTER_NOTIFY_SEPFILE:
5964 	case PRINTER_NOTIFY_PRINT_PROCESSOR:
5965 	case PRINTER_NOTIFY_PARAMETERS:
5966 	case PRINTER_NOTIFY_DATATYPE:
5967 	case PRINTER_NOTIFY_PORT_NAME:
5968 
5969 		offset = dissect_ndr_uint32(
5970 			tvb, offset, pinfo, tree, di, drep,
5971 			hf_notify_info_data_bufsize, &value1);
5972 
5973 		offset = dissect_ndr_pointer_cb(
5974 			tvb, offset, pinfo, tree, di, drep,
5975 			dissect_notify_info_data_buffer,
5976 			NDR_POINTER_UNIQUE, "String",
5977 			hf_notify_info_data_buffer,
5978 			cb_notify_str_postprocess,
5979 			GINT_TO_POINTER(printer_notify_hf_index(field)));
5980 
5981 		break;
5982 
5983 	case PRINTER_NOTIFY_ATTRIBUTES:
5984 
5985 		/* Value 1 is the printer attributes */
5986 
5987 		offset = dissect_printer_attributes(
5988 			tvb, offset, pinfo, tree, di, drep);
5989 
5990 		offset = dissect_ndr_uint32(
5991 			tvb, offset, pinfo, NULL, di, drep,
5992 			hf_notify_info_data_value2, NULL);
5993 
5994 		break;
5995 
5996 	case PRINTER_NOTIFY_STATUS: {
5997 		guint32 status;
5998 
5999 		/* Value 1 is the printer status */
6000 
6001  		offset = dissect_ndr_uint32(
6002 			tvb, offset, pinfo, tree, di, drep,
6003 			hf_printer_status, &status);
6004 
6005 		offset = dissect_ndr_uint32(
6006 			tvb, offset, pinfo, NULL, di, drep,
6007 			hf_notify_info_data_value2, NULL);
6008 
6009 		proto_item_append_text(
6010 			item, ": %s",
6011 			val_to_str_ext_const(status, &printer_status_vals_ext, "Unknown"));
6012 
6013 		break;
6014 	}
6015 
6016 		/* Unknown notify data */
6017 
6018 	case PRINTER_NOTIFY_SECURITY_DESCRIPTOR: /* Secdesc */
6019 	case PRINTER_NOTIFY_DEVMODE: /* Devicemode */
6020 
6021 		offset = dissect_ndr_uint32(
6022 			tvb, offset, pinfo, tree, di, drep,
6023 			hf_notify_info_data_bufsize, &value1);
6024 
6025 		offset = dissect_ndr_pointer(
6026 			tvb, offset, pinfo, tree, di, drep,
6027 			dissect_notify_info_data_buffer,
6028 			NDR_POINTER_UNIQUE, "Buffer",
6029 			hf_notify_info_data_buffer);
6030 
6031 		break;
6032 
6033 	default:
6034 		offset = dissect_ndr_uint32(
6035 			tvb, offset, pinfo, tree, di, drep,
6036 			hf_notify_info_data_value1, NULL);
6037 
6038 		offset = dissect_ndr_uint32(
6039 			tvb, offset, pinfo, tree, di, drep,
6040 			hf_notify_info_data_value2, NULL);
6041 
6042 		break;
6043 	}
6044 	return offset;
6045 }
6046 
6047 static void
notify_job_time_cb(packet_info * pinfo _U_,proto_tree * tree _U_,proto_item * item,dcerpc_info * di,tvbuff_t * tvb _U_,int start_offset _U_,int end_offset _U_,void * callback_args _U_)6048 notify_job_time_cb(packet_info *pinfo _U_, proto_tree *tree _U_,
6049 			       proto_item *item, dcerpc_info *di, tvbuff_t *tvb _U_,
6050 			       int start_offset _U_, int end_offset _U_,
6051 			       void *callback_args _U_)
6052 {
6053 	dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
6054 	char *str = (char *)dcv->private_data;
6055 
6056 	/* Append job string stored in dcv->private_data by
6057 	   dissect_SYSTEM_TIME_ptr() in the current item as well
6058 	   as the parent. */
6059 
6060 	proto_item_append_text(item, ": %s", str);
6061 
6062 	if (item)
6063 		proto_item_append_text(item->parent, ": %s", str);
6064 }
6065 
6066 static int
dissect_NOTIFY_INFO_DATA_job(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,proto_item * item,dcerpc_info * di,guint8 * drep,guint16 field)6067 dissect_NOTIFY_INFO_DATA_job(tvbuff_t *tvb, int offset, packet_info *pinfo,
6068 			     proto_tree *tree, proto_item *item, dcerpc_info *di, guint8 *drep,
6069 			     guint16 field)
6070 {
6071 	guint32 value1;
6072 	proto_item *hidden_item;
6073 
6074 	switch (field) {
6075 
6076 		/* String notify data */
6077 
6078 	case JOB_NOTIFY_PRINTER_NAME:
6079 	case JOB_NOTIFY_MACHINE_NAME:
6080 	case JOB_NOTIFY_PORT_NAME:
6081 	case JOB_NOTIFY_USER_NAME:
6082 	case JOB_NOTIFY_NOTIFY_NAME:
6083 	case JOB_NOTIFY_DATATYPE:
6084 	case JOB_NOTIFY_PRINT_PROCESSOR:
6085 	case JOB_NOTIFY_PARAMETERS:
6086 	case JOB_NOTIFY_DRIVER_NAME:
6087 	case JOB_NOTIFY_STATUS_STRING:
6088 	case JOB_NOTIFY_DOCUMENT:
6089 
6090 		offset = dissect_ndr_uint32(
6091 			tvb, offset, pinfo, tree, di, drep,
6092 			hf_notify_info_data_bufsize, &value1);
6093 
6094 		offset = dissect_ndr_pointer_cb(
6095 			tvb, offset, pinfo, tree, di, drep,
6096 			dissect_notify_info_data_buffer,
6097 			NDR_POINTER_UNIQUE, "String",
6098 			hf_notify_info_data_buffer,
6099 			cb_notify_str_postprocess,
6100 			GINT_TO_POINTER(job_notify_hf_index(field)));
6101 
6102 		break;
6103 
6104 	case JOB_NOTIFY_STATUS:
6105 		offset = dissect_job_status(
6106 			tvb, offset, pinfo, tree, di, drep);
6107 
6108 		offset = dissect_ndr_uint32(
6109 			tvb, offset, pinfo, NULL, di, drep,
6110 			hf_notify_info_data_value2, NULL);
6111 
6112 		break;
6113 
6114 	case JOB_NOTIFY_SUBMITTED:
6115 
6116 		/* SYSTEM_TIME */
6117 
6118 		offset = dissect_ndr_uint32(
6119 			tvb, offset, pinfo, tree, di, drep,
6120 			hf_notify_info_data_buffer_len, NULL);
6121 
6122 		offset = dissect_ndr_pointer_cb(
6123 			tvb, offset, pinfo, tree, di, drep,
6124 			dissect_SYSTEM_TIME_ptr, NDR_POINTER_UNIQUE,
6125 			"Time submitted", -1, notify_job_time_cb, NULL);
6126 
6127 		break;
6128 
6129 	case JOB_NOTIFY_PRIORITY:
6130 	case JOB_NOTIFY_POSITION:
6131 	case JOB_NOTIFY_TOTAL_PAGES:
6132 	case JOB_NOTIFY_PAGES_PRINTED:
6133 	case JOB_NOTIFY_TOTAL_BYTES:
6134 	case JOB_NOTIFY_BYTES_PRINTED: {
6135 		guint32 value;
6136 
6137 		offset = dissect_ndr_uint32(
6138 			tvb, offset, pinfo, tree, di, drep,
6139 			hf_notify_info_data_value1, &value);
6140 
6141 		offset = dissect_ndr_uint32(
6142 			tvb, offset, pinfo, tree, di, drep,
6143 			hf_notify_info_data_value2, NULL);
6144 
6145 		proto_item_append_text(item, ": %d", value);
6146 
6147 		hidden_item = proto_tree_add_uint(
6148 			tree, job_notify_hf_index(field), tvb,
6149 			offset, 4, value);
6150 		proto_item_set_hidden(hidden_item);
6151 
6152 		break;
6153 	}
6154 
6155 		/* Unknown notify data */
6156 
6157 	case JOB_NOTIFY_DEVMODE:
6158 
6159 		offset = dissect_ndr_uint32(
6160 			tvb, offset, pinfo, tree, di, drep,
6161 			hf_notify_info_data_bufsize, &value1);
6162 
6163 		offset = dissect_ndr_pointer(
6164 			tvb, offset, pinfo, tree, di, drep,
6165 			dissect_notify_info_data_buffer,
6166 			NDR_POINTER_UNIQUE, "Buffer",
6167 			hf_notify_info_data_buffer);
6168 
6169 		break;
6170 
6171 	default:
6172 		offset = dissect_ndr_uint32(
6173 			tvb, offset, pinfo, tree, di, drep,
6174 			hf_notify_info_data_value1, NULL);
6175 
6176 		offset = dissect_ndr_uint32(
6177 			tvb, offset, pinfo, tree, di, drep,
6178 			hf_notify_info_data_value2, NULL);
6179 	}
6180 	return offset;
6181 }
6182 
6183 static gint ett_NOTIFY_INFO_DATA = -1;
6184 
6185 static int
dissect_NOTIFY_INFO_DATA(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6186 dissect_NOTIFY_INFO_DATA(tvbuff_t *tvb, int offset, packet_info *pinfo,
6187 			 proto_tree *tree, dcerpc_info *di, guint8 *drep)
6188 {
6189 	proto_item *item;
6190 	proto_tree *subtree;
6191 	guint32 count;
6192 	guint16 type, field;
6193 	const char *field_string;
6194 
6195 	subtree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_NOTIFY_INFO_DATA, &item, "");
6196 
6197 	offset = dissect_ndr_uint16(
6198 		tvb, offset, pinfo, subtree, di, drep,
6199 		hf_notify_info_data_type, &type);
6200 
6201 	offset = dissect_notify_field(
6202 		tvb, offset, pinfo, subtree, di, drep, type, &field);
6203 
6204 	switch(type) {
6205 	case PRINTER_NOTIFY_TYPE:
6206 		field_string = val_to_str_ext(
6207 			field, &printer_notify_option_data_vals_ext,
6208 			"Unknown (%d)");
6209 		break;
6210 	case JOB_NOTIFY_TYPE:
6211 		field_string = val_to_str_ext(
6212 			field, &job_notify_option_data_vals_ext,
6213 			"Unknown (%d)");
6214 		break;
6215 	default:
6216 		field_string = "Unknown field";
6217 		break;
6218 	}
6219 
6220 	proto_item_append_text(
6221 		item, "%s, %s",
6222 		val_to_str(type, printer_notify_types, "Unknown (%d)"),
6223 		field_string);
6224 
6225 	offset = dissect_ndr_uint32(
6226 		tvb, offset, pinfo, subtree, di, drep,
6227 		hf_notify_info_data_count, &count);
6228 
6229 	offset = dissect_ndr_uint32(
6230 		tvb, offset, pinfo, subtree, di, drep,
6231 		hf_notify_info_data_id, NULL);
6232 
6233 	offset = dissect_ndr_uint32(
6234 		tvb, offset, pinfo, subtree, di, drep,
6235 		hf_notify_info_data_count, NULL);
6236 
6237 	/* The value here depends on (type, field) */
6238 
6239 	switch (type) {
6240 	case PRINTER_NOTIFY_TYPE:
6241 		offset = dissect_NOTIFY_INFO_DATA_printer(
6242 			tvb, offset, pinfo, subtree, item, di, drep, field);
6243 		break;
6244 	case JOB_NOTIFY_TYPE:
6245 		offset = dissect_NOTIFY_INFO_DATA_job(
6246 			tvb, offset, pinfo, subtree, item, di, drep, field);
6247 		break;
6248 	default:
6249 		expert_add_info(pinfo, item, &ei_notify_info_data_type);
6250 		break;
6251 	}
6252 
6253 	return offset;
6254 }
6255 
6256 int
dissect_NOTIFY_INFO(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6257 dissect_NOTIFY_INFO(tvbuff_t *tvb, int offset, packet_info *pinfo,
6258 		    proto_tree *tree, dcerpc_info *di, guint8 *drep)
6259 {
6260 	guint32 count;
6261 
6262 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6263 				    hf_notify_info_version, NULL);
6264 
6265 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6266 				    hf_notify_info_flags, NULL);
6267 
6268 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6269 				    hf_notify_info_count, &count);
6270 
6271 	if (!di->conformant_run)
6272 		col_append_fstr(
6273 			pinfo->cinfo, COL_INFO, ", %d %s", count,
6274 			notify_plural(count));
6275 
6276 	offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep,
6277 				     dissect_NOTIFY_INFO_DATA);
6278 
6279 	return offset;
6280 }
6281 
6282 /*
6283  * RFNPCNEX
6284  */
6285 
6286 static int
SpoolssRFNPCNEX_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6287 SpoolssRFNPCNEX_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
6288 			     proto_tree *tree, dcerpc_info *di, guint8 *drep)
6289 {
6290 	guint32 changeid;
6291 
6292 	/* Parse packet */
6293 
6294 	offset = dissect_nt_policy_hnd(
6295 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6296 		FALSE, FALSE);
6297 
6298 	offset = dissect_ndr_uint32(
6299 		tvb, offset, pinfo, tree, di, drep, hf_rrpcn_changelow, &changeid);
6300 
6301 	col_append_fstr(
6302 			pinfo->cinfo, COL_INFO, ", changeid %d", changeid);
6303 
6304 	offset = dissect_ndr_pointer(
6305 		tvb, offset, pinfo, tree, di, drep,
6306 		dissect_NOTIFY_OPTIONS_ARRAY_CTR, NDR_POINTER_UNIQUE,
6307 		"Notify Options Array Container", -1);
6308 
6309 	return offset;
6310 }
6311 
6312 static int
SpoolssRFNPCNEX_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6313 SpoolssRFNPCNEX_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
6314 			     proto_tree *tree, dcerpc_info *di, guint8 *drep)
6315 {
6316 	/* Parse packet */
6317 
6318 	offset = dissect_ndr_pointer(
6319 		tvb, offset, pinfo, tree, di, drep,
6320 		dissect_NOTIFY_INFO, NDR_POINTER_UNIQUE,
6321 		"Notify Info", -1);
6322 
6323 	offset = dissect_doserror(
6324 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6325 
6326 	return offset;
6327 }
6328 
6329 /*
6330  * RRPCN
6331  */
6332 
6333 static int
SpoolssRRPCN_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6334 SpoolssRRPCN_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
6335 			  proto_tree *tree, dcerpc_info *di, guint8 *drep)
6336 {
6337 	guint32 changeid;
6338 
6339 	/* Parse packet */
6340 
6341 	offset = dissect_nt_policy_hnd(
6342 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6343 		FALSE, FALSE);
6344 
6345 	offset = dissect_ndr_uint32(
6346 		tvb, offset, pinfo, tree, di, drep, hf_rrpcn_changelow, &changeid);
6347 
6348 	col_append_fstr(
6349 			pinfo->cinfo, COL_INFO, ", changeid %d", changeid);
6350 
6351 	offset = dissect_ndr_uint32(
6352 		tvb, offset, pinfo, tree, di, drep, hf_rrpcn_changehigh, NULL);
6353 
6354 	offset = dissect_ndr_uint32(
6355 		tvb, offset, pinfo, tree, di, drep, hf_rrpcn_unk0, NULL);
6356 
6357 	offset = dissect_ndr_uint32(
6358 		tvb, offset, pinfo, tree, di, drep, hf_rrpcn_unk1, NULL);
6359 
6360 	offset = dissect_ndr_pointer(
6361 		tvb, offset, pinfo, tree, di, drep,
6362 		dissect_NOTIFY_INFO, NDR_POINTER_UNIQUE,
6363 		"Notify Info", -1);
6364 
6365 	/* Notify info */
6366 
6367 	return offset;
6368 }
6369 
6370 static int
SpoolssRRPCN_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6371 SpoolssRRPCN_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
6372 			  proto_tree *tree, dcerpc_info *di, guint8 *drep)
6373 {
6374 	/* Parse packet */
6375 
6376 	offset = dissect_ndr_uint32(
6377 		tvb, offset, pinfo, tree, di, drep, hf_rrpcn_unk0, NULL);
6378 
6379 	offset = dissect_doserror(
6380 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6381 
6382 	return offset;
6383 }
6384 
6385 /*
6386  * ReplyClosePrinter
6387  */
6388 
6389 static int
SpoolssReplyClosePrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6390 SpoolssReplyClosePrinter_q(tvbuff_t *tvb, int offset,
6391 				      packet_info *pinfo, proto_tree *tree,
6392 				      dcerpc_info *di, guint8 *drep)
6393 {
6394 	/* Parse packet */
6395 
6396 	offset = dissect_nt_policy_hnd(
6397 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6398 		FALSE, TRUE);
6399 
6400 	return offset;
6401 }
6402 
6403 static int
SpoolssReplyClosePrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6404 SpoolssReplyClosePrinter_r(tvbuff_t *tvb, int offset,
6405 				      packet_info *pinfo, proto_tree *tree,
6406 				      dcerpc_info *di, guint8 *drep)
6407 {
6408 	/* Parse packet */
6409 
6410 	offset = dissect_nt_policy_hnd(
6411 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6412 		FALSE, FALSE);
6413 
6414 	offset = dissect_doserror(
6415 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6416 
6417 	return offset;
6418 }
6419 
6420 /*
6421  * FCPN
6422  */
6423 
6424 static int
SpoolssFCPN_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6425 SpoolssFCPN_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
6426 			proto_tree *tree, dcerpc_info *di, guint8 *drep)
6427 {
6428 	/* Parse packet */
6429 
6430 	offset = dissect_nt_policy_hnd(
6431 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6432 		FALSE, FALSE);
6433 
6434 	return offset;
6435 }
6436 
6437 static int
SpoolssFCPN_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6438 SpoolssFCPN_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
6439 			proto_tree *tree, dcerpc_info *di, guint8 *drep)
6440 {
6441 	/* Parse packet */
6442 
6443 	offset = dissect_doserror(
6444 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6445 
6446 	return offset;
6447 }
6448 
6449 /*
6450  * RouterReplyPrinter
6451  */
6452 
6453 static int hf_routerreplyprinter_condition = -1;
6454 static int hf_routerreplyprinter_unknown1 = -1;
6455 static int hf_routerreplyprinter_changeid = -1;
6456 
6457 static int
SpoolssRouterReplyPrinter_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6458 SpoolssRouterReplyPrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
6459 				       proto_tree *tree, dcerpc_info *di, guint8 *drep)
6460 {
6461 	/* Parse packet */
6462 
6463 	offset = dissect_nt_policy_hnd(
6464 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6465 		FALSE, FALSE);
6466 
6467 	offset = dissect_ndr_uint32(
6468 		tvb, offset, pinfo, tree, di, drep,
6469 		hf_routerreplyprinter_condition, NULL);
6470 
6471 	offset = dissect_ndr_uint32(
6472 		tvb, offset, pinfo, tree, di, drep,
6473 		hf_routerreplyprinter_unknown1, NULL);
6474 
6475 	offset = dissect_ndr_uint32(
6476 		tvb, offset, pinfo, tree, di, drep,
6477 		hf_routerreplyprinter_changeid, NULL);
6478 
6479 	return offset;
6480 }
6481 
6482 static int
SpoolssRouterReplyPrinter_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6483 SpoolssRouterReplyPrinter_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
6484 				       proto_tree *tree, dcerpc_info *di, guint8 *drep)
6485 {
6486 	/* Parse packet */
6487 
6488 	offset = dissect_doserror(
6489 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6490 
6491 	return offset;
6492 }
6493 
6494 static int hf_keybuffer_size = -1;
6495 
6496 static int
dissect_spoolss_keybuffer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6497 dissect_spoolss_keybuffer(tvbuff_t *tvb, int offset, packet_info *pinfo,
6498 			  proto_tree *tree, dcerpc_info *di, guint8 *drep)
6499 {
6500 	guint32 size;
6501 	int end_offset;
6502 
6503 	if (di->conformant_run)
6504 		return offset;
6505 
6506 	/* Dissect size and data */
6507 
6508 	offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
6509 				    hf_keybuffer_size, &size);
6510 
6511 	end_offset = offset + (size*2);
6512 	if (end_offset < offset) {
6513 		/*
6514 		 * Overflow - make the end offset one past the end of
6515 		 * the packet data, so we throw an exception (as the
6516 		 * size is almost certainly too big).
6517 		 */
6518 		end_offset = tvb_reported_length_remaining(tvb, offset) + 1;
6519 	}
6520 
6521 	while (offset > 0 && offset < end_offset) {
6522 		offset = dissect_spoolss_uint16uni(
6523 			tvb, offset, pinfo, tree, drep, NULL, hf_keybuffer);
6524 	}
6525 
6526 	return offset;
6527 }
6528 
6529 
6530 static int
SpoolssEnumPrinterKey_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6531 SpoolssEnumPrinterKey_q(tvbuff_t *tvb, int offset,
6532 				   packet_info *pinfo, proto_tree *tree,
6533 				   dcerpc_info *di, guint8 *drep)
6534 {
6535 	char *key_name;
6536 
6537 	/* Parse packet */
6538 
6539 	offset = dissect_nt_policy_hnd(
6540 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6541 		FALSE, FALSE);
6542 
6543 	offset = dissect_ndr_cvstring(
6544 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
6545 		hf_printerdata_key, TRUE, &key_name);
6546 
6547 	if (!key_name[0])
6548 		key_name = "\"\"";
6549 
6550 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", key_name);
6551 
6552 	offset = dissect_ndr_uint32(
6553 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
6554 
6555 	return offset;
6556 }
6557 
6558 static int
SpoolssEnumPrinterKey_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6559 SpoolssEnumPrinterKey_r(tvbuff_t *tvb, int offset,
6560 				   packet_info *pinfo, proto_tree *tree,
6561 				   dcerpc_info *di, guint8 *drep)
6562 {
6563 	/* Parse packet */
6564 
6565 	offset = dissect_spoolss_keybuffer(tvb, offset, pinfo, tree, di, drep);
6566 
6567 	offset = dissect_ndr_uint32(
6568 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
6569 
6570 	offset = dissect_doserror(
6571 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6572 
6573 	return offset;
6574 }
6575 
6576 static int hf_enumprinterdataex_name_offset = -1;
6577 static int hf_enumprinterdataex_name_len = -1;
6578 static int hf_enumprinterdataex_name = -1;
6579 static int hf_enumprinterdataex_val_offset = -1;
6580 static int hf_enumprinterdataex_val_len = -1;
6581 static int hf_enumprinterdataex_val_dword_low = -1;
6582 static int hf_enumprinterdataex_val_dword_high = -1;
6583 static int hf_enumprinterdataex_value_null = -1;
6584 static int hf_enumprinterdataex_value_uint = -1;
6585 static int hf_enumprinterdataex_value_binary = -1;
6586 static int hf_enumprinterdataex_value_multi_sz = -1;
6587 
6588 static int
SpoolssEnumPrinterDataEx_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6589 SpoolssEnumPrinterDataEx_q(tvbuff_t *tvb, int offset,
6590 				      packet_info *pinfo, proto_tree *tree,
6591 				      dcerpc_info *di, guint8 *drep)
6592 {
6593 	char *key_name;
6594 	proto_item *hidden_item;
6595 
6596 	hidden_item = proto_tree_add_uint(
6597 		tree, hf_printerdata, tvb, offset, 0, 1);
6598 	proto_item_set_hidden(hidden_item);
6599 
6600 	/* Parse packet */
6601 
6602 	offset = dissect_nt_policy_hnd(
6603 		tvb, offset, pinfo, tree, di, drep, hf_hnd, NULL, NULL,
6604 		FALSE, FALSE);
6605 
6606 	offset = dissect_ndr_cvstring(
6607 		tvb, offset, pinfo, tree, di, drep, sizeof(guint16),
6608 		hf_printerdata_key, TRUE, &key_name);
6609 
6610 	col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", key_name);
6611 
6612 	offset = dissect_ndr_uint32(
6613 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
6614 
6615 	return offset;
6616 }
6617 
6618 static gint ett_printer_enumdataex_value = -1;
6619 
6620 static int
dissect_spoolss_printer_enum_values(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6621 dissect_spoolss_printer_enum_values(tvbuff_t *tvb, int offset,
6622 				    packet_info *pinfo, proto_tree *tree,
6623 				    dcerpc_info *di, guint8 *drep)
6624 {
6625 	guint32 start_offset = offset;
6626 	guint32 name_offset, name_len, val_offset, val_len, val_type;
6627 	char *name;
6628 	proto_item *item;
6629 	proto_tree *subtree;
6630 
6631 	/* Get offset of value name */
6632 
6633 	offset = dissect_ndr_uint32(
6634 		tvb, offset, pinfo, NULL, di, drep,
6635 		hf_enumprinterdataex_name_offset, &name_offset);
6636 
6637 	offset = dissect_ndr_uint32(
6638 		tvb, offset, pinfo, NULL, di, drep,
6639 		hf_enumprinterdataex_name_len, &name_len);
6640 
6641 	dissect_spoolss_uint16uni(
6642 		tvb, start_offset + name_offset, pinfo, NULL, drep,
6643 		&name, hf_enumprinterdataex_name);
6644 
6645 	subtree = proto_tree_add_subtree_format(tree, tvb, offset, 0, ett_printer_enumdataex_value, &item, "Name: %s", name);
6646 
6647 	proto_tree_add_uint(subtree, hf_enumprinterdataex_name_offset, tvb, offset - 8, 4, name_offset);
6648 
6649 	proto_tree_add_uint(subtree, hf_enumprinterdataex_name_len, tvb, offset - 4, 4, name_len);
6650 
6651 	proto_tree_add_string( subtree, hf_enumprinterdataex_name, tvb, start_offset + name_offset, ((int)strlen(name) + 1) * 2, name);
6652 
6653 	offset = dissect_ndr_uint32(
6654 		tvb, offset, pinfo, subtree, di, drep, hf_printerdata_type,
6655 		&val_type);
6656 
6657 	offset = dissect_ndr_uint32(
6658 		tvb, offset, pinfo, subtree, di, drep,
6659 		hf_enumprinterdataex_val_offset, &val_offset);
6660 
6661 	offset = dissect_ndr_uint32(
6662 		tvb, offset, pinfo, subtree, di, drep,
6663 		hf_enumprinterdataex_val_len, &val_len);
6664 
6665 	if (val_len == 0) {
6666 		proto_tree_add_uint_format_value(subtree, hf_enumprinterdataex_value_null, tvb, start_offset + val_offset, 4, 0, "(null)");
6667 		return offset;
6668 	}
6669 
6670 	switch(val_type) {
6671 	case DCERPC_REG_DWORD: {
6672 		guint32 value;
6673 		guint16 low, high;
6674 		int offset2 = start_offset + val_offset;
6675 
6676 		/* Needs to be broken into two 16-byte ints because it may
6677 		   not be aligned. */
6678 
6679 		offset2 = dissect_ndr_uint16(
6680 			tvb, offset2, pinfo, subtree, di, drep,
6681 			hf_enumprinterdataex_val_dword_low, &low);
6682 
6683 		/*offset2 = */dissect_ndr_uint16(
6684 			tvb, offset2, pinfo, subtree, di, drep,
6685 			hf_enumprinterdataex_val_dword_high, &high);
6686 
6687 		value = (high << 16) | low;
6688 
6689 		proto_tree_add_uint(subtree, hf_enumprinterdataex_value_uint, tvb, start_offset + val_offset, 4, value);
6690 
6691 		proto_item_append_text(item, ", Value: %d", value);
6692 
6693 		break;
6694 	}
6695 	case DCERPC_REG_SZ: {
6696 		char *value;
6697 
6698 		dissect_spoolss_uint16uni(
6699 			tvb, start_offset + val_offset, pinfo, subtree, drep,
6700 			&value, hf_value_string);
6701 
6702 		proto_item_append_text(item, ", Value: %s", value);
6703 
6704 		break;
6705 	}
6706 	case DCERPC_REG_BINARY:
6707 
6708 		/* FIXME: nicer way to display this */
6709 
6710 		proto_tree_add_bytes_format_value( subtree, hf_enumprinterdataex_value_binary, tvb, start_offset + val_offset, val_len, NULL, "<binary data>");
6711 		break;
6712 
6713 	case DCERPC_REG_MULTI_SZ:
6714 
6715 		/* FIXME: implement REG_MULTI_SZ support */
6716 
6717 		proto_tree_add_bytes_format_value(subtree, hf_enumprinterdataex_value_multi_sz, tvb, start_offset + val_offset, val_len, NULL, "<REG_MULTI_SZ not implemented>");
6718 		break;
6719 
6720 	default:
6721 		proto_tree_add_expert_format( subtree, pinfo, &ei_enumprinterdataex_value, tvb, start_offset + val_offset, val_len, "%s: unknown type %d", name, val_type);
6722 	}
6723 
6724 	return offset;
6725 }
6726 
6727 static gint ett_PRINTER_DATA_CTR = -1;
6728 
6729 static int
SpoolssEnumPrinterDataEx_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6730 SpoolssEnumPrinterDataEx_r(tvbuff_t *tvb, int offset,
6731 				   packet_info *pinfo, proto_tree *tree,
6732 				   dcerpc_info *di, guint8 *drep)
6733 {
6734 	guint32 size, num_values;
6735 	proto_item *hidden_item;
6736 
6737 	hidden_item = proto_tree_add_uint(
6738 		tree, hf_printerdata, tvb, offset, 0, 1);
6739 	proto_item_set_hidden(hidden_item);
6740 
6741 	/* Parse packet */
6742 
6743 	offset = dissect_ndr_uint32(
6744 		tvb, offset, pinfo, tree, di, drep,
6745 		hf_buffer_size, &size);
6746 
6747 	dissect_ndr_uint32(
6748 		tvb, offset + size + 4, pinfo, NULL, di, drep, hf_returned,
6749 		&num_values);
6750 
6751 	if (size) {
6752 		proto_tree *subtree;
6753 		int offset2 = offset;
6754 		guint32 i;
6755 
6756 		subtree = proto_tree_add_subtree(
6757 			tree, tvb, offset, 0, ett_PRINTER_DATA_CTR, NULL, "Printer data");
6758 
6759 		for (i=0; i < num_values; i++)
6760 			offset2 = dissect_spoolss_printer_enum_values(
6761 				tvb, offset2, pinfo, subtree, di, drep);
6762 	}
6763 
6764 	offset += size;
6765 
6766 	offset = dissect_ndr_uint32(
6767 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
6768 
6769 	offset = dissect_ndr_uint32(
6770 		tvb, offset, pinfo, tree, di, drep, hf_returned, NULL);
6771 
6772 	offset = dissect_doserror(
6773 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6774 
6775 	return offset;
6776 }
6777 
6778 static int
SpoolssGetPrinterDriverDirectory_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6779 SpoolssGetPrinterDriverDirectory_q(tvbuff_t *tvb, int offset,
6780 				      packet_info *pinfo, proto_tree *tree,
6781 				      dcerpc_info *di, guint8 *drep)
6782 {
6783 	guint32 level;
6784 
6785 	/* Parse packet */
6786 
6787 	offset = dissect_ndr_str_pointer_item(
6788 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
6789 		"Name", hf_servername, 0);
6790 
6791 	offset = dissect_ndr_str_pointer_item(
6792 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
6793 		"Environment", hf_environment, 0);
6794 
6795 	offset = dissect_ndr_uint32(
6796 		tvb, offset, pinfo, tree, di, drep, hf_level, &level);
6797 
6798 	offset = dissect_spoolss_buffer(
6799 		tvb, offset, pinfo, tree, di, drep, NULL);
6800 
6801 	offset = dissect_ndr_uint32(
6802 		tvb, offset, pinfo, tree, di, drep, hf_offered, NULL);
6803 
6804 	return offset;
6805 }
6806 
6807 static int
SpoolssGetPrinterDriverDirectory_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6808 SpoolssGetPrinterDriverDirectory_r(tvbuff_t *tvb, int offset,
6809 				      packet_info *pinfo, proto_tree *tree,
6810 				      dcerpc_info *di, guint8 *drep)
6811 {
6812 	/* Parse packet */
6813 
6814 	offset = dissect_spoolss_string_parm(
6815 		tvb, offset, pinfo, tree, di, drep, "Directory");
6816 
6817 	offset = dissect_ndr_uint32(
6818 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
6819 
6820 	offset = dissect_doserror(
6821 		tvb, offset, pinfo, tree, di, drep, hf_rc, NULL);
6822 
6823 	return offset;
6824 }
6825 
6826 static int
SpoolssGetCorePrinterDrivers_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6827 SpoolssGetCorePrinterDrivers_q(tvbuff_t *tvb, int offset,
6828 			       packet_info *pinfo, proto_tree *tree,
6829 			       dcerpc_info *di, guint8 *drep)
6830 {
6831 	/* Parse packet */
6832 
6833 	offset = dissect_ndr_str_pointer_item(
6834 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
6835 		"Name", hf_servername, 0);
6836 
6837 	offset = dissect_ndr_str_pointer_item(
6838 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_REF,
6839 		"Environment", hf_environment, 0);
6840 
6841 	offset = dissect_ndr_uint32(
6842 		tvb, offset, pinfo, tree, di, drep,
6843 		hf_offered, NULL);
6844 #if 1
6845 	offset = dissect_spoolss_keybuffer(
6846 		tvb, offset, pinfo, tree, di, drep);
6847 #else
6848 	offset = dissect_ndr_uint32(
6849 		tvb, offset, pinfo, tree, di, drep,
6850 		hf_core_driver_size, NULL);
6851 
6852 	offset = dissect_spoolss_uint16uni(
6853 		tvb, offset, pinfo, tree, drep,
6854 		NULL, hf_core_printer_driver_ids);
6855 #endif
6856 	offset = dissect_ndr_uint32(
6857 		tvb, offset, pinfo, tree, di, drep,
6858 		hf_core_printer_driver_count, NULL);
6859 
6860 	return offset;
6861 }
6862 
6863 static int
SpoolssGetCorePrinterDrivers_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6864 SpoolssGetCorePrinterDrivers_r(tvbuff_t *tvb, int offset,
6865 			       packet_info *pinfo, proto_tree *tree,
6866 			       dcerpc_info *di, guint8 *drep)
6867 {
6868 	guint32 num_drivers, i;
6869 
6870 	/* Parse packet */
6871 
6872 	offset = dissect_ndr_uint32(
6873 		tvb, offset, pinfo, tree, di, drep,
6874 		hf_core_printer_driver_count,
6875 		&num_drivers);
6876 
6877 	offset = dissect_ndr_uint32(
6878 		tvb, offset, pinfo, tree, di, drep, hf_core_printer_driver_ids,
6879 		NULL);
6880 
6881 	for (i = 0; i < num_drivers; i++) {
6882 		offset = dissect_CORE_PRINTER_DRIVER(
6883 			tvb, offset, pinfo,
6884 			tree, di, drep);
6885 	}
6886 
6887 	offset = dissect_hresult(
6888 		tvb, offset, pinfo, tree, di, drep, hf_hresult, NULL);
6889 
6890 	return offset;
6891 }
6892 
6893 static int
SpoolssGetPrinterDriverPackagePath_q(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6894 SpoolssGetPrinterDriverPackagePath_q(tvbuff_t *tvb, int offset,
6895 				     packet_info *pinfo, proto_tree *tree,
6896 				     dcerpc_info *di, guint8 *drep)
6897 {
6898 	/* Parse packet */
6899 
6900 	offset = dissect_ndr_str_pointer_item(
6901 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
6902 		"Name", hf_servername, 0);
6903 
6904 	offset = dissect_ndr_str_pointer_item(
6905 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_REF,
6906 		"Environment", hf_environment, 0);
6907 
6908 	offset = dissect_ndr_str_pointer_item(
6909 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_UNIQUE,
6910 		"Language", hf_language, 0);
6911 
6912 	offset = dissect_ndr_str_pointer_item(
6913 		tvb, offset, pinfo, tree, di, drep, NDR_POINTER_REF,
6914 		"PackageId", hf_package_id, 0);
6915 
6916 	offset = dissect_spoolss_buffer(
6917 		tvb, offset, pinfo, tree, di, drep, NULL);
6918 
6919 	offset = dissect_ndr_uint32(
6920 		tvb, offset, pinfo, tree, di, drep,
6921 		hf_driver_package_cab_size, NULL);
6922 
6923 	return offset;
6924 }
6925 
6926 static int
SpoolssGetPrinterDriverPackagePath_r(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)6927 SpoolssGetPrinterDriverPackagePath_r(tvbuff_t *tvb, int offset,
6928 				     packet_info *pinfo, proto_tree *tree,
6929 				     dcerpc_info *di, guint8 *drep)
6930 {
6931 	/* Parse packet */
6932 
6933 	offset = dissect_spoolss_string_parm(
6934 		tvb, offset, pinfo, tree, di, drep, "DriverPackageCab");
6935 
6936 	offset = dissect_ndr_uint32(
6937 		tvb, offset, pinfo, tree, di, drep, hf_needed, NULL);
6938 
6939 	offset = dissect_hresult(
6940 		tvb, offset, pinfo, tree, di, drep, hf_hresult, NULL);
6941 
6942 	return offset;
6943 }
6944 
6945 /*
6946  * List of subdissectors for this pipe.
6947  */
6948 
6949 static dcerpc_sub_dissector dcerpc_spoolss_dissectors[] = {
6950 	{ SPOOLSS_ENUMPRINTERS, "EnumPrinters",
6951 	  SpoolssEnumPrinters_q, SpoolssEnumPrinters_r },
6952 	{ SPOOLSS_OPENPRINTER, "OpenPrinter",
6953 	  NULL, SpoolssGeneric_r },
6954 	{ SPOOLSS_SETJOB, "SetJob",
6955 	  SpoolssSetJob_q, SpoolssSetJob_r },
6956 	{ SPOOLSS_GETJOB, "GetJob",
6957 	  SpoolssGetJob_q, SpoolssGetJob_r },
6958 	{ SPOOLSS_ENUMJOBS, "EnumJobs",
6959 	  SpoolssEnumJobs_q, SpoolssEnumJobs_r },
6960 	{ SPOOLSS_ADDPRINTER, "AddPrinter",
6961 	  NULL, SpoolssGeneric_r },
6962 	{ SPOOLSS_DELETEPRINTER, "DeletePrinter",
6963 	  SpoolssDeletePrinter_q, SpoolssDeletePrinter_r },
6964 	{ SPOOLSS_SETPRINTER, "SetPrinter",
6965 	  SpoolssSetPrinter_q, SpoolssSetPrinter_r },
6966 	{ SPOOLSS_GETPRINTER, "GetPrinter",
6967 	  SpoolssGetPrinter_q, SpoolssGetPrinter_r },
6968 	{ SPOOLSS_ADDPRINTERDRIVER, "AddPrinterDriver",
6969 	  NULL, SpoolssAddPrinterDriver_r },
6970 	{ SPOOLSS_ENUMPRINTERDRIVERS, "EnumPrinterDrivers",
6971 	  SpoolssEnumPrinterDrivers_q, SpoolssEnumPrinterDrivers_r },
6972 	{ SPOOLSS_GETPRINTERDRIVER, "GetPrinterDriver",
6973 	  NULL, SpoolssGeneric_r },
6974 	{ SPOOLSS_GETPRINTERDRIVERDIRECTORY, "GetPrinterDriverDirectory",
6975 	  SpoolssGetPrinterDriverDirectory_q, SpoolssGetPrinterDriverDirectory_r },
6976 	{ SPOOLSS_DELETEPRINTERDRIVER, "DeletePrinterDriver",
6977 	  NULL, SpoolssGeneric_r },
6978 	{ SPOOLSS_ADDPRINTPROCESSOR, "AddPrintProcessor",
6979 	  NULL, SpoolssGeneric_r },
6980 	{ SPOOLSS_ENUMPRINTPROCESSORS, "EnumPrintProcessor",
6981 	  NULL, SpoolssGeneric_r },
6982 	{ SPOOLSS_GETPRINTPROCESSORDIRECTORY, "GetPrintProcessorDirectory",
6983 	  NULL, SpoolssGeneric_r },
6984 	{ SPOOLSS_STARTDOCPRINTER, "StartDocPrinter",
6985 	  SpoolssStartDocPrinter_q, SpoolssStartDocPrinter_r },
6986 	{ SPOOLSS_STARTPAGEPRINTER, "StartPagePrinter",
6987 	  SpoolssStartPagePrinter_q, SpoolssStartPagePrinter_r },
6988 	{ SPOOLSS_WRITEPRINTER, "WritePrinter",
6989 	  SpoolssWritePrinter_q, SpoolssWritePrinter_r },
6990 	{ SPOOLSS_ENDPAGEPRINTER, "EndPagePrinter",
6991 	  SpoolssEndPagePrinter_q, SpoolssEndPagePrinter_r },
6992 	{ SPOOLSS_ABORTPRINTER, "AbortPrinter",
6993 	  NULL, SpoolssGeneric_r },
6994 	{ SPOOLSS_READPRINTER, "ReadPrinter",
6995 	  NULL, SpoolssGeneric_r },
6996 	{ SPOOLSS_ENDDOCPRINTER, "EndDocPrinter",
6997 	  SpoolssEndDocPrinter_q, SpoolssEndDocPrinter_r },
6998 	{ SPOOLSS_ADDJOB, "AddJob",
6999 	  NULL, SpoolssGeneric_r },
7000 	{ SPOOLSS_SCHEDULEJOB, "ScheduleJob",
7001 	  NULL, SpoolssGeneric_r },
7002 	{ SPOOLSS_GETPRINTERDATA, "GetPrinterData",
7003 	  SpoolssGetPrinterData_q, SpoolssGetPrinterData_r },
7004 	{ SPOOLSS_SETPRINTERDATA, "SetPrinterData",
7005 	  SpoolssSetPrinterData_q, SpoolssSetPrinterData_r },
7006 	{ SPOOLSS_WAITFORPRINTERCHANGE, "WaitForPrinterChange",
7007 	  NULL, SpoolssGeneric_r },
7008 	{ SPOOLSS_CLOSEPRINTER, "ClosePrinter",
7009 	  SpoolssClosePrinter_q, SpoolssClosePrinter_r },
7010 	{ SPOOLSS_ADDFORM, "AddForm",
7011 	  SpoolssAddForm_q, SpoolssAddForm_r },
7012 	{ SPOOLSS_DELETEFORM, "DeleteForm",
7013 	  SpoolssDeleteForm_q, SpoolssDeleteForm_r },
7014 	{ SPOOLSS_GETFORM, "GetForm",
7015 	  SpoolssGetForm_q, SpoolssGetForm_r },
7016 	{ SPOOLSS_SETFORM, "SetForm",
7017 	  SpoolssSetForm_q, SpoolssSetForm_r },
7018 	{ SPOOLSS_ENUMFORMS, "EnumForms",
7019 	  SpoolssEnumForms_q, SpoolssEnumForms_r },
7020 	{ SPOOLSS_ENUMPORTS, "EnumPorts",
7021 	  NULL, SpoolssGeneric_r },
7022 	{ SPOOLSS_ENUMMONITORS, "EnumMonitors",
7023 	  NULL, SpoolssGeneric_r },
7024 	{ SPOOLSS_ADDPORT, "AddPort",
7025 	  NULL, SpoolssGeneric_r },
7026 	{ SPOOLSS_CONFIGUREPORT, "ConfigurePort",
7027 	  NULL, SpoolssGeneric_r },
7028 	{ SPOOLSS_DELETEPORT, "DeletePort",
7029 	  NULL, SpoolssGeneric_r },
7030 	{ SPOOLSS_CREATEPRINTERIC, "CreatePrinterIC",
7031 	  NULL, SpoolssGeneric_r },
7032 	{ SPOOLSS_PLAYGDISCRIPTONPRINTERIC, "PlayDiscriptOnPrinterIC",
7033 	  NULL, SpoolssGeneric_r },
7034 	{ SPOOLSS_DELETEPRINTERIC, "DeletePrinterIC",
7035 	  NULL, SpoolssGeneric_r },
7036 	{ SPOOLSS_ADDPRINTERCONNECTION, "AddPrinterConnection",
7037 	  NULL, SpoolssGeneric_r },
7038 	{ SPOOLSS_DELETEPRINTERCONNECTION, "DeletePrinterConnection",
7039 	  NULL, SpoolssGeneric_r },
7040 	{ SPOOLSS_PRINTERMESSAGEBOX, "PrinterMessageBox",
7041 	  NULL, SpoolssGeneric_r },
7042 	{ SPOOLSS_ADDMONITOR, "AddMonitor",
7043 	  NULL, SpoolssGeneric_r },
7044 	{ SPOOLSS_DELETEMONITOR, "DeleteMonitor",
7045 	  NULL, SpoolssGeneric_r },
7046 	{ SPOOLSS_DELETEPRINTPROCESSOR, "DeletePrintProcessor",
7047 	  NULL, SpoolssGeneric_r },
7048 	{ SPOOLSS_ADDPRINTPROVIDER, "AddPrintProvider",
7049 	  NULL, SpoolssGeneric_r },
7050 	{ SPOOLSS_DELETEPRINTPROVIDER, "DeletePrintProvider",
7051 	  NULL, SpoolssGeneric_r },
7052 	{ SPOOLSS_ENUMPRINTPROCDATATYPES, "EnumPrintProcDataTypes",
7053 	  NULL, SpoolssGeneric_r },
7054 	{ SPOOLSS_RESETPRINTER, "ResetPrinter",
7055 	  NULL, SpoolssGeneric_r },
7056 	{ SPOOLSS_GETPRINTERDRIVER2, "GetPrinterDriver2",
7057 	  SpoolssGetPrinterDriver2_q, SpoolssGetPrinterDriver2_r },
7058 	{ SPOOLSS_FINDFIRSTPRINTERCHANGENOTIFICATION,
7059 	  "FindFirstPrinterChangeNotification",
7060 	  NULL, SpoolssGeneric_r },
7061 	{ SPOOLSS_FINDNEXTPRINTERCHANGENOTIFICATION,
7062 	  "FindNextPrinterChangeNotification",
7063 	  NULL, SpoolssGeneric_r },
7064 	{ SPOOLSS_FCPN, "FCPN",
7065 	  SpoolssFCPN_q, SpoolssFCPN_r },
7066 	{ SPOOLSS_ROUTERFINDFIRSTPRINTERNOTIFICATIONOLD,
7067 	  "RouterFindFirstPrinterNotificationOld",
7068 	  NULL, SpoolssGeneric_r },
7069 	{ SPOOLSS_REPLYOPENPRINTER, "ReplyOpenPrinter",
7070 	  SpoolssReplyOpenPrinter_q, SpoolssReplyOpenPrinter_r },
7071 	{ SPOOLSS_ROUTERREPLYPRINTER, "RouterReplyPrinter",
7072 	  SpoolssRouterReplyPrinter_q, SpoolssRouterReplyPrinter_r },
7073 	{ SPOOLSS_REPLYCLOSEPRINTER, "ReplyClosePrinter",
7074 	  SpoolssReplyClosePrinter_q, SpoolssReplyClosePrinter_r },
7075 	{ SPOOLSS_ADDPORTEX, "AddPortEx",
7076 	  NULL, SpoolssGeneric_r },
7077 	{ SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFICATION,
7078 	  "RemoteFindFirstPrinterChangeNotification",
7079 	  NULL, SpoolssGeneric_r },
7080 	{ SPOOLSS_SPOOLERINIT, "SpoolerInit",
7081 	  NULL, SpoolssGeneric_r },
7082 	{ SPOOLSS_RESETPRINTEREX, "ResetPrinterEx",
7083 	  NULL, SpoolssGeneric_r },
7084 	{ SPOOLSS_RFFPCNEX, "RFFPCNEX",
7085 	  SpoolssRFFPCNEX_q, SpoolssRFFPCNEX_r },
7086 	{ SPOOLSS_RRPCN, "RRPCN",
7087 	  SpoolssRRPCN_q, SpoolssRRPCN_r },
7088 	{ SPOOLSS_RFNPCNEX, "RFNPCNEX",
7089 	  SpoolssRFNPCNEX_q, SpoolssRFNPCNEX_r },
7090 	{ SPOOLSS_OPENPRINTEREX, "OpenPrinterEx",
7091 	  SpoolssOpenPrinterEx_q, SpoolssOpenPrinterEx_r },
7092 	{ SPOOLSS_ADDPRINTEREX, "AddPrinterEx",
7093 	  NULL, SpoolssAddPrinterEx_r },
7094 	{ SPOOLSS_ENUMPRINTERDATA, "EnumPrinterData",
7095 	  SpoolssEnumPrinterData_q, SpoolssEnumPrinterData_r },
7096 	{ SPOOLSS_DELETEPRINTERDATA, "DeletePrinterData",
7097 	  SpoolssDeletePrinterData_q, SpoolssDeletePrinterData_r },
7098 	{ SPOOLSS_GETPRINTERDATAEX, "GetPrinterDataEx",
7099 	  SpoolssGetPrinterDataEx_q, SpoolssGetPrinterDataEx_r },
7100 	{ SPOOLSS_SETPRINTERDATAEX, "SetPrinterDataEx",
7101 	  SpoolssSetPrinterDataEx_q, SpoolssSetPrinterDataEx_r },
7102 	{ SPOOLSS_ENUMPRINTERDATAEX, "EnumPrinterDataEx",
7103 	  SpoolssEnumPrinterDataEx_q, SpoolssEnumPrinterDataEx_r },
7104 	{ SPOOLSS_ENUMPRINTERKEY, "EnumPrinterKey",
7105 	  SpoolssEnumPrinterKey_q, SpoolssEnumPrinterKey_r },
7106 	{ SPOOLSS_DELETEPRINTERDATAEX, "DeletePrinterDataEx",
7107 	  NULL, SpoolssGeneric_r },
7108 	{ SPOOLSS_DELETEPRINTERDRIVEREX, "DeletePrinterDriverEx",
7109 	  NULL, SpoolssGeneric_r },
7110 	{ SPOOLSS_ADDPRINTERDRIVEREX, "AddPrinterDriverEx",
7111 	  NULL, SpoolssGeneric_r },
7112 	{ SPOOLSS_GETCOREPRINTERDRIVERS, "GetCorePrinterDrivers",
7113 	  SpoolssGetCorePrinterDrivers_q, SpoolssGetCorePrinterDrivers_r },
7114 	{ SPOOLSS_GETPRINTERDRIVERPACKAGEPATH, "GetPrinterDriverPackagePath",
7115 	  SpoolssGetPrinterDriverPackagePath_q, SpoolssGetPrinterDriverPackagePath_r },
7116 
7117 	{ 0, NULL, NULL, NULL },
7118 };
7119 
7120 /*
7121  * Dissector initialisation function
7122  */
7123 
7124 /* Protocol registration */
7125 
7126 static int proto_dcerpc_spoolss = -1;
7127 static gint ett_dcerpc_spoolss = -1;
7128 
7129 void
proto_register_dcerpc_spoolss(void)7130 proto_register_dcerpc_spoolss(void)
7131 {
7132 	static hf_register_info hf[] = {
7133 
7134 		/* GetPrinterDriver2 */
7135 
7136 		{ &hf_clientmajorversion,
7137 		  { "Client major version", "spoolss.clientmajorversion", FT_UINT32, BASE_DEC,
7138 		    NULL, 0x0, "Client printer driver major version", HFILL }},
7139 		{ &hf_clientminorversion,
7140 		  { "Client minor version", "spoolss.clientminorversion", FT_UINT32, BASE_DEC,
7141 		    NULL, 0x0, "Client printer driver minor version", HFILL }},
7142 		{ &hf_servermajorversion,
7143 		  { "Server major version", "spoolss.servermajorversion", FT_UINT32, BASE_DEC,
7144 		    NULL, 0x0, "Server printer driver major version", HFILL }},
7145 		{ &hf_serverminorversion,
7146 		  { "Server minor version", "spoolss.serverminorversion", FT_UINT32, BASE_DEC,
7147 		    NULL, 0x0, "Server printer driver minor version", HFILL }},
7148 		{ &hf_driverpath,
7149 		  { "Driver path", "spoolss.driverpath", FT_STRING, BASE_NONE,
7150 		    NULL, 0, NULL, HFILL }},
7151 		{ &hf_datafile,
7152 		  { "Data file", "spoolss.datafile", FT_STRING, BASE_NONE,
7153 		    NULL, 0, NULL, HFILL }},
7154 		{ &hf_configfile,
7155 		  { "Config file", "spoolss.configfile", FT_STRING, BASE_NONE,
7156 		    NULL, 0, "Printer name", HFILL }},
7157 		{ &hf_helpfile,
7158 		  { "Help file", "spoolss.helpfile", FT_STRING, BASE_NONE,
7159 		    NULL, 0, NULL, HFILL }},
7160 		{ &hf_monitorname,
7161 		  { "Monitor name", "spoolss.monitorname", FT_STRING, BASE_NONE,
7162 		    NULL, 0, NULL, HFILL }},
7163 		{ &hf_defaultdatatype,
7164 		  { "Default data type", "spoolss.defaultdatatype", FT_STRING, BASE_NONE,
7165 		    NULL, 0, NULL, HFILL }},
7166 		{ &hf_driverinfo_cversion,
7167 		  { "Driver version", "spoolss.drivercversion", FT_UINT32, BASE_DEC,
7168 		    VALS(driverinfo_cversion_vals), 0, "Printer name", HFILL }},
7169 		{ &hf_dependentfiles,
7170 		  { "Dependent files", "spoolss.dependentfiles", FT_STRING, BASE_NONE,
7171 		    NULL, 0, NULL, HFILL }},
7172 
7173 		{ &hf_printer_status,
7174 		  { "Status", "spoolss.printer_status", FT_UINT32, BASE_DEC|BASE_EXT_STRING,
7175 		    &printer_status_vals_ext, 0, NULL, HFILL }},
7176 
7177 		{ &hf_previousdrivernames,
7178 		  { "Previous Driver Names", "spoolss.previousdrivernames", FT_STRING, BASE_NONE,
7179 		    NULL, 0, NULL, HFILL }},
7180 
7181 		{ &hf_color_profiles,
7182 		  { "Color Profiles", "spoolss.colorprofiles", FT_STRING, BASE_NONE,
7183 		    NULL, 0, NULL, HFILL }},
7184 
7185 		{ &hf_core_driver_dependencies,
7186 		  { "Core Driver Dependencies", "spoolss.coredriverdependencies", FT_STRING, BASE_NONE,
7187 		    NULL, 0, NULL, HFILL }},
7188 
7189 		{ &hf_driverdate,
7190 		  { "Driver Date", "spoolss.driverdate", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7191 		    NULL, 0, "Date of driver creation", HFILL }},
7192 
7193 		{ &hf_min_inbox_driverdate,
7194 		  { "Min Inbox Driver Date", "spoolss.mininboxdriverdate", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
7195 		    NULL, 0, "Min Inbox Date of driver creation", HFILL }},
7196 
7197 		{ &hf_padding,
7198 		  { "Padding", "spoolss.padding", FT_UINT32, BASE_HEX,
7199 		    NULL, 0, "Some padding - conveys no semantic information", HFILL }},
7200 
7201 		{ &hf_driver_version,
7202 		  { "Driver Version", "spoolss.driverversion", FT_UINT64, BASE_HEX,
7203 		    NULL, 0, "Driver Version ID", HFILL }},
7204 
7205 		{ &hf_driver_version_low,
7206 		  { "Minor Driver Version", "spoolss.minordriverversion", FT_UINT32, BASE_HEX,
7207 		    NULL, 0, "Driver Version Low", HFILL }},
7208 
7209 		{ &hf_driver_version_high,
7210 		  { "Major Driver Version", "spoolss.majordriverversion", FT_UINT32, BASE_HEX,
7211 		    NULL, 0, "Driver Version High", HFILL }},
7212 
7213 		{ &hf_min_inbox_driver_version_low,
7214 		  { "Min Inbox Minor Driver Version", "spoolss.mininboxminordriverversion", FT_UINT32, BASE_HEX,
7215 		    NULL, 0, "Min Inbox Driver Version Low", HFILL }},
7216 
7217 		{ &hf_min_inbox_driver_version_high,
7218 		  { "Min Inbox Major Driver Version", "spoolss.mininboxmajordriverversion", FT_UINT32, BASE_HEX,
7219 		    NULL, 0, "Min Inbox Driver Version High", HFILL }},
7220 
7221 		{ &hf_mfgname,
7222 		  { "Mfgname", "spoolss.mfgname", FT_STRING, BASE_NONE,
7223 		    NULL, 0, "Manufacturer Name", HFILL }},
7224 
7225 		{ &hf_oemurl,
7226 		  { "OEM URL", "spoolss.oemrul", FT_STRING, BASE_NONE,
7227 		    NULL, 0, "OEM URL - Website of Vendor", HFILL }},
7228 
7229 		{ &hf_hardwareid,
7230 		  { "Hardware ID", "spoolss.hardwareid", FT_STRING, BASE_NONE,
7231 		    NULL, 0, "Hardware Identification Information", HFILL }},
7232 
7233 	   	{ &hf_provider,
7234 	   	  { "Provider", "spoolss.provider", FT_STRING, BASE_NONE,
7235 		    NULL, 0, "Provider of Driver", HFILL }},
7236 
7237 		/* Setprinter RPC */
7238 
7239 		{ &hf_setprinter_cmd,
7240 		  { "Command", "spoolss.setprinter_cmd", FT_UINT32, BASE_DEC,
7241 		   VALS(setprinter_cmd_vals), 0, NULL, HFILL }},
7242 
7243 		/* Enumprinters */
7244 
7245 		{ &hf_enumprinters_flags,
7246 		  { "Flags", "spoolss.enumprinters.flags",
7247 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
7248 
7249 		{ &hf_enumprinters_flags_local,
7250 		  { "Enum local", "spoolss.enumprinters.flags.enum_local",
7251 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7252 		    PRINTER_ENUM_LOCAL, NULL, HFILL }},
7253 
7254 		{ &hf_enumprinters_flags_name,
7255 		  { "Enum name", "spoolss.enumprinters.flags.enum_name",
7256 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7257 		    PRINTER_ENUM_NAME, NULL, HFILL }},
7258 
7259 		{ &hf_enumprinters_flags_shared,
7260 		  { "Enum shared", "spoolss.enumprinters.flags.enum_shared",
7261 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7262 		    PRINTER_ENUM_SHARED, NULL, HFILL }},
7263 
7264 		{ &hf_enumprinters_flags_default,
7265 		  { "Enum default", "spoolss.enumprinters.flags.enum_default",
7266 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7267 		    PRINTER_ENUM_DEFAULT, NULL, HFILL }},
7268 
7269 		{ &hf_enumprinters_flags_connections,
7270 		  { "Enum connections", "spoolss.enumprinters.flags.enum_connections",
7271 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7272 		    PRINTER_ENUM_CONNECTIONS, NULL, HFILL }},
7273 
7274 		{ &hf_enumprinters_flags_network,
7275 		  { "Enum network", "spoolss.enumprinters.flags.enum_network",
7276 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7277 		    PRINTER_ENUM_NETWORK, NULL, HFILL }},
7278 
7279 		{ &hf_enumprinters_flags_remote,
7280 		  { "Enum remote", "spoolss.enumprinters.flags.enum_remote",
7281 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7282 		    PRINTER_ENUM_REMOTE, NULL, HFILL }},
7283 
7284 		/* GetPrinter */
7285 
7286 		{ &hf_start_time,
7287 		  { "Start time", "spoolss.start_time",
7288 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7289 
7290 		{ &hf_end_time,
7291 		  { "End time", "spoolss.end_time",
7292 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7293 
7294 		{ &hf_elapsed_time,
7295 		  { "Elapsed time", "spoolss.elapsed_time",
7296 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7297 
7298 		{ &hf_device_not_selected_timeout,
7299 		  { "Device Not Selected Timeout", "spoolss.device_not_selected_timeout",
7300 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7301 
7302 		{ &hf_transmission_retry_timeout,
7303 		  { "Transmission Retry Timeout", "spoolss.transmission_retry_timeout",
7304 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7305 
7306 		/*
7307 		 * New hf index values
7308 		 */
7309 
7310 		{ &hf_opnum,
7311 		  { "Operation", "spoolss.opnum", FT_UINT16, BASE_DEC,
7312 		    NULL, 0x0, NULL, HFILL }},
7313 
7314 		{ &hf_hnd,
7315 		  { "Context handle", "spoolss.hnd", FT_BYTES, BASE_NONE,
7316 		    NULL, 0x0, "SPOOLSS policy handle", HFILL }},
7317 
7318 		{ &hf_rc,
7319 		  { "Return code", "spoolss.rc", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
7320 		    &DOS_errors_ext, 0x0, "SPOOLSS return code", HFILL }},
7321 
7322 		{ &hf_hresult,
7323 		  { "HRESULT return code", "spoolss.hresult", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
7324 		    &HRES_errors_ext, 0x0, "SPOOLSS HRESULT return code", HFILL }},
7325 
7326 		{ &hf_offered,
7327 		  { "Offered", "spoolss.offered", FT_UINT32, BASE_DEC,
7328 		    NULL, 0x0, "Size of buffer offered in this request",
7329 		    HFILL }},
7330 
7331 		{ &hf_needed,
7332 		  { "Needed", "spoolss.needed", FT_UINT32, BASE_DEC,
7333 		    NULL, 0x0, "Size of buffer required for request", HFILL }},
7334 
7335 		{ &hf_returned,
7336 		  { "Returned", "spoolss.returned", FT_UINT32, BASE_DEC,
7337 		    NULL, 0x0, "Number of items returned", HFILL }},
7338 
7339 		{ &hf_buffer_size,
7340 		  { "Buffer size", "spoolss.buffer.size", FT_UINT32, BASE_DEC,
7341 		    NULL, 0x0, "Size of buffer", HFILL }},
7342 
7343 		{ &hf_buffer_data,
7344 		  { "Buffer data", "spoolss.buffer.data", FT_BYTES, BASE_NONE,
7345 		    NULL, 0x0, "Contents of buffer", HFILL }},
7346 
7347 		{ &hf_string_parm_size,
7348 		  { "String buffer size", "spoolss.string.buffersize", FT_UINT32, BASE_DEC,
7349 		    NULL, 0x0, "Size of string buffer", HFILL }},
7350 
7351 		{ &hf_string_parm_data,
7352 		  { "String data", "spoolss.string.data", FT_STRINGZ, BASE_NONE,
7353 		    NULL, 0x0, "Contents of string", HFILL }},
7354 
7355 		{ &hf_offset,
7356 		  { "Offset", "spoolss.offset", FT_UINT32, BASE_DEC,
7357 		    NULL, 0x0, "Offset of data", HFILL }},
7358 
7359 		{ &hf_level,
7360 		  { "Info level", "spoolss.enumjobs.level", FT_UINT32,
7361 		    BASE_DEC, NULL, 0x0, NULL, HFILL }},
7362 
7363 
7364 		{ &hf_printername,
7365 		  { "Printer name", "spoolss.printername", FT_STRING,
7366 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7367 
7368 		{ &hf_machinename,
7369 		  { "Machine name", "spoolss.machinename", FT_STRING,
7370 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7371 
7372 		{ &hf_notifyname,
7373 		  { "Notify name", "spoolss.notifyname", FT_STRING,
7374 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7375 
7376 		{ &hf_printerdesc,
7377 		  { "Printer description", "spoolss.printerdesc", FT_STRING,
7378 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7379 
7380 		{ &hf_printercomment,
7381 		  { "Printer comment", "spoolss.printercomment", FT_STRING,
7382 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7383 
7384 		{ &hf_servername,
7385 		  { "Server name", "spoolss.servername", FT_STRING, BASE_NONE,
7386 		    NULL, 0, NULL, HFILL }},
7387 
7388 		{ &hf_sharename,
7389 		  { "Share name", "spoolss.sharename", FT_STRING, BASE_NONE,
7390 		    NULL, 0, NULL, HFILL }},
7391 
7392 		{ &hf_portname,
7393 		  { "Port name", "spoolss.portname", FT_STRING, BASE_NONE,
7394 		    NULL, 0, NULL, HFILL }},
7395 
7396 		{ &hf_printerlocation,
7397 		  { "Printer location", "spoolss.printerlocation", FT_STRING,
7398 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7399 
7400 		{ &hf_environment,
7401 		  { "Environment name", "spoolss.environment", FT_STRING,
7402 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7403 
7404 		{ &hf_drivername,
7405 		  { "Driver name", "spoolss.drivername", FT_STRING, BASE_NONE,
7406 		    NULL, 0, NULL, HFILL }},
7407 
7408 		{ &hf_username,
7409 		  { "User name", "spoolss.username", FT_STRING, BASE_NONE,
7410 		    NULL, 0, NULL, HFILL }},
7411 
7412 		{ &hf_documentname,
7413 		  { "Document name", "spoolss.document", FT_STRING, BASE_NONE,
7414 		    NULL, 0, NULL, HFILL }},
7415 
7416 		{ &hf_outputfile,
7417 		  { "Output file", "spoolss.outputfile", FT_STRING, BASE_NONE,
7418 		    NULL, 0, NULL, HFILL }},
7419 
7420 		{ &hf_datatype,
7421 		  { "Datatype", "spoolss.datatype", FT_STRING, BASE_NONE,
7422 		    NULL, 0, NULL, HFILL }},
7423 
7424 		{ &hf_textstatus,
7425 		  { "Text status", "spoolss.textstatus", FT_STRING, BASE_NONE,
7426 		    NULL, 0, NULL, HFILL }},
7427 
7428  		{ &hf_sepfile,
7429 		  { "Separator file", "spoolss.setpfile", FT_STRING, BASE_NONE,
7430 		    NULL, 0, NULL, HFILL }},
7431 
7432  		{ &hf_parameters,
7433 		  { "Parameters", "spoolss.parameters", FT_STRING, BASE_NONE,
7434 		    NULL, 0, NULL, HFILL }},
7435 
7436 		{ &hf_printprocessor,
7437 		  { "Print processor", "spoolss.printprocessor", FT_STRING,
7438 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7439 
7440 		{ &hf_vendor_setup,
7441 		  { "Vendor Setup", "spoolss.vendorsetup", FT_STRING,
7442 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7443 
7444 		{ &hf_inf_path,
7445 		  { "Inf Path", "spoolss.infpath", FT_STRING,
7446 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7447 
7448 		{ &hf_core_printer_driver_ids,
7449 		  { "Core Printer Driver IDs", "spoolss.core_printer_driver_ids", FT_STRING,
7450 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7451 
7452 		{ &hf_core_driver_guid,
7453 		  { "Core Printer Driver GUID", "spoolss.core_driver_guid", FT_GUID,
7454 		    BASE_NONE, NULL, 0,	NULL, HFILL }},
7455 
7456 		{ &hf_core_driver_size,
7457 		  { "Core Printer Driver Size", "spoolss.core_driver_size", FT_UINT32,
7458 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7459 
7460 		{ &hf_core_printer_driver_count,
7461 		  { "Core Printer Driver Count", "spoolss.core_printer_driver_count", FT_UINT32,
7462 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7463 
7464 		{ &hf_package_id,
7465 		  { "PackageId", "spoolss.package_id", FT_STRING,
7466 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7467 
7468 		{ &hf_language,
7469 		  { "Language name", "spoolss.language", FT_STRING,
7470 		    BASE_NONE, NULL, 0, NULL, HFILL }},
7471 
7472 		{ &hf_driver_package_cab_size,
7473 		  { "Driver Package Cabinet Size", "spoolss.driver_package_cab_size", FT_UINT32,
7474 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7475 
7476 		/* Printer data */
7477 
7478 		{ &hf_printerdata,
7479 		  { "Data", "spoolss.printerdata", FT_UINT32,
7480 		    BASE_HEX, NULL, 0, NULL, HFILL }},
7481 
7482 		{ &hf_printerdata_key,
7483 		  { "Key", "spoolss.printerdata.key", FT_STRING,
7484 		    BASE_NONE, NULL, 0, "Printer data key", HFILL }},
7485 
7486 		{ &hf_printerdata_value,
7487 		  { "Value", "spoolss.printerdata.value",
7488 		    FT_STRING, BASE_NONE, NULL, 0, "Printer data value",
7489 		    HFILL }},
7490 
7491 		{ &hf_printerdata_type,
7492 		  { "Type", "spoolss.printerdata.type",
7493 		    FT_UINT32, BASE_DEC|BASE_EXT_STRING, &reg_datatypes_ext, 0,
7494 		    "Printer data type", HFILL }},
7495 
7496 		{ &hf_printerdata_size,
7497 		  { "Size", "spoolss.printerdata.size",
7498 		    FT_UINT32, BASE_DEC, NULL, 0, "Printer data size",
7499 		    HFILL }},
7500 
7501 		{ &hf_printerdata_data,
7502 		  { "Data", "spoolss.printerdata.data", FT_BYTES, BASE_NONE,
7503 		    NULL, 0x0, "Printer data", HFILL }},
7504 
7505 		{ &hf_printerdata_data_dword,
7506 		  { "DWORD data", "spoolss.printerdata.data.dword",
7507 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
7508 
7509 		{ &hf_printerdata_data_sz,
7510 		  { "String data", "spoolss.printerdata.data.sz",
7511 		    FT_STRING, BASE_NONE, NULL, 0, NULL,
7512 		    HFILL }},
7513 
7514 		/* Devicemode */
7515 
7516 		{ &hf_devmodectr_size,
7517 		  { "Devicemode ctr size", "spoolss.devicemodectr.size",
7518 		    FT_UINT32, BASE_DEC, NULL, 0, NULL,
7519 		    HFILL }},
7520 
7521 		{ &hf_devmode,
7522 		  { "Devicemode", "spoolss.devmode", FT_UINT32,
7523 		    BASE_HEX, NULL, 0, NULL, HFILL }},
7524 
7525 		{ &hf_devmode_size,
7526 		  { "Size", "spoolss.devmode.size",
7527 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7528 
7529 		{ &hf_devmode_spec_version,
7530 		  { "Spec version", "spoolss.devmode.spec_version",
7531 		    FT_UINT16, BASE_DEC, VALS(devmode_specversion_vals),
7532 		    0, NULL, HFILL }},
7533 
7534 		{ &hf_devmode_driver_version,
7535 		  { "Driver version", "spoolss.devmode.driver_version",
7536 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7537 
7538 		{ &hf_devmode_size2,
7539 		  { "Size2", "spoolss.devmode.size2",
7540 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7541 
7542 		{ &hf_devmode_fields,
7543 		  { "Fields", "spoolss.devmode.fields",
7544 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
7545 
7546 		{ &hf_devmode_orientation,
7547 		  { "Orientation", "spoolss.devmode.orientation",
7548 		    FT_UINT16, BASE_DEC, VALS(devmode_orientation_vals),
7549 		    0, NULL, HFILL }},
7550 
7551 		{ &hf_devmode_paper_size,
7552 		  { "Paper size", "spoolss.devmode.paper_size",
7553 		    FT_UINT16, BASE_DEC|BASE_EXT_STRING, &devmode_papersize_vals_ext,
7554 		    0, NULL, HFILL }},
7555 
7556 		{ &hf_devmode_paper_width,
7557 		  { "Paper width", "spoolss.devmode.paper_width",
7558 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7559 
7560 		{ &hf_devmode_paper_length,
7561 		  { "Paper length", "spoolss.devmode.paper_length",
7562 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7563 
7564 		{ &hf_devmode_scale,
7565 		  { "Scale", "spoolss.devmode.scale",
7566 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7567 
7568 		{ &hf_devmode_copies,
7569 		  { "Copies", "spoolss.devmode.copies",
7570 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7571 
7572 		{ &hf_devmode_default_source,
7573 		  { "Default source", "spoolss.devmode.default_source",
7574 		    FT_UINT16, BASE_DEC|BASE_EXT_STRING, &devmode_papersource_vals_ext,
7575 		    0, NULL, HFILL }},
7576 
7577 		{ &hf_devmode_print_quality,
7578 		  { "Print quality", "spoolss.devmode.print_quality",
7579 		    FT_UINT16, BASE_DEC, VALS(devmode_printquality_vals),
7580 		    0, NULL, HFILL }},
7581 
7582 		{ &hf_devmode_color,
7583 		  { "Color", "spoolss.devmode.color",
7584 		    FT_UINT16, BASE_DEC, VALS(devmode_colour_vals), 0,
7585 		    NULL, HFILL }},
7586 
7587 		{ &hf_devmode_duplex,
7588 		  { "Duplex", "spoolss.devmode.duplex",
7589 		    FT_UINT16, BASE_DEC, VALS(devmode_duplex_vals), 0,
7590 		    NULL, HFILL }},
7591 
7592 		{ &hf_devmode_y_resolution,
7593 		  { "Y resolution", "spoolss.devmode.y_resolution",
7594 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7595 
7596 		{ &hf_devmode_tt_option,
7597 		  { "TT option", "spoolss.devmode.tt_option",
7598 		    FT_UINT16, BASE_DEC, VALS(devmode_ttoption_vals), 0,
7599 		    NULL, HFILL }},
7600 
7601 		{ &hf_devmode_collate,
7602 		  { "Collate", "spoolss.devmode.collate",
7603 		    FT_UINT16, BASE_DEC, VALS(devmode_collate_vals), 0,
7604 		    NULL, HFILL }},
7605 
7606 		{ &hf_devmode_log_pixels,
7607 		  { "Log pixels", "spoolss.devmode.log_pixels",
7608 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
7609 
7610 		{ &hf_devmode_bits_per_pel,
7611 		  { "Bits per pel", "spoolss.devmode.bits_per_pel",
7612 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7613 
7614 		{ &hf_devmode_pels_width,
7615 		  { "Pels width", "spoolss.devmode.pels_width",
7616 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7617 
7618 		{ &hf_devmode_pels_height,
7619 		  { "Pels height", "spoolss.devmode.pels_height",
7620 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7621 
7622 		{ &hf_devmode_display_flags,
7623 		  { "Display flags", "spoolss.devmode.display_flags",
7624 		    FT_UINT32, BASE_DEC, VALS(devmode_displayflags_vals), 0,
7625 		    NULL, HFILL }},
7626 
7627 		{ &hf_devmode_display_freq,
7628 		  { "Display frequency", "spoolss.devmode.display_freq",
7629 		    FT_UINT32, BASE_DEC, NULL, 0, NULL,
7630 		    HFILL }},
7631 
7632 		{ &hf_devmode_icm_method,
7633 		  { "ICM method", "spoolss.devmode.icm_method",
7634 		    FT_UINT32, BASE_DEC, VALS(devmode_icmmethod_vals), 0,
7635 		    NULL, HFILL }},
7636 
7637 		{ &hf_devmode_icm_intent,
7638 		  { "ICM intent", "spoolss.devmode.icm_intent",
7639 		    FT_UINT32, BASE_DEC, VALS(devmode_icmintent_vals), 0,
7640 		    NULL, HFILL }},
7641 
7642 		{ &hf_devmode_media_type,
7643 		  { "Media type", "spoolss.devmode.media_type",
7644 		    FT_UINT32, BASE_DEC, VALS(devmode_mediatype_vals), 0,
7645 		    NULL, HFILL }},
7646 
7647 		{ &hf_devmode_dither_type,
7648 		  { "Dither type", "spoolss.devmode.dither_type",
7649 		    FT_UINT32, BASE_DEC, VALS(devmode_dithertype_vals), 0,
7650 		    NULL, HFILL }},
7651 
7652 		{ &hf_devmode_reserved1,
7653 		  { "Reserved1", "spoolss.devmode.reserved1",
7654 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7655 
7656 		{ &hf_devmode_reserved2,
7657 		  { "Reserved2", "spoolss.devmode.reserved2",
7658 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7659 
7660 		{ &hf_devmode_panning_width,
7661 		  { "Panning width", "spoolss.devmode.panning_width",
7662 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7663 
7664 		{ &hf_devmode_panning_height,
7665 		  { "Panning height", "spoolss.devmode.panning_height",
7666 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
7667 
7668 		{ &hf_devmode_driver_extra_len,
7669 		  { "Driver extra length",
7670 		    "spoolss.devmode.driver_extra_len",
7671 		    FT_UINT32, BASE_DEC, NULL, 0, NULL,
7672 		    HFILL }},
7673 
7674 		{ &hf_devmode_driver_extra,
7675 		  { "Driver extra", "spoolss.devmode.driver_extra",
7676 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
7677 
7678 		/* Devicemode fields */
7679 
7680 		{ &hf_devmode_fields_orientation,
7681 		  { "Orientation", "spoolss.devmode.fields.orientation",
7682 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7683 		    DEVMODE_ORIENTATION, NULL, HFILL }},
7684 
7685 		{ &hf_devmode_fields_papersize,
7686 		  { "Paper size", "spoolss.devmode.fields.paper_size",
7687 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7688 		    DEVMODE_PAPERSIZE, NULL, HFILL }},
7689 
7690 		{ &hf_devmode_fields_paperlength,
7691 		  { "Paper length", "spoolss.devmode.fields.paper_length",
7692 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7693 		    DEVMODE_PAPERLENGTH, NULL, HFILL }},
7694 
7695 		{ &hf_devmode_fields_paperwidth,
7696 		  { "Paper width", "spoolss.devmode.fields.paper_width",
7697 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7698 		    DEVMODE_PAPERWIDTH, NULL, HFILL }},
7699 
7700 		{ &hf_devmode_fields_scale,
7701 		  { "Scale", "spoolss.devmode.fields.scale",
7702 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7703 		    DEVMODE_SCALE, NULL, HFILL }},
7704 
7705 		{ &hf_devmode_fields_position,
7706 		  { "Position", "spoolss.devmode.fields.position",
7707 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7708 		    DEVMODE_POSITION, NULL, HFILL }},
7709 
7710 		{ &hf_devmode_fields_nup,
7711 		  { "N-up", "spoolss.devmode.fields.nup",
7712 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7713 		    DEVMODE_NUP, NULL, HFILL }},
7714 
7715 		{ &hf_devmode_fields_copies,
7716 		  { "Copies", "spoolss.devmode.fields.copies",
7717 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7718 		    DEVMODE_COPIES, NULL, HFILL }},
7719 
7720 		{ &hf_devmode_fields_defaultsource,
7721 		  { "Default source", "spoolss.devmode.fields.default_source",
7722 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7723 		    DEVMODE_DEFAULTSOURCE, NULL, HFILL }},
7724 
7725 		{ &hf_devmode_fields_printquality,
7726 		  { "Print quality", "spoolss.devmode.fields.print_quality",
7727 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7728 		    DEVMODE_PRINTQUALITY, NULL, HFILL }},
7729 
7730 		{ &hf_devmode_fields_color,
7731 		  { "Color", "spoolss.devmode.fields.color",
7732 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7733 		    DEVMODE_COLOR, NULL, HFILL }},
7734 
7735 		{ &hf_devmode_fields_duplex,
7736 		  { "Duplex", "spoolss.devmode.fields.duplex",
7737 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7738 		    DEVMODE_DUPLEX, NULL, HFILL }},
7739 
7740 		{ &hf_devmode_fields_yresolution,
7741 		  { "Y resolution", "spoolss.devmode.fields.y_resolution",
7742 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7743 		    DEVMODE_YRESOLUTION, NULL, HFILL }},
7744 
7745 		{ &hf_devmode_fields_ttoption,
7746 		  { "TT option", "spoolss.devmode.fields.tt_option",
7747 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7748 		    DEVMODE_TTOPTION, NULL, HFILL }},
7749 
7750 		{ &hf_devmode_fields_collate,
7751 		  { "Collate", "spoolss.devmode.fields.collate",
7752 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7753 		    DEVMODE_COLLATE, NULL, HFILL }},
7754 
7755 		{ &hf_devmode_fields_formname,
7756 		  { "Form name", "spoolss.devmode.fields.form_name",
7757 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7758 		    DEVMODE_FORMNAME, NULL, HFILL }},
7759 
7760 		{ &hf_devmode_fields_logpixels,
7761 		  { "Log pixels", "spoolss.devmode.fields.log_pixels",
7762 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7763 		    DEVMODE_LOGPIXELS, NULL, HFILL }},
7764 
7765 		{ &hf_devmode_fields_bitsperpel,
7766 		  { "Bits per pel", "spoolss.devmode.fields.bits_per_pel",
7767 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7768 		    DEVMODE_BITSPERPEL, NULL, HFILL }},
7769 
7770 		{ &hf_devmode_fields_pelswidth,
7771 		  { "Pels width", "spoolss.devmode.fields.pels_width",
7772 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7773 		    DEVMODE_PELSWIDTH, NULL, HFILL }},
7774 
7775 		{ &hf_devmode_fields_pelsheight,
7776 		  { "Pels height", "spoolss.devmode.fields.pels_height",
7777 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7778 		    DEVMODE_PELSHEIGHT, NULL, HFILL }},
7779 
7780 		{ &hf_devmode_fields_displayflags,
7781 		  { "Display flags", "spoolss.devmode.fields.display_flags",
7782 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7783 		    DEVMODE_DISPLAYFLAGS, NULL, HFILL }},
7784 
7785 		{ &hf_devmode_fields_displayfrequency,
7786 		  { "Display frequency",
7787 		    "spoolss.devmode.fields.display_frequency",
7788 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7789 		    DEVMODE_DISPLAYFREQUENCY, NULL, HFILL }},
7790 
7791 		{ &hf_devmode_fields_icmmethod,
7792 		  { "ICM method", "spoolss.devmode.fields.icm_method",
7793 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7794 		    DEVMODE_ICMMETHOD, NULL, HFILL }},
7795 
7796 		{ &hf_devmode_fields_icmintent,
7797 		  { "ICM intent", "spoolss.devmode.fields.icm_intent",
7798 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7799 		    DEVMODE_ICMINTENT, NULL, HFILL }},
7800 
7801 		{ &hf_devmode_fields_mediatype,
7802 		  { "Media type", "spoolss.devmode.fields.media_type",
7803 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7804 		    DEVMODE_MEDIATYPE, NULL, HFILL }},
7805 
7806 		{ &hf_devmode_fields_dithertype,
7807 		  { "Dither type", "spoolss.devmode.fields.dither_type",
7808 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7809 		    DEVMODE_DITHERTYPE, NULL, HFILL }},
7810 
7811 		{ &hf_devmode_fields_panningwidth,
7812 		  { "Panning width", "spoolss.devmode.fields.panning_width",
7813 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7814 		    DEVMODE_PANNINGWIDTH, NULL, HFILL }},
7815 
7816 		{ &hf_devmode_fields_panningheight,
7817 		  { "Panning height", "spoolss.devmode.fields.panning_height",
7818 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
7819 		    DEVMODE_PANNINGHEIGHT, NULL, HFILL }},
7820 
7821 		/* EnumPrinterData RPC */
7822 
7823 		{ &hf_enumprinterdata_enumindex,
7824 		  { "Enum index", "spoolss.enumprinterdata.enumindex",
7825 		    FT_UINT32, BASE_DEC, NULL, 0x0,
7826 		    "Index for start of enumeration", HFILL }},
7827 
7828 		{ &hf_enumprinterdata_value_offered,
7829 		  { "Value size offered",
7830 		    "spoolss.enumprinterdata.value_offered", FT_UINT32,
7831 		    BASE_DEC, NULL, 0x0,
7832 		    "Buffer size offered for printerdata value", HFILL }},
7833 
7834 		{ &hf_enumprinterdata_data_offered,
7835 		  { "Data size offered",
7836 		    "spoolss.enumprinterdata.data_offered", FT_UINT32,
7837 		    BASE_DEC, NULL, 0x0,
7838 		    "Buffer size offered for printerdata data", HFILL }},
7839 
7840 		{ &hf_enumprinterdata_value_len,
7841 		  { "Value length",
7842 		    "spoolss.enumprinterdata.value_len", FT_UINT32,
7843 		    BASE_DEC, NULL, 0x0,
7844 		    "Size of printerdata value", HFILL }},
7845 
7846 		{ &hf_enumprinterdata_value_needed,
7847 		  { "Value size needed",
7848 		    "spoolss.enumprinterdata.value_needed", FT_UINT32,
7849 		    BASE_DEC, NULL, 0x0,
7850 		    "Buffer size needed for printerdata value", HFILL }},
7851 
7852 		{ &hf_enumprinterdata_data_needed,
7853 		  { "Data size needed",
7854 		    "spoolss.enumprinterdata.data_needed", FT_UINT32, BASE_DEC,
7855 		    NULL, 0x0, "Buffer size needed for printerdata data",
7856 		    HFILL }},
7857 
7858 		/* Print jobs */
7859 
7860 		{ &hf_job_id,
7861 		  { "Job ID", "spoolss.job.id", FT_UINT32, BASE_DEC,
7862 		    NULL, 0x0, "Job identification number", HFILL }},
7863 
7864 		{ &hf_job_status,
7865 		  { "Job status", "spoolss.job.status", FT_UINT32, BASE_DEC,
7866 		    NULL, 0x0, NULL, HFILL }},
7867 
7868 		{ &hf_job_status_paused,
7869 		  { "Paused", "spoolss.job.status.paused", FT_BOOLEAN, 32,
7870 		    TFS(&tfs_job_status_paused), JOB_STATUS_PAUSED,
7871 		    NULL, HFILL }},
7872 
7873 		{ &hf_job_status_error,
7874 		  { "Error", "spoolss.job.status.error", FT_BOOLEAN, 32,
7875 		    TFS(&tfs_job_status_error), JOB_STATUS_ERROR,
7876 		    NULL, HFILL }},
7877 
7878 		{ &hf_job_status_deleting,
7879 		  { "Deleting", "spoolss.job.status.deleting", FT_BOOLEAN, 32,
7880 		    TFS(&tfs_job_status_deleting), JOB_STATUS_DELETING,
7881 		    NULL, HFILL }},
7882 
7883 		{ &hf_job_status_spooling,
7884 		  { "Spooling", "spoolss.job.status.spooling", FT_BOOLEAN, 32,
7885 		    TFS(&tfs_job_status_spooling), JOB_STATUS_SPOOLING,
7886 		    NULL, HFILL }},
7887 
7888 		{ &hf_job_status_printing,
7889 		  { "Printing", "spoolss.job.status.printing", FT_BOOLEAN, 32,
7890 		    TFS(&tfs_job_status_printing), JOB_STATUS_PRINTING,
7891 		    NULL, HFILL }},
7892 
7893 		{ &hf_job_status_offline,
7894 		  { "Offline", "spoolss.job.status.offline", FT_BOOLEAN, 32,
7895 		    TFS(&tfs_job_status_offline), JOB_STATUS_OFFLINE,
7896 		    NULL, HFILL }},
7897 
7898 		{ &hf_job_status_paperout,
7899 		  { "Paperout", "spoolss.job.status.paperout", FT_BOOLEAN, 32,
7900 		    TFS(&tfs_job_status_paperout), JOB_STATUS_PAPEROUT,
7901 		    NULL, HFILL }},
7902 
7903 		{ &hf_job_status_printed,
7904 		  { "Printed", "spoolss.job.status.printed", FT_BOOLEAN, 32,
7905 		    TFS(&tfs_job_status_printed), JOB_STATUS_PRINTED,
7906 		    NULL, HFILL }},
7907 
7908 		{ &hf_job_status_deleted,
7909 		  { "Deleted", "spoolss.job.status.deleted", FT_BOOLEAN, 32,
7910 		    TFS(&tfs_job_status_deleted), JOB_STATUS_DELETED,
7911 		    NULL, HFILL }},
7912 
7913 		{ &hf_job_status_blocked,
7914 		  { "Blocked", "spoolss.job.status.blocked", FT_BOOLEAN, 32,
7915 		    TFS(&tfs_job_status_blocked), JOB_STATUS_BLOCKED,
7916 		    NULL, HFILL }},
7917 
7918 		{ &hf_job_status_user_intervention,
7919 		  { "User intervention",
7920 		    "spoolss.job.status.user_intervention", FT_BOOLEAN, 32,
7921 		    TFS(&tfs_job_status_user_intervention),
7922 		    JOB_STATUS_USER_INTERVENTION, NULL,
7923 		    HFILL }},
7924 
7925 		{ &hf_job_priority,
7926 		  { "Job priority", "spoolss.job.priority", FT_UINT32,
7927 		    BASE_DEC, NULL, 0x0, NULL, HFILL }},
7928 
7929 		{ &hf_job_position,
7930 		  { "Job position", "spoolss.job.position", FT_UINT32,
7931 		    BASE_DEC, NULL, 0x0, NULL, HFILL }},
7932 
7933 		{ &hf_job_totalpages,
7934 		  { "Job total pages", "spoolss.job.totalpages", FT_UINT32,
7935 		    BASE_DEC, NULL, 0x0, NULL, HFILL }},
7936 
7937 		{ &hf_job_totalbytes,
7938 		  { "Job total bytes", "spoolss.job.totalbytes", FT_UINT32,
7939 		    BASE_DEC, NULL, 0x0, NULL, HFILL }},
7940 
7941 		{ &hf_job_bytesprinted,
7942 		  { "Job bytes printed", "spoolss.job.bytesprinted",
7943 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL,
7944 		    HFILL }},
7945 
7946 		{ &hf_job_pagesprinted,
7947 		  { "Job pages printed", "spoolss.job.pagesprinted",
7948 		    FT_UINT32, BASE_DEC, NULL, 0x0, NULL,
7949 		    HFILL }},
7950 
7951 		{ &hf_job_size,
7952 		  { "Job size", "spoolss.job.size", FT_UINT32, BASE_DEC,
7953 		    NULL, 0x0, NULL, HFILL }},
7954 
7955 		/* Forms */
7956 
7957 		{ &hf_form,
7958 		  { "Data", "spoolss.form", FT_UINT32,
7959 		    BASE_HEX, NULL, 0, NULL, HFILL }},
7960 
7961 		{ &hf_form_level,
7962 		  { "Level", "spoolss.form.level", FT_UINT32,
7963 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7964 
7965 		{ &hf_form_name,
7966 		  { "Name", "spoolss.form.name", FT_STRING, BASE_NONE,
7967 		    NULL, 0, NULL, HFILL }},
7968 
7969 		{ &hf_form_flags,
7970 		  { "Flags", "spoolss.form.flags", FT_UINT32,
7971 		    BASE_DEC, VALS(form_type_vals), 0, NULL, HFILL }},
7972 
7973 		{ &hf_form_unknown,
7974 		  { "Unknown", "spoolss.form.unknown", FT_UINT32,
7975 		    BASE_HEX, NULL, 0, NULL, HFILL }},
7976 
7977 		{ &hf_form_width,
7978 		  { "Width", "spoolss.form.width", FT_UINT32,
7979 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7980 
7981 		{ &hf_form_height,
7982 		  { "Height", "spoolss.form.height", FT_UINT32,
7983 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7984 
7985 		{ &hf_form_left_margin,
7986 		  { "Left margin", "spoolss.form.left", FT_UINT32,
7987 		    BASE_DEC, NULL, 0, "Left", HFILL }},
7988 
7989 		{ &hf_form_top_margin,
7990 		  { "Top", "spoolss.form.top", FT_UINT32,
7991 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7992 
7993 		{ &hf_form_horiz_len,
7994 		  { "Horizontal", "spoolss.form.horiz", FT_UINT32,
7995 		    BASE_DEC, NULL, 0, NULL, HFILL }},
7996 
7997 		{ &hf_form_vert_len,
7998 		  { "Vertical", "spoolss.form.vert", FT_UINT32,
7999 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8000 
8001 		{ &hf_enumforms_num,
8002 		  { "Num", "spoolss.enumforms.num", FT_UINT32,
8003 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8004 
8005 		/* Print notify */
8006 
8007 		{ &hf_notify_options_version,
8008 		  { "Version", "spoolss.notify_options.version", FT_UINT32,
8009 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8010 
8011 		{ &hf_notify_options_flags,
8012 		  { "Flags", "spoolss.notify_options.flags", FT_UINT32,
8013 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8014 
8015 		{ &hf_notify_options_count,
8016 		  { "Count", "spoolss.notify_options.count", FT_UINT32,
8017 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8018 
8019 		{ &hf_notify_option_type,
8020 		  { "Type", "spoolss.notify_option.type", FT_UINT16, BASE_DEC,
8021 		    VALS(printer_notify_types), 0, NULL, HFILL }},
8022 
8023 		{ &hf_notify_option_reserved1,
8024 		  { "Reserved1", "spoolss.notify_option.reserved1", FT_UINT16,
8025 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8026 
8027 		{ &hf_notify_option_reserved2,
8028 		  { "Reserved2", "spoolss.notify_option.reserved2", FT_UINT32,
8029 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8030 
8031 		{ &hf_notify_option_reserved3,
8032 		  { "Reserved3", "spoolss.notify_option.reserved3", FT_UINT32,
8033 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8034 
8035 		{ &hf_notify_option_count,
8036 		  { "Count", "spoolss.notify_option.count", FT_UINT32,
8037 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8038 
8039 		{ &hf_notify_option_data_count,
8040 		  { "Count", "spoolss.notify_option_data.count", FT_UINT32,
8041 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8042 
8043 		{ &hf_notify_options_flags_refresh,
8044 		  { "Refresh", "spoolss.notify_options.flags.refresh", FT_BOOLEAN, 32,
8045 		    TFS(&tfs_notify_options_flags_refresh),
8046 		    PRINTER_NOTIFY_OPTIONS_REFRESH, NULL, HFILL }},
8047 
8048 		{ &hf_notify_info_count,
8049 		  { "Count", "spoolss.notify_info.count", FT_UINT32, BASE_DEC,
8050 		    NULL, 0, NULL, HFILL }},
8051 
8052 		{ &hf_notify_info_version,
8053 		  { "Version", "spoolss.notify_info.version", FT_UINT32,
8054 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8055 
8056 		{ &hf_notify_info_flags,
8057 		  { "Flags", "spoolss.notify_info.flags", FT_UINT32, BASE_HEX,
8058 		    NULL, 0, NULL, HFILL }},
8059 
8060 		{ &hf_notify_info_data_type,
8061 		  { "Type", "spoolss.notify_info_data.type", FT_UINT16,
8062 		    BASE_DEC, VALS(printer_notify_types), 0, NULL, HFILL }},
8063 
8064 		{ &hf_notify_field,
8065 		  { "Field", "spoolss.notify_field", FT_UINT16, BASE_DEC,
8066 		    NULL, 0, NULL, HFILL }},
8067 
8068 		{ &hf_notify_info_data_count,
8069 		  { "Count", "spoolss.notify_info_data.count", FT_UINT32,
8070 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8071 
8072 		{ &hf_notify_info_data_id,
8073 		  { "Job Id", "spoolss.notify_info_data.jobid", FT_UINT32,
8074 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8075 
8076 		{ &hf_notify_info_data_value1,
8077 		  { "Value1", "spoolss.notify_info_data.value1", FT_UINT32,
8078 		    BASE_HEX, NULL, 0, NULL, HFILL }},
8079 
8080 		{ &hf_notify_info_data_value2,
8081 		  { "Value2", "spoolss.notify_info_data.value2", FT_UINT32,
8082 		    BASE_HEX, NULL, 0, NULL, HFILL }},
8083 
8084 		{ &hf_notify_info_data_bufsize,
8085 		  { "Buffer size", "spoolss.notify_info_data.bufsize",
8086 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8087 
8088 		{ &hf_notify_info_data_buffer,
8089 		  { "Buffer", "spoolss.notify_info_data.buffer", FT_UINT32,
8090 		    BASE_HEX, NULL, 0, NULL, HFILL }},
8091 
8092 		{ &hf_notify_info_data_buffer_len,
8093 		  { "Buffer length", "spoolss.notify_info_data.buffer.len",
8094 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
8095 
8096 		{ &hf_notify_info_data_buffer_data,
8097 		  { "Buffer data", "spoolss.notify_info_data.buffer.data",
8098 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
8099 
8100 		/* RffpCNex RPC */
8101 
8102 		{ &hf_rffpcnex_options,
8103 		  { "Options", "spoolss.rffpcnex.options", FT_UINT32, BASE_DEC,
8104 		    NULL, 0, "RFFPCNEX options", HFILL }},
8105 
8106 		{ &hf_printerlocal, /* XXX: move me */
8107 		  { "Printer local", "spoolss.printer_local", FT_UINT32,
8108 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8109 
8110 		{ &hf_rffpcnex_flags,
8111 		  { "RFFPCNEX flags", "spoolss.rffpcnex.flags", FT_UINT32,
8112 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8113 
8114 		{ &hf_rffpcnex_flags_add_printer,
8115 		  { "Add printer", "spoolss.rffpcnex.flags.add_printer",
8116 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_add_printer),
8117 		    SPOOLSS_PRINTER_CHANGE_ADD_PRINTER, NULL,
8118 		    HFILL }},
8119 
8120 		{ &hf_rffpcnex_flags_set_printer,
8121 		  { "Set printer", "spoolss.rffpcnex.flags.set_printer",
8122 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_set_printer),
8123 		    SPOOLSS_PRINTER_CHANGE_SET_PRINTER, NULL,
8124 		    HFILL }},
8125 
8126 		{ &hf_rffpcnex_flags_delete_printer,
8127 		  { "Delete printer", "spoolss.rffpcnex.flags.delete_printer",
8128 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_delete_printer),
8129 		    SPOOLSS_PRINTER_CHANGE_DELETE_PRINTER, NULL,
8130 		    HFILL }},
8131 
8132 		{ &hf_rffpcnex_flags_add_job,
8133 		  { "Add job", "spoolss.rffpcnex.flags.add_job",
8134 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_add_job),
8135 		    SPOOLSS_PRINTER_CHANGE_ADD_JOB, NULL, HFILL }},
8136 
8137 		{ &hf_rffpcnex_flags_set_job,
8138 		  { "Set job", "spoolss.rffpcnex.flags.set_job",
8139 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_set_job),
8140 		    SPOOLSS_PRINTER_CHANGE_SET_JOB, NULL, HFILL }},
8141 
8142 		{ &hf_rffpcnex_flags_delete_job,
8143 		  { "Delete job", "spoolss.rffpcnex.flags.delete_job",
8144 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_delete_job),
8145 		    SPOOLSS_PRINTER_CHANGE_DELETE_JOB, NULL, HFILL }},
8146 
8147 		{ &hf_rffpcnex_flags_write_job,
8148 		  { "Write job", "spoolss.rffpcnex.flags.write_job",
8149 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_write_job),
8150 		    SPOOLSS_PRINTER_CHANGE_WRITE_JOB, NULL, HFILL }},
8151 
8152 		{ &hf_rffpcnex_flags_add_form,
8153 		  { "Add form", "spoolss.rffpcnex.flags.add_form",
8154 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_add_form),
8155 		    SPOOLSS_PRINTER_CHANGE_ADD_FORM, NULL, HFILL }},
8156 
8157 		{ &hf_rffpcnex_flags_set_form,
8158 		  { "Set form", "spoolss.rffpcnex.flags.set_form",
8159 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_set_form),
8160 		    SPOOLSS_PRINTER_CHANGE_SET_FORM, NULL, HFILL }},
8161 
8162 		{ &hf_rffpcnex_flags_delete_form,
8163 		  { "Delete form", "spoolss.rffpcnex.flags.delete_form",
8164 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_delete_form),
8165 		    SPOOLSS_PRINTER_CHANGE_DELETE_FORM, NULL,
8166 		    HFILL }},
8167 
8168 		{ &hf_rffpcnex_flags_add_port,
8169 		  { "Add port", "spoolss.rffpcnex.flags.add_port",
8170 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_add_port),
8171 		    SPOOLSS_PRINTER_CHANGE_ADD_PORT, NULL, HFILL }},
8172 
8173 		{ &hf_rffpcnex_flags_configure_port,
8174 		  { "Configure port", "spoolss.rffpcnex.flags.configure_port",
8175 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_configure_port),
8176 		    SPOOLSS_PRINTER_CHANGE_CONFIGURE_PORT, NULL,
8177 		    HFILL }},
8178 
8179 		{ &hf_rffpcnex_flags_delete_port,
8180 		  { "Delete port", "spoolss.rffpcnex.flags.delete_port",
8181 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_delete_port),
8182 		    SPOOLSS_PRINTER_CHANGE_DELETE_PORT, NULL,
8183 		    HFILL }},
8184 
8185 		{ &hf_rffpcnex_flags_add_print_processor,
8186 		  { "Add processor", "spoolss.rffpcnex.flags.add_processor",
8187 		    FT_BOOLEAN, 32,
8188 		    TFS(&tfs_rffpcnex_flags_add_print_processor),
8189 		    SPOOLSS_PRINTER_CHANGE_ADD_PRINT_PROCESSOR,
8190 		    NULL, HFILL }},
8191 
8192 		{ &hf_rffpcnex_flags_delete_print_processor,
8193 		  { "Delete processor",
8194 		    "spoolss.rffpcnex.flags.delete_processor", FT_BOOLEAN, 32,
8195 		    TFS(&tfs_rffpcnex_flags_delete_print_processor),
8196 		    SPOOLSS_PRINTER_CHANGE_DELETE_PRINT_PROCESSOR,
8197 		    NULL, HFILL }},
8198 
8199 		{ &hf_rffpcnex_flags_add_driver,
8200 		  { "Add driver", "spoolss.rffpcnex.flags.add_driver",
8201 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_add_driver),
8202 		    SPOOLSS_PRINTER_CHANGE_ADD_PRINTER_DRIVER, NULL,
8203 		    HFILL }},
8204 
8205 		{ &hf_rffpcnex_flags_set_driver,
8206 		  { "Set driver", "spoolss.rffpcnex.flags.set_driver",
8207 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_set_driver),
8208 		    SPOOLSS_PRINTER_CHANGE_SET_PRINTER_DRIVER, NULL,
8209 		    HFILL }},
8210 
8211 		{ &hf_rffpcnex_flags_delete_driver,
8212 		  { "Delete driver", "spoolss.rffpcnex.flags.delete_driver",
8213 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_delete_driver),
8214 		    SPOOLSS_PRINTER_CHANGE_DELETE_PRINTER_DRIVER,
8215 		    NULL, HFILL }},
8216 
8217 		{ &hf_rffpcnex_flags_timeout,
8218 		  { "Timeout", "spoolss.rffpcnex.flags.timeout",
8219 		    FT_BOOLEAN, 32, TFS(&tfs_rffpcnex_flags_timeout),
8220 		    SPOOLSS_PRINTER_CHANGE_TIMEOUT, NULL, HFILL }},
8221 
8222 		{ &hf_rffpcnex_flags_failed_printer_connection,
8223 		  { "Failed printer connection",
8224 		    "spoolss.rffpcnex.flags.failed_connection_printer",
8225 		    FT_BOOLEAN, 32,
8226 		    TFS(&tfs_rffpcnex_flags_failed_connection_printer),
8227 		    SPOOLSS_PRINTER_CHANGE_FAILED_CONNECTION_PRINTER,
8228 		    NULL, HFILL }},
8229 
8230 		/* RRPCN RPC */
8231 
8232 		{ &hf_rrpcn_changelow,
8233 		  { "Change low", "spoolss.rrpcn.changelow", FT_UINT32,
8234 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8235 
8236 		{ &hf_rrpcn_changehigh,
8237 		  { "Change high", "spoolss.rrpcn.changehigh", FT_UINT32,
8238 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8239 
8240 		{ &hf_rrpcn_unk0,
8241 		  { "Unknown 0", "spoolss.rrpcn.unk0", FT_UINT32, BASE_DEC,
8242 		    NULL, 0, NULL, HFILL }},
8243 
8244 		{ &hf_rrpcn_unk1,
8245 		  { "Unknown 1", "spoolss.rrpcn.unk1", FT_UINT32, BASE_DEC,
8246 		    NULL, 0, NULL, HFILL }},
8247 
8248 		/* ReplyOpenPrinter RPC */
8249 
8250 		{ &hf_replyopenprinter_unk0,
8251 		  { "Unknown 0", "spoolss.replyopenprinter.unk0", FT_UINT32,
8252 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8253 
8254 		{ &hf_replyopenprinter_unk1,
8255 		  { "Unknown 1", "spoolss.replyopenprinter.unk1", FT_UINT32,
8256 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8257 
8258 		{ &hf_devmode_devicename,
8259 		  { "DeviceName", "spoolss.devmode.devicename", FT_STRING,
8260 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8261 
8262 		{ &hf_devmode_form_name,
8263 		  { "FormName", "spoolss.devmode.form_name", FT_STRING,
8264 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8265 
8266 		{ &hf_relative_string,
8267 		  { "String", "spoolss.relative_string", FT_STRING,
8268 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8269 
8270 		{ &hf_value_name,
8271 		  { "Value Name", "spoolss.value_name", FT_STRING,
8272 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8273 
8274 		{ &hf_keybuffer,
8275 		  { "Key", "spoolss.hf_keybuffer", FT_STRING,
8276 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8277 
8278 		{ &hf_value_string,
8279 		  { "Value", "spoolss.value_string", FT_STRING,
8280 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8281 
8282 		/* Printer attributes */
8283 
8284 		{ &hf_printer_attributes,
8285 		  { "Attributes", "spoolss.printer_attributes", FT_UINT32,
8286 		    BASE_HEX, NULL, 0, NULL, HFILL }},
8287 
8288 		{ &hf_printer_attributes_queued,
8289 		  { "Queued", "spoolss.printer_attributes.queued", FT_BOOLEAN,
8290 		    32, TFS(&tfs_printer_attributes_queued),
8291 		    PRINTER_ATTRIBUTE_QUEUED, NULL, HFILL }},
8292 
8293 		{ &hf_printer_attributes_direct,
8294 		  { "Direct", "spoolss.printer_attributes.direct", FT_BOOLEAN,
8295 		    32, TFS(&tfs_printer_attributes_direct),
8296 		    PRINTER_ATTRIBUTE_DIRECT, NULL, HFILL }},
8297 
8298 		{ &hf_printer_attributes_default,
8299 		  { "Default (9x/ME only)",
8300 		    "spoolss.printer_attributes.default",FT_BOOLEAN,
8301 		    32, TFS(&tfs_printer_attributes_default),
8302 		    PRINTER_ATTRIBUTE_DEFAULT, "Default", HFILL }},
8303 
8304 		{ &hf_printer_attributes_shared,
8305 		  { "Shared", "spoolss.printer_attributes.shared", FT_BOOLEAN,
8306 		    32, TFS(&tfs_printer_attributes_shared),
8307 		    PRINTER_ATTRIBUTE_SHARED, NULL, HFILL }},
8308 
8309 		{ &hf_printer_attributes_network,
8310 		  { "Network", "spoolss.printer_attributes.network",
8311 		    FT_BOOLEAN, 32, TFS(&tfs_printer_attributes_network),
8312 		    PRINTER_ATTRIBUTE_NETWORK, NULL, HFILL }},
8313 
8314 		{ &hf_printer_attributes_hidden,
8315 		  { "Hidden", "spoolss.printer_attributes.hidden", FT_BOOLEAN,
8316 		    32, TFS(&tfs_printer_attributes_hidden),
8317 		    PRINTER_ATTRIBUTE_HIDDEN, NULL, HFILL }},
8318 
8319 		{ &hf_printer_attributes_local,
8320 		  { "Local", "spoolss.printer_attributes.local", FT_BOOLEAN,
8321 		    32, TFS(&tfs_printer_attributes_local),
8322 		    PRINTER_ATTRIBUTE_LOCAL, NULL, HFILL }},
8323 
8324 		{ &hf_printer_attributes_enable_devq,
8325 		  { "Enable devq", "spoolss.printer_attributes.enable_devq",
8326 		    FT_BOOLEAN, 32, TFS(&tfs_printer_attributes_enable_devq),
8327 		    PRINTER_ATTRIBUTE_ENABLE_DEVQ, "Enable evq", HFILL }},
8328 
8329 		{ &hf_printer_attributes_keep_printed_jobs,
8330 		  { "Keep printed jobs",
8331 		    "spoolss.printer_attributes.keep_printed_jobs", FT_BOOLEAN,
8332 		    32, TFS(&tfs_printer_attributes_keep_printed_jobs),
8333 		    PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS, NULL,
8334 		    HFILL }},
8335 
8336 		{ &hf_printer_attributes_do_complete_first,
8337 		  { "Do complete first",
8338 		    "spoolss.printer_attributes.do_complete_first", FT_BOOLEAN,
8339 		    32, TFS(&tfs_printer_attributes_do_complete_first),
8340 		    PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST, NULL,
8341 		    HFILL }},
8342 
8343 		{ &hf_printer_attributes_work_offline,
8344 		  { "Work offline (9x/ME only)",
8345 		    "spoolss.printer_attributes.work_offline", FT_BOOLEAN,
8346 		    32, TFS(&tfs_printer_attributes_work_offline),
8347 		    PRINTER_ATTRIBUTE_WORK_OFFLINE, "Work offline", HFILL }},
8348 
8349 		{ &hf_printer_attributes_enable_bidi,
8350 		  { "Enable bidi (9x/ME only)",
8351 		    "spoolss.printer_attributes.enable_bidi", FT_BOOLEAN,
8352 		    32, TFS(&tfs_printer_attributes_enable_bidi),
8353 		    PRINTER_ATTRIBUTE_ENABLE_BIDI, "Enable bidi", HFILL }},
8354 
8355 		{ &hf_printer_attributes_raw_only,
8356 		  { "Raw only", "spoolss.printer_attributes.raw_only",
8357 		    FT_BOOLEAN, 32, TFS(&tfs_printer_attributes_raw_only),
8358 		    PRINTER_ATTRIBUTE_RAW_ONLY, NULL, HFILL }},
8359 
8360 		{ &hf_printer_attributes_published,
8361 		  { "Published", "spoolss.printer_attributes.published",
8362 		    FT_BOOLEAN, 32, TFS(&tfs_printer_attributes_published),
8363 		    PRINTER_ATTRIBUTE_PUBLISHED, NULL, HFILL }},
8364 
8365 		/* Printer Driver attributes */
8366 
8367 		{ &hf_printer_driver_attributes,
8368 		  { "Driver Attributes", "spoolss.printer_driver_attributes", FT_UINT32,
8369 		    BASE_HEX, NULL, 0, NULL, HFILL }},
8370 
8371 		{ &hf_printer_driver_attributes_package_aware,
8372 		  { "Package Aware", "spoolss.printer_driver_attributes.packageaware", FT_BOOLEAN,
8373 		    32, TFS(&tfs_printer_driver_attributes_package_aware),
8374 		    PRINTER_DRIVER_PACKAGE_AWARE, NULL, HFILL }},
8375 
8376 		{ &hf_printer_driver_attributes_xps,
8377 		  { "XPS", "spoolss.printer_driver_attributes.xps", FT_BOOLEAN,
8378 		    32, TFS(&tfs_printer_driver_attributes_xps),
8379 		    PRINTER_DRIVER_XPS, NULL, HFILL }},
8380 
8381 		{ &hf_printer_driver_attributes_sandbox_enabled,
8382 		  { "Sandbox enabled", "spoolss.printer_driver_attributes.sandboxenabled", FT_BOOLEAN,
8383 		    32, TFS(&tfs_printer_driver_attributes_sandbox_enabled),
8384 		    PRINTER_DRIVER_SANDBOX_ENABLED, NULL, HFILL }},
8385 
8386 		{ &hf_printer_driver_attributes_class,
8387 		  { "Class Driver", "spoolss.printer_driver_attributes.class", FT_BOOLEAN,
8388 		    32, TFS(&tfs_printer_driver_attributes_class),
8389 		    PRINTER_DRIVER_CLASS, NULL, HFILL }},
8390 
8391 		{ &hf_printer_driver_attributes_derived,
8392 		  { "Derived Driver", "spoolss.printer_driver_attributes.derived", FT_BOOLEAN,
8393 		    32, TFS(&tfs_printer_driver_attributes_derived),
8394 		    PRINTER_DRIVER_DERIVED, NULL, HFILL }},
8395 
8396 		{ &hf_printer_driver_attributes_not_shareable,
8397 		  { "Not Shareable", "spoolss.printer_driver_attributes.notshareable", FT_BOOLEAN,
8398 		    32, TFS(&tfs_printer_driver_attributes_not_shareable),
8399 		    PRINTER_DRIVER_NOT_SHAREABLE, NULL, HFILL }},
8400 
8401 		{ &hf_printer_driver_attributes_category_fax,
8402 		  { "Category Fax", "spoolss.printer_driver_attributes.categoryfax", FT_BOOLEAN,
8403 		    32, TFS(&tfs_printer_driver_attributes_category_fax),
8404 		    PRINTER_DRIVER_CATEGORY_FAX, NULL, HFILL }},
8405 
8406 		{ &hf_printer_driver_attributes_category_file,
8407 		  { "Category File", "spoolss.printer_driver_attributes.categoryfile", FT_BOOLEAN,
8408 		    32, TFS(&tfs_printer_driver_attributes_category_file),
8409 		    PRINTER_DRIVER_CATEGORY_FILE, NULL, HFILL }},
8410 
8411 		{ &hf_printer_driver_attributes_category_virtual,
8412 		  { "Category Virtual", "spoolss.printer_driver_attributes.categoryvirtual", FT_BOOLEAN,
8413 		    32, TFS(&tfs_printer_driver_attributes_category_virtual),
8414 		    PRINTER_DRIVER_CATEGORY_VIRTUAL, NULL, HFILL }},
8415 
8416 		{ &hf_printer_driver_attributes_category_service,
8417 		  { "Category Service", "spoolss.printer_driver_attributes.categoryservice", FT_BOOLEAN,
8418 		    32, TFS(&tfs_printer_driver_attributes_category_service),
8419 		    PRINTER_DRIVER_CATEGORY_SERVICE, NULL, HFILL }},
8420 
8421 		{ &hf_printer_driver_attributes_soft_reset_required,
8422 		  { "Soft Reset Required", "spoolss.printer_driver_attributes.softresetrequired", FT_BOOLEAN,
8423 		    32, TFS(&tfs_printer_driver_attributes_soft_reset_required),
8424 		    PRINTER_DRIVER_SOFT_RESET_REQUIRED, NULL, HFILL }},
8425 
8426 		{ &hf_printer_driver_attributes_category_3d,
8427 		  { "Category 3D", "spoolss.printer_driver_attributes.category3d", FT_BOOLEAN,
8428 		    32, TFS(&tfs_printer_driver_attributes_category_3d),
8429 		    PRINTER_DRIVER_CATEGORY_3D, NULL, HFILL }},
8430 
8431 
8432 		/* Timestamps */
8433 
8434 		{ &hf_time_year,
8435 		  { "Year", "spoolss.time.year", FT_UINT32, BASE_DEC,
8436 		    NULL, 0x0, NULL, HFILL }},
8437 
8438 		{ &hf_time_month,
8439 		  { "Month", "spoolss.time.month", FT_UINT32, BASE_DEC,
8440 		    NULL, 0x0, NULL, HFILL }},
8441 
8442 		{ &hf_time_dow,
8443 		  { "Day of week", "spoolss.time.dow", FT_UINT32, BASE_DEC,
8444 		    NULL, 0x0, NULL, HFILL }},
8445 
8446 		{ &hf_time_day,
8447 		  { "Day", "spoolss.time.day", FT_UINT32, BASE_DEC,
8448 		    NULL, 0x0, NULL, HFILL }},
8449 
8450 		{ &hf_time_hour,
8451 		  { "Hour", "spoolss.time.hour", FT_UINT32, BASE_DEC,
8452 		    NULL, 0x0, NULL, HFILL }},
8453 
8454 		{ &hf_time_minute,
8455 		  { "Minute", "spoolss.time.minute", FT_UINT32, BASE_DEC,
8456 		    NULL, 0x0, NULL, HFILL }},
8457 
8458 		{ &hf_time_second,
8459 		  { "Second", "spoolss.time.second", FT_UINT32, BASE_DEC,
8460 		    NULL, 0x0, NULL, HFILL }},
8461 
8462 		{ &hf_time_msec,
8463 		  { "Millisecond", "spoolss.time.msec", FT_UINT32, BASE_DEC,
8464 		    NULL, 0x0, NULL, HFILL }},
8465 
8466 		/* Userlevel */
8467 
8468 		{ &hf_userlevel_size,
8469 		  { "Size", "spoolss.userlevel.size",
8470 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8471 
8472 		{ &hf_userlevel_client,
8473 		  { "Client", "spoolss.userlevel.client", FT_STRING,
8474 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8475 
8476 		{ &hf_userlevel_user,
8477 		  { "User", "spoolss.userlevel.user", FT_STRING,
8478 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8479 
8480 		{ &hf_userlevel_build,
8481 		  { "Build", "spoolss.userlevel.build",
8482 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8483 
8484 		{ &hf_userlevel_major,
8485 		  { "Major", "spoolss.userlevel.major",
8486 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8487 
8488 		{ &hf_userlevel_minor,
8489 		  { "Minor", "spoolss.userlevel.minor",
8490 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8491 
8492 		{ &hf_userlevel_processor,
8493 		  { "Processor", "spoolss.userlevel.processor",
8494 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8495 
8496 		/* EnumprinterdataEx RPC */
8497 
8498 		{ &hf_enumprinterdataex_name_offset,
8499 		  { "Name offset", "spoolss.enumprinterdataex.name_offset",
8500 		    FT_UINT32, BASE_DEC, NULL, 0x0,
8501 		    NULL, HFILL }},
8502 
8503 		{ &hf_enumprinterdataex_name_len,
8504 		  { "Name len", "spoolss.enumprinterdataex.name_len",
8505 		    FT_UINT32, BASE_DEC, NULL, 0x0,
8506 		    NULL, HFILL }},
8507 
8508 		{ &hf_enumprinterdataex_name,
8509 		  { "Name", "spoolss.enumprinterdataex.name",
8510 		    FT_STRING, BASE_NONE, NULL, 0x0,
8511 		    NULL, HFILL }},
8512 
8513 		{ &hf_enumprinterdataex_val_offset,
8514 		  { "Value offset", "spoolss.enumprinterdataex.value_offset",
8515 		    FT_UINT32, BASE_DEC, NULL, 0x0,
8516 		    NULL, HFILL }},
8517 
8518 		{ &hf_enumprinterdataex_val_len,
8519 		  { "Value len", "spoolss.enumprinterdataex.value_len",
8520 		    FT_UINT32, BASE_DEC, NULL, 0x0,
8521 		    NULL, HFILL }},
8522 
8523 		{ &hf_enumprinterdataex_val_dword_high,
8524 		  { "DWORD value (high)",
8525 		    "spoolss.enumprinterdataex.val_dword.high",
8526 		    FT_UINT16, BASE_DEC, NULL, 0x0,
8527 		    NULL, HFILL }},
8528 
8529 		{ &hf_enumprinterdataex_value_null,
8530 		  { "Value",
8531 		    "spoolss.enumprinterdataex.val_null",
8532 		    FT_UINT32, BASE_DEC, NULL, 0x0,
8533 		    NULL, HFILL }},
8534 
8535 		{ &hf_enumprinterdataex_value_uint,
8536 		  { "Value",
8537 		    "spoolss.enumprinterdataex.val_uint",
8538 		    FT_UINT32, BASE_DEC, NULL, 0x0,
8539 		    NULL, HFILL }},
8540 
8541 		{ &hf_enumprinterdataex_value_binary,
8542 		  { "Value",
8543 		    "spoolss.enumprinterdataex.val_binary",
8544 		    FT_BYTES, BASE_NONE, NULL, 0x0,
8545 		    NULL, HFILL }},
8546 
8547 		{ &hf_enumprinterdataex_value_multi_sz,
8548 		  { "Value",
8549 		    "spoolss.enumprinterdataex.val_multi_sz",
8550 		    FT_BYTES, BASE_NONE, NULL, 0x0,
8551 		    NULL, HFILL }},
8552 
8553 		{ &hf_enumprinterdataex_val_dword_low,
8554 		  { "DWORD value (low)",
8555 		    "spoolss.enumprinterdataex.val_dword.low",
8556 		    FT_UINT16, BASE_DEC, NULL, 0x0,
8557 		    NULL, HFILL }},
8558 
8559 		/* RouterReplyPrinter RPC */
8560 
8561 		{ &hf_routerreplyprinter_condition,
8562 		  { "Condition", "spoolss.routerreplyprinter.condition",
8563 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8564 
8565 		{ &hf_routerreplyprinter_unknown1,
8566 		  { "Unknown1", "spoolss.routerreplyprinter.unknown1",
8567 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8568 
8569 		{ &hf_routerreplyprinter_changeid,
8570 		  { "Change id", "spoolss.routerreplyprinter.changeid",
8571 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8572 
8573 		/* EnumPrinterKey RPC */
8574 
8575 		{ &hf_keybuffer_size,
8576 		  { "Key Buffer size", "spoolss.keybuffer.size", FT_UINT32,
8577 		    BASE_DEC, NULL, 0x0, "Size of buffer", HFILL }},
8578 
8579 		/* SetJob RPC */
8580 
8581 		{ &hf_setjob_cmd,
8582 		  { "Set job command", "spoolss.setjob.cmd", FT_UINT32,
8583 		    BASE_DEC, VALS(setjob_commands), 0x0, "Printer data name",
8584 		    HFILL }},
8585 
8586 		/* EnumJobs RPC */
8587 
8588 		{ &hf_enumjobs_firstjob,
8589 		  { "First job", "spoolss.enumjobs.firstjob", FT_UINT32,
8590 		    BASE_DEC, NULL, 0x0, "Index of first job to return",
8591 		    HFILL }},
8592 
8593 		{ &hf_enumjobs_numjobs,
8594 		  { "Num jobs", "spoolss.enumjobs.numjobs", FT_UINT32,
8595 		    BASE_DEC, NULL, 0x0, "Number of jobs to return", HFILL }},
8596 
8597 		/* Security descriptor buffer */
8598 
8599 		{ &hf_secdescbuf_maxlen,
8600 		  { "Max len", "spoolss.secdescbuf.max_len",
8601 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8602 
8603 		{ &hf_secdescbuf_undoc,
8604 		  { "Undocumented", "spoolss.secdescbuf.undoc",
8605 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8606 
8607 		{ &hf_secdescbuf_len,
8608 		  { "Length", "spoolss.secdescbuf.len",
8609 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8610 
8611 		/* Spool printer info */
8612 
8613 		{ &hf_spool_printer_info_devmode_ptr,
8614 		  { "Devmode pointer", "spoolss.spoolprinterinfo.devmode_ptr",
8615 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
8616 
8617 		{ &hf_spool_printer_info_secdesc_ptr,
8618 		  { "Secdesc pointer", "spoolss.spoolprinterinfo.secdesc_ptr",
8619 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
8620 
8621 		/* WritePrinter RPC */
8622 
8623 		{ &hf_writeprinter_numwritten,
8624 		  { "Num written", "spoolss.writeprinter.numwritten",
8625 		    FT_UINT32, BASE_DEC, NULL, 0x0, "Number of bytes written",
8626 		    HFILL }},
8627 
8628 		/* Setprinterdataex RPC */
8629 
8630 		{ &hf_setprinterdataex_max_len,
8631 		  { "Max len", "spoolss.setprinterdataex.max_len",
8632 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8633 
8634 		{ &hf_setprinterdataex_real_len,
8635 		  { "Real len", "spoolss.setprinterdataex.real_len",
8636 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8637 
8638 		{ &hf_setprinterdataex_data,
8639 		  { "Data", "spoolss.setprinterdataex.data",
8640 		    FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
8641 
8642 		/* Specific access rights */
8643 
8644 		{ &hf_access_required,
8645 		  { "Access required", "spoolss.access_required",
8646 		    FT_UINT32, BASE_HEX, NULL, 0x0, NULL,
8647 		    HFILL }},
8648 
8649 		{ &hf_server_access_admin,
8650 		  { "Server admin", "spoolss.access_mask.server_admin",
8651 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
8652 		    SERVER_ACCESS_ADMINISTER, NULL, HFILL }},
8653 
8654 		{ &hf_server_access_enum,
8655 		  { "Server enum", "spoolss.access_mask.server_enum",
8656 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
8657 		    SERVER_ACCESS_ENUMERATE, NULL, HFILL }},
8658 
8659 		{ &hf_printer_access_admin,
8660 		  { "Printer admin", "spoolss.access_mask.printer_admin",
8661 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
8662 		    PRINTER_ACCESS_ADMINISTER, NULL, HFILL }},
8663 
8664 		{ &hf_printer_access_use,
8665 		  { "Printer use", "spoolss.access_mask.printer_use",
8666 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
8667 		    PRINTER_ACCESS_USE, NULL, HFILL }},
8668 
8669 		{ &hf_job_access_admin,
8670 		  { "Job admin", "spoolss.access_mask.job_admin",
8671 		    FT_BOOLEAN, 32, TFS(&tfs_set_notset),
8672 		    JOB_ACCESS_ADMINISTER, NULL, HFILL }},
8673 
8674 		/* Printer information */
8675 
8676 		{ &hf_printer_cjobs,
8677 		  { "CJobs", "spoolss.printer.cjobs", FT_UINT32,
8678 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8679 
8680 		{ &hf_printer_total_jobs,
8681 		  { "Total jobs", "spoolss.printer.total_jobs", FT_UINT32,
8682 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8683 
8684 		{ &hf_printer_total_bytes,
8685 		  { "Total bytes", "spoolss.printer.total_bytes", FT_UINT32,
8686 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8687 
8688 		{ &hf_printer_global_counter,
8689 		  { "Global counter", "spoolss.printer.global_counter",
8690 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8691 
8692 		{ &hf_printer_total_pages,
8693 		  { "Total pages", "spoolss.printer.total_pages", FT_UINT32,
8694 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8695 
8696 		{ &hf_printer_major_version,
8697 		  { "Major version", "spoolss.printer.major_version",
8698 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8699 
8700 		{ &hf_printer_build_version,
8701 		  { "Build version", "spoolss.printer.build_version",
8702 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8703 
8704 		{ &hf_printer_unk7,
8705 		  { "Unknown 7", "spoolss.printer.unknown7", FT_UINT32,
8706 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8707 
8708 		{ &hf_printer_unk8,
8709 		  { "Unknown 8", "spoolss.printer.unknown8", FT_UINT32,
8710 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8711 
8712 		{ &hf_printer_unk9,
8713 		  { "Unknown 9", "spoolss.printer.unknown9", FT_UINT32,
8714 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8715 
8716 		{ &hf_printer_session_ctr,
8717 		  { "Session counter", "spoolss.printer.session_ctr",
8718 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8719 
8720 		{ &hf_printer_unk11,
8721 		  { "Unknown 11", "spoolss.printer.unknown11", FT_UINT32,
8722 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8723 
8724 		{ &hf_printer_printer_errors,
8725 		  { "Printer errors", "spoolss.printer.printer_errors",
8726 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8727 
8728 		{ &hf_printer_unk13,
8729 		  { "Unknown 13", "spoolss.printer.unknown13", FT_UINT32,
8730 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8731 
8732 		{ &hf_printer_unk14,
8733 		  { "Unknown 14", "spoolss.printer.unknown14", FT_UINT32,
8734 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8735 
8736 		{ &hf_printer_unk15,
8737 		  { "Unknown 15", "spoolss.printer.unknown15", FT_UINT32,
8738 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8739 
8740 		{ &hf_printer_unk16,
8741 		  { "Unknown 16", "spoolss.printer.unknown16", FT_UINT32,
8742 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8743 
8744 		{ &hf_printer_changeid,
8745 		  { "Change id", "spoolss.printer.changeid", FT_UINT32,
8746 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8747 
8748 		{ &hf_printer_unk18,
8749 		  { "Unknown 18", "spoolss.printer.unknown18", FT_UINT32,
8750 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8751 
8752 		{ &hf_printer_unk20,
8753 		  { "Unknown 20", "spoolss.printer.unknown20", FT_UINT32,
8754 		    BASE_DEC, NULL, 0, NULL, HFILL }},
8755 
8756 		{ &hf_printer_c_setprinter,
8757 		  { "Csetprinter", "spoolss.printer.c_setprinter",
8758 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8759 
8760 		{ &hf_printer_unk22,
8761 		  { "Unknown 22", "spoolss.printer.unknown22",
8762 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8763 
8764 		{ &hf_printer_unk23,
8765 		  { "Unknown 23", "spoolss.printer.unknown23",
8766 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8767 
8768 		{ &hf_printer_unk24,
8769 		  { "Unknown 24", "spoolss.printer.unknown24",
8770 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8771 
8772 		{ &hf_printer_unk25,
8773 		  { "Unknown 25", "spoolss.printer.unknown25",
8774 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8775 
8776 		{ &hf_printer_unk26,
8777 		  { "Unknown 26", "spoolss.printer.unknown26",
8778 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8779 
8780 		{ &hf_printer_unk27,
8781 		  { "Unknown 27", "spoolss.printer.unknown27",
8782 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8783 
8784 		{ &hf_printer_unk28,
8785 		  { "Unknown 28", "spoolss.printer.unknown28",
8786 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8787 
8788 		{ &hf_printer_unk29,
8789 		  { "Unknown 29", "spoolss.printer.unknown29",
8790 		    FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
8791 
8792 		{ &hf_printer_flags,
8793 		  { "Flags", "spoolss.printer.flags",
8794 		    FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
8795 
8796 		{ &hf_printer_priority,
8797 		  { "Priority", "spoolss.printer.priority",
8798 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8799 
8800 		{ &hf_printer_default_priority,
8801 		  { "Default Priority", "spoolss.printer.default_priority",
8802 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8803 
8804 		{ &hf_printer_averageppm,
8805 		  { "Average PPM", "spoolss.printer.averageppm",
8806 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8807 
8808 		{ &hf_printer_jobs,
8809 		  { "Jobs", "spoolss.printer.jobs",
8810 		    FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
8811 
8812 		{ &hf_printer_guid,
8813 		  { "GUID", "spoolss.printer.guid", FT_STRING,
8814 		    BASE_NONE, NULL, 0, NULL, HFILL }},
8815 
8816 		{ &hf_printer_action,
8817 		  { "Action", "spoolss.printer.action", FT_UINT32, BASE_DEC,
8818 		   VALS(getprinter_action_vals), 0, NULL, HFILL }},
8819 	};
8820 
8821 	static gint *ett[] = {
8822 		&ett_dcerpc_spoolss,
8823 		&ett_PRINTER_DATATYPE,
8824 		&ett_DEVMODE_CTR,
8825 		&ett_DEVMODE,
8826 		&ett_DEVMODE_fields,
8827 		&ett_USER_LEVEL_CTR,
8828 		&ett_USER_LEVEL_1,
8829 		&ett_BUFFER,
8830 		&ett_PRINTER_INFO,
8831 		&ett_SPOOL_PRINTER_INFO_LEVEL,
8832 		&ett_PRINTER_INFO_0,
8833 		&ett_PRINTER_INFO_1,
8834 		&ett_PRINTER_INFO_2,
8835 		&ett_PRINTER_INFO_3,
8836 		&ett_PRINTER_INFO_5,
8837 		&ett_PRINTER_INFO_7,
8838 		&ett_RELSTR,
8839 		&ett_RELSTR_ARRAY,
8840 		&ett_FORM_REL,
8841 		&ett_FORM_CTR,
8842 		&ett_FORM_1,
8843 		&ett_JOB_INFO_1,
8844 		&ett_JOB_INFO_2,
8845 		&ett_SEC_DESC_BUF,
8846 		&ett_SYSTEM_TIME,
8847 		&ett_DOC_INFO_1,
8848 		&ett_DOC_INFO,
8849 		&ett_DOC_INFO_CTR,
8850 		&ett_printerdata_value,
8851 		&ett_printerdata_data,
8852 		&ett_writeprinter_buffer,
8853 		&ett_DRIVER_INFO_1,
8854 		&ett_DRIVER_INFO_2,
8855 		&ett_DRIVER_INFO_3,
8856 		&ett_DRIVER_INFO_6,
8857 		&ett_DRIVER_INFO_8,
8858 		&ett_DRIVER_INFO_101,
8859 		&ett_CORE_PRINTER_DRIVER,
8860 		&ett_rffpcnex_flags,
8861 		&ett_notify_options_flags,
8862 		&ett_NOTIFY_INFO_DATA,
8863 		&ett_NOTIFY_OPTION,
8864 		&ett_printer_attributes,
8865 		&ett_printer_driver_attributes,
8866 		&ett_job_status,
8867 		&ett_enumprinters_flags,
8868 		&ett_PRINTER_DATA_CTR,
8869 		&ett_printer_enumdataex_value,
8870 	};
8871 
8872 	static ei_register_info ei[] = {
8873 		{ &ei_unimplemented_dissector, { "spoolss.unimplemented_dissector", PI_UNDECODED, PI_WARN, "Unimplemented dissector: SPOOLSS", EXPFILL }},
8874 		{ &ei_unknown_data, { "spoolss.unknown_data", PI_UNDECODED, PI_WARN, "Unknown data follows", EXPFILL }},
8875 		{ &ei_printer_info_level, { "spoolss.printer.unknown", PI_PROTOCOL, PI_WARN, "Unknown printer info level", EXPFILL }},
8876 		{ &ei_spool_printer_info_level, { "spoolss.spool_printer.unknown", PI_PROTOCOL, PI_WARN, "Unknown spool printer info level", EXPFILL }},
8877 		{ &ei_form_level, { "spoolss.form.level.unknown", PI_PROTOCOL, PI_WARN, "Unknown form info level", EXPFILL }},
8878 		{ &ei_job_info_level, { "spoolss.job_info.level.unknown", PI_PROTOCOL, PI_WARN, "Unknown job info level", EXPFILL }},
8879 		{ &ei_driver_info_level, { "spoolss.driver_info.level.unknown", PI_PROTOCOL, PI_WARN, "Unknown driver info level", EXPFILL }},
8880 		{ &ei_level, { "spoolss.level.unknown", PI_PROTOCOL, PI_WARN, "Info level unknown", EXPFILL }},
8881 		{ &ei_notify_info_data_type, { "spoolss.notify_info_data.type.unknown", PI_PROTOCOL, PI_WARN, "Unknown notify type", EXPFILL }},
8882 		{ &ei_enumprinterdataex_value, { "spoolss.enumprinterdataex.val_unknown", PI_PROTOCOL, PI_WARN, "Unknown value type", EXPFILL }},
8883 		{ &ei_buffer_size_too_long, { "spoolss.buffer.size.invalid", PI_PROTOCOL, PI_ERROR, "Buffer size too long", EXPFILL }},
8884 	};
8885 
8886 	expert_module_t* expert_dcerpc_spoolss;
8887 
8888 	proto_dcerpc_spoolss = proto_register_protocol(
8889 		"Microsoft Spool Subsystem", "SPOOLSS", "spoolss");
8890 
8891 	proto_register_field_array(proto_dcerpc_spoolss, hf, array_length(hf));
8892 	proto_register_subtree_array(ett, array_length(ett));
8893 	expert_dcerpc_spoolss = expert_register_protocol(proto_dcerpc_spoolss);
8894 	expert_register_field_array(expert_dcerpc_spoolss, ei, array_length(ei));
8895 }
8896 
8897 /* Protocol handoff */
8898 
8899 static e_guid_t uuid_dcerpc_spoolss = {
8900 	0x12345678, 0x1234, 0xabcd,
8901 	{ 0xef, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }
8902 };
8903 
8904 static guint16 ver_dcerpc_spoolss = 1;
8905 
8906 void
proto_reg_handoff_dcerpc_spoolss(void)8907 proto_reg_handoff_dcerpc_spoolss(void)
8908 {
8909 
8910 	/* Register protocol as dcerpc */
8911 
8912 	dcerpc_init_uuid(proto_dcerpc_spoolss, ett_dcerpc_spoolss,
8913 			 &uuid_dcerpc_spoolss, ver_dcerpc_spoolss,
8914 			 dcerpc_spoolss_dissectors, hf_opnum);
8915 }
8916 
8917 /*
8918  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
8919  *
8920  * Local variables:
8921  * c-basic-offset: 8
8922  * tab-width: 8
8923  * indent-tabs-mode: t
8924  * End:
8925  *
8926  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
8927  * :indentSize=8:tabSize=8:noTabs=false:
8928  */
8929