aboutsummaryrefslogtreecommitdiffstats
path: root/packet-dcerpc-spoolss.c
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2003-01-11 04:40:21 +0000
committerTim Potter <tpot@samba.org>2003-01-11 04:40:21 +0000
commit5039537845244241d0cf14947105160f239dcf47 (patch)
tree425a704a1e6e3b609319ab573ea283f6bd5f867c /packet-dcerpc-spoolss.c
parent56b60052cd95d5f65e906392457520b7476b2df6 (diff)
Finish converting remaining RPCs to ndr routines.
Deleted all the old crufy ndr pointer dissection. Hooray! Next on the hit list is some refactoring of the ndr string routines... svn path=/trunk/; revision=6899
Diffstat (limited to 'packet-dcerpc-spoolss.c')
-rw-r--r--packet-dcerpc-spoolss.c483
1 files changed, 125 insertions, 358 deletions
diff --git a/packet-dcerpc-spoolss.c b/packet-dcerpc-spoolss.c
index 0bc5474e66..f5b36d28e3 100644
--- a/packet-dcerpc-spoolss.c
+++ b/packet-dcerpc-spoolss.c
@@ -2,7 +2,7 @@
* Routines for SMB \PIPE\spoolss packet disassembly
* Copyright 2001-2002, Tim Potter <tpot@samba.org>
*
- * $Id: packet-dcerpc-spoolss.c,v 1.70 2003/01/11 00:42:12 tpot Exp $
+ * $Id: packet-dcerpc-spoolss.c,v 1.71 2003/01/11 04:40:21 tpot Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -665,6 +665,23 @@ static int hf_spoolss_userlevel_major = -1;
static int hf_spoolss_userlevel_minor = -1;
static int hf_spoolss_userlevel_processor = -1;
+/* Setprinterdataex */
+
+static int hf_spoolss_setprinterdataex_max_len = -1;
+static int hf_spoolss_setprinterdataex_real_len = -1;
+static int hf_spoolss_setprinterdataex_data = -1;
+
+/* spool printer info */
+
+static int hf_spoolss_spool_printer_info_devmode_ptr = -1;
+static int hf_spoolss_spool_printer_info_secdesc_ptr = -1;
+
+/* Security descriptor buffer */
+
+static int hf_spoolss_secdescbuf_maxlen = -1;
+static int hf_spoolss_secdescbuf_undoc = -1;
+static int hf_spoolss_secdescbuf_len = -1;
+
static void
spoolss_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree,
guint32 access)
@@ -820,141 +837,6 @@ dissect_SYSTEM_TIME(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
/*
- * New system for handling pointers and buffers. We act more like the NDR
- * specification and have a list of deferred pointers which are processed
- * after a structure has been parsed.
- *
- * Each structure has a parse function which takes as an argument a GList.
- * As pointers are processed, they are appended onto this list. When the
- * structure is complete, the pointers (referents) are processed by calling
- * prs_referents(). In the case of function arguments, the
- * prs_struct_and_referents() function is called as pointers are always
- * processed immediately after the argument.
- */
-
-typedef int prs_fn(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, GList **dp_list, void **data);
-
-/* Deferred referent */
-
-struct deferred_ptr {
- prs_fn *fn; /* Parse function to call */
- proto_tree *tree; /* Tree context */
-};
-
-/* A structure to hold needed ethereal state to pass to GList foreach
- iterator. */
-
-struct deferred_ptr_state {
- tvbuff_t *tvb;
- int *poffset;
- packet_info *pinfo;
- GList **dp_list;
- void **ptr_data;
-};
-
-static void defer_ptr(GList **list, prs_fn *fn, proto_tree *tree)
-{
- struct deferred_ptr *dr;
-
- dr = g_malloc(sizeof(struct deferred_ptr));
-
- dr->fn = fn;
- dr->tree = tree;
-
- *list = g_list_append(*list, dr);
-}
-
-/* Parse a pointer */
-
-static int prs_ptr(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, guint32 *data, char *name)
-{
- guint32 ptr;
-
- offset = prs_uint32(tvb, offset, pinfo, tree, &ptr, NULL);
-
- if (tree && name)
- proto_tree_add_text(tree, tvb, offset - 4, 4,
- "%s pointer: 0x%08x", name, ptr);
-
- if (data)
- *data = ptr;
-
- return offset;
-}
-
-/* Iterator function for prs_referents */
-
-static void dr_iterator(gpointer data, gpointer user_data)
-{
- struct deferred_ptr *dp = (struct deferred_ptr *)data;
- struct deferred_ptr_state *s = (struct deferred_ptr_state *)user_data;
-
- /* Parse pointer */
-
- *s->poffset = dp->fn(s->tvb, *s->poffset, s->pinfo, dp->tree,
- s->dp_list, s->ptr_data);
-
- if (s->ptr_data)
- s->ptr_data++; /* Ready for next parse fn */
-}
-
-/* Call the parse function for each element in the deferred pointers list.
- If there are any additional pointers in these structures they are pushed
- onto parent_dp_list. */
-
-static int prs_referents(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree _U_, GList **dp_list, GList **list,
- void ***ptr_data)
-{
- struct deferred_ptr_state s;
- int new_offset = offset;
-
- /* Create a list of void pointers to store return data */
-
- if (ptr_data) {
- int len = g_list_length(*dp_list) * sizeof(void *);
-
- if (len > 0) {
- *ptr_data = malloc(len);
- memset(*ptr_data, 0, len);
- } else
- *ptr_data = NULL;
- }
-
- /* Set up iterator data */
-
- s.tvb = tvb;
- s.poffset = &new_offset;
- s.pinfo = pinfo;
- s.dp_list = dp_list;
- s.ptr_data = ptr_data ? *ptr_data : NULL;
-
- g_list_foreach(*list, dr_iterator, &s);
-
- *list = NULL; /* XXX: free list */
-
- return new_offset;
-}
-
-/* Parse a structure then clean up any deferred referants it creates. */
-
-static int prs_struct_and_referents(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- prs_fn *fn, void **data, void ***ptr_data)
-{
- GList *dp_list = NULL;
-
- offset = fn(tvb, offset, pinfo, tree, &dp_list, data);
-
- offset = prs_referents(tvb, offset, pinfo, tree, &dp_list,
- &dp_list, ptr_data);
-
- return offset;
-}
-
-/*
* SpoolssClosePrinter
*/
@@ -1070,56 +952,6 @@ dissect_unistr2(tvbuff_t *tvb, gint offset, packet_info *pinfo,
return offset;
}
-/* Parse a UNISTR2 structure */
-
-static int prs_UNISTR2_dp(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, GList **dp_list _U_, void **data)
-{
- proto_item *item;
- proto_tree *subtree;
- guint32 length, the_offset, max_len;
- int old_offset = offset;
- int data16_offset;
- char *text;
-
- offset = prs_uint32(tvb, offset, pinfo, tree, &length, NULL);
- offset = prs_uint32(tvb, offset, pinfo, tree, &the_offset, NULL);
- offset = prs_uint32(tvb, offset, pinfo, tree, &max_len, NULL);
-
- offset = prs_uint16s(tvb, offset, pinfo, tree, max_len, &data16_offset,
- NULL);
-
- text = fake_unicode(tvb, data16_offset, max_len);
-
- item = proto_tree_add_text(tree, tvb, old_offset, offset - old_offset,
- "UNISTR2: %s", text);
-
- subtree = proto_item_add_subtree(item, ett_UNISTR2);
-
- if (data)
- *data = text;
- else
- g_free(text);
-
- proto_tree_add_text(subtree, tvb, old_offset, 4, "Length: %u", length);
-
- old_offset += 4;
-
- proto_tree_add_text(subtree, tvb, old_offset, 4, "Offset: %u",
- the_offset);
-
- old_offset += 4;
-
- proto_tree_add_text(subtree, tvb, old_offset, 4, "Max length: %u",
- max_len);
-
- old_offset += 4;
-
- proto_tree_add_text(subtree, tvb, old_offset, max_len * 2, "Data");
-
- return offset;
-}
-
/* Dissect some printer data. The get/set/enum printerdata routines all
store value/data in a uint8 array. We could use the ndr routines for
this but that would result in one item for each byte in the printer
@@ -1209,7 +1041,8 @@ static int SpoolssGetPrinterData_r(tvbuff_t *tvb, int offset,
offset = dissect_printerdata_data(tvb, offset, pinfo, tree, drep);
- offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Needed");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep, hf_spoolss_needed, NULL);
offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
hf_spoolss_rc, NULL);
@@ -1295,11 +1128,15 @@ static int SpoolssGetPrinterDataEx_r(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_spoolss_printerdata_type, NULL);
- offset = prs_uint32(tvb, offset, pinfo, tree, &size, "Size");
+ offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
+ hf_spoolss_printerdata_size, &size);
- offset = prs_uint8s(tvb, offset, pinfo, tree, size, NULL, "Data");
+ offset = dissect_ndr_uint8s(
+ tvb, offset, pinfo, NULL, drep,
+ hf_spoolss_printerdata_data, size, NULL);
- offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Needed");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep, hf_spoolss_needed, NULL);
offset = dissect_doserror(tvb, offset, pinfo, tree, drep,
hf_spoolss_rc, NULL);
@@ -1417,12 +1254,17 @@ static int SpoolssSetPrinterDataEx_q(tvbuff_t *tvb, int offset,
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_spoolss_printerdata_type, NULL);
- offset = prs_uint32(tvb, offset, pinfo, tree, &max_len, "Max length");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_spoolss_setprinterdataex_max_len, &max_len);
- offset = prs_uint8s(tvb, offset, pinfo, tree, max_len, NULL,
- "Data");
+ offset = dissect_ndr_uint8s(
+ tvb, offset, pinfo, tree, drep,
+ hf_spoolss_setprinterdataex_data, max_len, NULL);
- offset = prs_uint32(tvb, offset, pinfo, tree, NULL, "Real length");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, tree, drep,
+ hf_spoolss_setprinterdataex_real_len, NULL);
dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
@@ -1484,33 +1326,6 @@ dissect_spoolss_uint16uni(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
return offset + (len + 1) * 2;
}
-static int prs_uint16uni(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
- proto_tree *tree, void **data, char *name)
-{
- gint len = 0, remaining;
- char *text;
-
- offset = prs_align(offset, 2);
-
- /* Get remaining data in buffer as a string */
-
- remaining = tvb_length_remaining(tvb, offset)/2;
- text = fake_unicode(tvb, offset, remaining);
- len = strlen(text);
-
- if (name)
- proto_tree_add_text(tree, tvb, offset, (len + 1) * 2,
- "%s: %s", name ? name : "UINT16UNI",
- text);
-
- if (data)
- *data = text;
- else
- g_free(text);
-
- return offset + (len + 1) * 2;
-}
-
/*
* DEVMODE
*/
@@ -1846,71 +1661,6 @@ static int dissect_DEVMODE_CTR(tvbuff_t *tvb, int offset, packet_info *pinfo,
return offset;
}
-static int prs_DEVMODE(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, GList **dp_list _U_, void **data _U_)
-{
- proto_item *item;
- proto_tree *subtree;
- guint16 extra;
-
- item = proto_tree_add_text(tree, tvb, offset, 0, "DEVMODE");
-
- subtree = proto_item_add_subtree(item, ett_DEVMODE);
-
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Size");
-
- /* The device name is stored in a 32-wchar buffer */
-
- prs_uint16uni(tvb, offset, pinfo, subtree, NULL, "Devicename");
- offset += 64;
-
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Spec version");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Driver version");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Size");
- offset = prs_uint16(tvb, offset, pinfo, subtree, &extra, "Driver extra");
-
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Fields");
-
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Orientation");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Paper size");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Paper length");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Paper width");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Scale");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Copies");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Default source");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Print quality");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Color");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Duplex");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Y resolution");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "TT option");
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Collate");
-
- prs_uint16uni(tvb, offset, pinfo, subtree, NULL, "Form name");
- offset += 64;
-
- offset = prs_uint16(tvb, offset, pinfo, subtree, NULL, "Log pixels");
-
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Bits per pel");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Pels width");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Pels height");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Display flags");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Display frequency");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "ICM method");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "ICM intent");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Media type");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Dither type");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Reserved");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Reserved");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Panning width");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Panning height");
-
- if (extra != 0)
- offset = prs_uint8s(tvb, offset, pinfo, subtree, extra, NULL,
- "Private");
-
- return offset;
-}
-
/*
* Relative string given by offset into the current buffer. Note that
* the offset for subsequent relstrs are against the structure start, not
@@ -2484,32 +2234,6 @@ static int dissect_PRINTER_INFO_7(tvbuff_t *tvb, int offset,
}
/*
- * DEVMODE_CTR
- */
-
-static int prs_DEVMODE_CTR(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, GList **dp_list, void **data)
-{
- proto_item *item;
- proto_tree *subtree;
- guint32 ptr = 0;
-
- item = proto_tree_add_text(tree, tvb, offset, 0, "DEVMODE_CTR");
-
- subtree = proto_item_add_subtree(item, ett_DEVMODE_CTR);
-
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Size");
-
- offset = prs_ptr(tvb, offset, pinfo, subtree, &ptr, "Devicemode");
-
- if (ptr)
- offset = prs_DEVMODE(tvb, offset, pinfo, subtree, dp_list,
- data);
-
- return offset;
-}
-
-/*
* PRINTER_DATATYPE structure
*/
@@ -3290,8 +3014,8 @@ static int SpoolssReplyOpenPrinter_q(tvbuff_t *tvb, int offset,
/* Parse packet */
- offset = prs_struct_and_referents(tvb, offset, pinfo, tree,
- prs_UNISTR2_dp, NULL, NULL);
+ offset = dissect_unistr2(
+ tvb, offset, pinfo, tree, drep, hf_spoolss_servername, NULL);
offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
hf_spoolss_printerlocal, &printerlocal);
@@ -3468,25 +3192,36 @@ static int SpoolssGetPrinter_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
static gint ett_SEC_DESC_BUF = -1;
-static int prs_SEC_DESC_BUF(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, GList **dp_list _U_,
- void **Data _U_)
+static int
+dissect_SEC_DESC_BUF(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
{
proto_item *item;
proto_tree *subtree;
guint32 len;
- item = proto_tree_add_text(tree, tvb, offset, 0, "SEC_DESC_BUF");
+ /* I think this is really a array of bytes */
+
+ item = proto_tree_add_text(tree, tvb, offset, 0,
+ "SEC_DESC_BUF");
subtree = proto_item_add_subtree(item, ett_SEC_DESC_BUF);
- offset = prs_uint32(tvb, offset, pinfo, subtree, &len, "Max length");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Undocumented");
- offset = prs_uint32(tvb, offset, pinfo, subtree, NULL, "Length");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, subtree, drep,
+ hf_spoolss_secdescbuf_maxlen, NULL);
+
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, subtree, drep,
+ hf_spoolss_secdescbuf_undoc, NULL);
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, subtree, drep,
+ hf_spoolss_secdescbuf_len, &len);
+
dissect_nt_sec_desc(tvb, offset, subtree, len);
- offset += len;
+ offset += len;
return offset;
}
@@ -3497,9 +3232,9 @@ static int prs_SEC_DESC_BUF(tvbuff_t *tvb, int offset, packet_info *pinfo,
static gint ett_SPOOL_PRINTER_INFO_LEVEL = -1;
-static int prs_SPOOL_PRINTER_INFO_LEVEL(tvbuff_t *tvb, int offset,
- packet_info *pinfo, proto_tree *tree,
- GList **dp_list, void **data _U_)
+static int
+dissect_SPOOL_PRINTER_INFO(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *tree, char *drep)
{
proto_item *item;
proto_tree *subtree;
@@ -3510,43 +3245,39 @@ static int prs_SPOOL_PRINTER_INFO_LEVEL(tvbuff_t *tvb, int offset,
subtree = proto_item_add_subtree(item, ett_SPOOL_PRINTER_INFO_LEVEL);
- offset = prs_uint32(tvb, offset, pinfo, subtree, &level, "Level");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, subtree, drep,
+ hf_spoolss_level, &level);
switch(level) {
case 3: {
- guint32 ptr;
+ guint32 devmode_ptr, secdesc_ptr;
- offset = prs_ptr(tvb, offset, pinfo, subtree, &ptr,
- "Devicemode container");
+ /* I can't seem to get this working with the correct
+ dissect_ndr_pointer() function so let's cheat and
+ dissect the pointers by hand. )-: */
- if (ptr)
- defer_ptr(dp_list, prs_DEVMODE_CTR, subtree);
-
- offset = prs_ptr(tvb, offset, pinfo, subtree, &ptr,
- "Security descriptor");
-
- if (ptr)
- defer_ptr(dp_list, prs_SEC_DESC_BUF, subtree);
-
- break;
- }
- case 2: {
- guint32 ptr;
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, subtree, drep,
+ hf_spoolss_spool_printer_info_devmode_ptr,
+ &devmode_ptr);
- offset = prs_ptr(tvb, offset, pinfo, subtree, &ptr, "Info");
+ offset = dissect_ndr_uint32(
+ tvb, offset, pinfo, subtree, drep,
+ hf_spoolss_spool_printer_info_secdesc_ptr,
+ &secdesc_ptr);
- /* Sigh - dissecting a PRINTER_INFO_2 is currently
- broken. Hopefully this will be fixed when these
- routines are converted to the NDR parsing functions
- used by all the other DCERPC dissectors. */
+ if (devmode_ptr)
+ offset = dissect_DEVMODE_CTR(
+ tvb, offset, pinfo, subtree, drep);
-#if 0
- if (ptr)
- defer_ptr(dp_list, prs_PRINTER_INFO_2, subtree);
-#endif
+ if (secdesc_ptr)
+ offset = dissect_SEC_DESC_BUF(
+ tvb, offset, pinfo, subtree, drep);
- break;
- }
+ break;
+ }
+ case 2:
default:
proto_tree_add_text(subtree, tvb, offset, 0,
"[Unknown info level %d]", level);
@@ -3584,10 +3315,9 @@ static int SpoolssSetPrinter_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO, ", level %d", level);
- offset = prs_struct_and_referents(tvb, offset, pinfo, tree,
- prs_SPOOL_PRINTER_INFO_LEVEL,
- NULL, NULL);
-
+ offset = dissect_SPOOL_PRINTER_INFO(
+ tvb, offset, pinfo, tree, drep);
+
offset = dissect_ndr_uint32(
tvb, offset, pinfo, tree, drep,
hf_spoolss_setprinter_cmd, NULL);
@@ -8064,7 +7794,44 @@ proto_register_dcerpc_spoolss(void)
{ &hf_unistr2_buffer,
{ "Buffer", "unistr2.buffer",
FT_BYTES, BASE_HEX, NULL, 0, "Buffer", HFILL }},
-
+
+ /* Setprinterdataex */
+
+ { &hf_spoolss_setprinterdataex_max_len,
+ { "Max len", "setprinterdataex.max_len",
+ FT_UINT32, BASE_DEC, NULL, 0, "Max len", HFILL }},
+
+ { &hf_spoolss_setprinterdataex_real_len,
+ { "Real len", "setprinterdataex.real_len",
+ FT_UINT32, BASE_DEC, NULL, 0, "Real len", HFILL }},
+
+ { &hf_spoolss_setprinterdataex_data,
+ { "Data", "setprinterdataex.data",
+ FT_BYTES, BASE_HEX, NULL, 0, "Data", HFILL }},
+
+ /* Spool printer info */
+
+ { &hf_spoolss_spool_printer_info_devmode_ptr,
+ { "Devmode pointer", "spoolprinterinfo.devmode_ptr",
+ FT_UINT32, BASE_HEX, NULL, 0, "Devmode pointer", HFILL }},
+
+ { &hf_spoolss_spool_printer_info_secdesc_ptr,
+ { "Secdesc pointer", "spoolprinterinfo.secdesc_ptr",
+ FT_UINT32, BASE_HEX, NULL, 0, "Secdesc pointer", HFILL }},
+
+ /* Security descriptor buffer */
+
+ { &hf_spoolss_secdescbuf_maxlen,
+ { "Max len", "secdescbuf.max_len",
+ FT_UINT32, BASE_DEC, NULL, 0, "Max len", HFILL }},
+
+ { &hf_spoolss_secdescbuf_undoc,
+ { "Undocumented", "secdescbuf.undoc",
+ FT_UINT32, BASE_DEC, NULL, 0, "Undocumented", HFILL }},
+
+ { &hf_spoolss_secdescbuf_len,
+ { "Length", "secdescbuf.len",
+ FT_UINT32, BASE_DEC, NULL, 0, "Length", HFILL }},
};
static gint *ett[] = {