2 * Routines for PROTONAME dissection
3 * Copyright 2012, Gregor Beck <gregor.beck@sernet.de>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 /* Include only as needed */
38 #include <epan/packet.h>
39 #include <epan/prefs.h>
41 #include "packet-smb.h"
42 #include "packet-smb2.h"
44 /* IF PROTO exposes code to other dissectors, then it must be exported
45 in a header file. If not, a header file is not needed at all. */
47 * #include "packet-mswsp.h"
51 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
53 /* Forward declaration we need below (if using proto_reg_handoff...
54 as a prefs callback) */
55 void proto_reg_handoff_mswsp(void);
57 /* Initialize the protocol and registered fields */
58 static int proto_mswsp
= -1;
59 static int hf_mswsp_msg
= -1;
60 static int hf_mswsp_hdr
= -1;
61 static int hf_mswsp_hdr_msg
= -1;
62 static int hf_mswsp_hdr_status
= -1;
63 static int hf_mswsp_hdr_checksum
= -1;
64 static int hf_mswsp_hdr_reserved
= -1;
65 static int hf_mswsp_msg_Connect_Version
= -1;
66 static int hf_mswsp_msg_ConnectIn_ClientIsRemote
= -1;
67 static int hf_mswsp_msg_ConnectIn_Blob1
= -1;
68 static int hf_mswsp_msg_ConnectIn_Blob2
= -1;
69 static int hf_mswsp_msg_ConnectIn_MachineName
= -1;
70 static int hf_mswsp_msg_ConnectIn_UserName
= -1;
71 static int hf_mswsp_msg_ConnectIn_PropSets_num
= -1;
72 static int hf_mswsp_msg_ConnectIn_ExtPropSets_num
= -1;
75 /* Global sample preference ("controls" display of numbers) */
76 static gboolean gPREF_HEX
= FALSE
;
77 /* Global sample port pref */
78 static guint gPORT_PREF
= 1234;
80 /* Initialize the subtree pointers */
81 static gint ett_mswsp
= -1;
82 static gint ett_mswsp_hdr
= -1;
83 static gint ett_mswsp_msg
= -1;
84 static gint ett_mswsp_pad
= -1;
86 static gint ett_mswsp_property_restriction
= -1;
87 static gint ett_CRestrictionArray
= -1;
88 static gint ett_CBaseStorageVariant
= -1;
89 static gint ett_CBaseStorageVariant_Vector
= -1;
90 static gint ett_CBaseStorageVariant_Array
= -1;
91 static gint ett_CDbColId
= -1;
92 static gint ett_GUID
= -1;
93 static gint ett_CDbProp
= -1;
94 static gint ett_CDbPropSet
= -1;
95 static gint ett_CDbPropSet_Array
= -1;
96 static gint ett_CRestriction
= -1;
97 static gint ett_CNodeRestriction
= -1;
98 static gint ett_CPropertyRestriction
= -1;
99 static gint ett_CCoercionRestriction
= -1;
100 static gint ett_CContentRestriction
= -1;
101 static gint ett_RANGEBOUNDARY
= -1;
102 static gint ett_CRangeCategSpec
= -1;
103 static gint ett_CCategSpec
= -1;
104 static gint ett_CAggregSpec
= -1;
105 static gint ett_CAggregSet
= -1;
106 static gint ett_CCategorizationSpec
= -1;
107 static gint ett_CAggregSortKey
= -1;
108 static gint ett_CSortAggregSet
= -1;
109 static gint ett_CInGroupSortAggregSet
= -1;
110 static gint ett_CInGroupSortAggregSets
= -1;
111 static gint ett_CRowsetProperties
= -1;
112 static gint ett_CFullPropSpec
= -1;
113 static gint ett_CPidMapper
= -1;
114 static gint ett_CSort
= -1;
115 static gint ett_CSortSet
= -1;
117 /******************************************************************************/
118 struct GuidPropertySet
{
122 const value_string
*id_map
;
126 static const value_string DBPROPSET_FSCIFRMWRK_EXT_IDS
[] = {
127 {0x02, "DBPROP_CI_CATALOG_NAME"},
128 {0x03, "DBPROP_CI_INCLUDE_SCOPES"},
129 {0x04, "DBPROP_CI_SCOPE_FLAGS"},
130 {0x07, "DBPROP_CI_QUERY_TYPE"},
134 static const value_string DBPROPSET_QUERYEXT_IDS
[] = {
135 {0x02, "DBPROP_USECONTENTINDEX"},
136 {0x03, "DBPROP_DEFERNONINDEXEDTRIMMING"},
137 {0x04, "DBPROP_USEEXTENDEDDBTYPES"},
138 {0x05, "DBPROP_IGNORENOISEONLYCLAUSES"},
139 {0x06, "DBPROP_GENERICOPTIONS_STRING"},
140 {0x07, "DBPROP_FIRSTROWS"},
141 {0x08, "DBPROP_DEFERCATALOGVERIFICATION"},
142 {0x0a, "DBPROP_GENERATEPARSETREE"},
143 {0x0c, "DBPROP_FREETEXTANYTERM"},
144 {0x0d, "DBPROP_FREETEXTUSESTEMMING"},
145 {0x0e, "DBPROP_IGNORESBRI"},
146 {0x10, "DBPROP_ENABLEROWSETEVENTS"},
150 static const value_string DBPROPSET_CIFRMWRKCORE_EXT_IDS
[] = {
151 {0x02, "DBPROP_MACHINE"},
152 {0x03, "DBPROP_CLIENT_CLSID"},
156 static const value_string DBPROPSET_MSIDXS_ROWSETEXT_IDS
[] = {
157 {0x02, "MSIDXSPROP_ROWSETQUERYSTATUS"},
158 {0x03, "MSIDXSPROP_COMMAND_LOCALE_STRING"},
159 {0x04, "MSIDXSPROP_QUERY_RESTRICTION"},
160 {0x05, "MSIDXSPROP_PARSE_TREE"},
161 {0x06, "MSIDXSPROP_MAX_RANK"},
162 {0x07, "MSIDXSPROP_RESULTS_FOUND"},
166 static struct GuidPropertySet GuidPropertySet
[] = {
167 {{0xa9bd1526, 0x6a80, 0x11d0, {0x8c, 0x9d, 0x00, 0x20, 0xaf, 0x1d, 0x74, 0x0e}},
168 "DBPROPSET_FSCIFRMWRK_EXT", "File system content index framework",
169 DBPROPSET_FSCIFRMWRK_EXT_IDS
},
170 {{0xa7ac77ed, 0xf8d7, 0x11ce, {0xa7, 0x98, 0x00, 0x20, 0xf8, 0x00, 0x80, 0x25}},
171 "DBPROPSET_QUERYEXT", "Query extension",
172 DBPROPSET_QUERYEXT_IDS
},
173 {{0xafafaca5, 0xb5d1, 0x11d0, {0x8c, 0x62, 0x00, 0xc0, 0x4f, 0xc2, 0xdb, 0x8d}},
174 "DBPROPSET_CIFRMWRKCORE_EXT", "Content index framework core",
175 DBPROPSET_CIFRMWRKCORE_EXT_IDS
},
176 {{0xAA6EE6B0, 0xE828, 0x11D0, {0xB2, 0x3E, 0x00, 0xAA, 0x00, 0x47, 0xFC, 0x01}},
177 "DBPROPSET_MSIDXS_ROWSETEXT", "???",
178 DBPROPSET_MSIDXS_ROWSETEXT_IDS
},
181 static struct GuidPropertySet
*GuidPropertySet_find_guid(const e_guid_t
*guid
)
184 for (i
=0; i
<array_length(GuidPropertySet
); i
++) {
185 if (guid_cmp(&GuidPropertySet
[i
].guid
, guid
) == 0) {
186 return &GuidPropertySet
[i
];
192 /******************************************************************************/
194 static int parse_padding(tvbuff_t
*tvb
, int offset
, int alignment
, proto_tree
*pad_tree
, const char *fmt
, ...)
196 if (offset
% alignment
) {
197 const int padding
= alignment
- (offset
% alignment
);
201 ti
= proto_tree_add_text_valist(pad_tree
, tvb
, offset
, padding
, fmt
, ap
);
204 proto_item_append_text(ti
, " (%d)", padding
);
207 DISSECTOR_ASSERT((offset
% alignment
) == 0);
211 static int parse_guid(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, e_guid_t
*guid
, const char *text
)
213 const char *guid_str
, *name
, *bytes
;
217 tvb_get_letohguid(tvb
, offset
, guid
);
218 guid_str
= guid_to_str(guid
);
219 name
= guids_get_guid_name(guid
);
221 ti
= proto_tree_add_text(tree
, tvb
, offset
, 16, "%s: %s {%s}", text
, name
? name
: "", guid_str
);
222 tr
= proto_item_add_subtree(ti
, ett_GUID
);
224 proto_tree_add_text(tr
, tvb
, offset
, 4, "time-low: 0x%08x", guid
->data1
);
226 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-mid: 0x%04x", guid
->data2
);
228 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-high-and-version: 0x%04x", guid
->data3
);
230 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_hi_and_reserved: 0x%02x", guid
->data4
[0]);
232 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_low: 0x%02x", guid
->data4
[1]);
234 bytes
= bytestring_to_str(&guid
->data4
[2], 6, ':');
235 proto_tree_add_text(tr
, tvb
, offset
, 6, "node: %s", bytes
);
241 /*****************************************************************************************/
242 /* 2.2.1.1 CBaseStorageVariant */
243 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
244 struct CBaseStorageVariant
*value
, const char *text
);
246 /* 2.2.1.2 CFullPropSpec */
247 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
248 struct CFullPropSpec
*v
, const char *fmt
, ...);
250 /* 2.2.1.3 CContentRestriction */
251 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
252 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
253 const char *fmt
, ...);
254 /* 2.2.1.6 CNodeRestriction */
255 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
256 struct CNodeRestriction
*v
, const char* fmt
, ...);
258 /* 2.2.1.7 CPropertyRestriction */
259 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
260 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
261 const char *fmt
, ...);
263 /* 2.2.1.8 CReuseWhere */
264 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
265 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
266 const char *fmt
, ...);
269 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
270 proto_tree
*pad_tree _U_
,
271 const char *fmt
, ...);
273 /* 2.2.1.12 CCoercionRestriction */
274 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
275 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
276 const char *fmt
, ...);
277 /* 2.2.1.16 CRestrictionArray */
278 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
279 const char *fmt
, ...);
281 /* 2.2.1.17 CRestriction */
282 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
283 struct CRestriction
*v
, const char *fmt
, ...);
285 /* 2.2.1.18 CColumnSet */
286 static int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...);
288 /* 2.2.1.20 CCategorizationSpec */
289 static int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
290 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
291 const char *fmt
, ...);
293 /* 2.2.1.21 CCategSpec */
294 static int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
295 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
296 const char *fmt
, ...);
298 /* 2.2.1.22 CRangeCategSpec */
299 static int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
300 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
301 const char *fmt
, ...);
303 /* 2.2.1.23 RANGEBOUNDARY */
304 static int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
305 proto_tree
*pad_tree
, const char *fmt
, ...);
307 /* 2.2.1.24 CAggregSet */
308 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
309 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
310 const char *fmt
, ...);
312 /* 2.2.1.25 CAggregSpec */
313 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
314 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
315 const char *fmt
, ...);
317 /* 2.2.1.26 CSortAggregSet */
318 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
319 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
320 const char *fmt
, ...);
322 /* 2.2.1.27 CAggregSortKey */
323 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
324 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
325 const char *fmt
, ...);
327 /* 2.2.1.28 CInGroupSortAggregSets */
328 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
329 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
330 const char *fmt
, ...);
332 /* 2.2.1.29 CInGroupSortAggregSet */
333 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
334 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
335 const char *fmt
, ...);
336 /* 2.2.1.30 CDbColId */
337 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
,
338 proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
);
340 /* 2.2.1.31 CDbProp */
341 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
342 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
343 const char *fmt
, ...);
345 /* 2.2.1.32 CDbPropSet */
346 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
347 proto_tree
*pad_tree
, const char *fmt
, ...);
348 /* 2.2.1.33 CPidMapper */
349 static int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
350 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
351 const char *fmt
, ...);
353 /* 2.2.1.41 CRowsetProperties */
354 static int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
355 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
356 const char *fmt
, ...);
358 /* 2.2.1.43 CSortSet */
359 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
,
360 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
361 const char *fmt
, ...);
364 2.2.1.4 CInternalPropertyRestriction
365 2.2.1.5 CNatLanguageRestriction
366 2.2.1.9 CScopeRestriction
367 2.2.1.11 CVectorRestriction
368 2.2.1.13 CRelDocRestriction
369 2.2.1.14 CProbRestriction
370 2.2.1.15 CFeedbackRestriction
371 2.2.1.19 CCategorizationSet
372 2.2.1.34 CColumnGroupArray
373 2.2.1.35 CColumnGroup
376 2.2.1.38 CRowSeekAtRatio
377 2.2.1.39 CRowSeekByBookmark
378 2.2.1.40 CRowSeekNext
380 2.2.1.44 CTableColumn
381 2.2.1.45 SERIALIZEDPROPERTYVALUE
382 2.2.1.46 CCompletionCategSp
385 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
386 proto_tree
*pad_tree _U_
,
387 const char *fmt
, ...)
389 guint32 col
, ord
, ind
, lcid
;
397 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
399 tree
= proto_item_add_subtree(item
, ett_CSort
);
401 col
= tvb_get_letohl(tvb
, offset
);
402 proto_tree_add_text(tree
, tvb
, offset
, 4, "column: %u", col
);
405 ord
= tvb_get_letohl(tvb
, offset
);
406 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", ord
);
409 ind
= tvb_get_letohl(tvb
, offset
);
410 proto_tree_add_text(tree
, tvb
, offset
, 4, "individual: %u", ind
);
413 lcid
= tvb_get_letohl(tvb
, offset
);
414 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", lcid
);
417 proto_item_set_end(item
, tvb
, offset
);
421 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
422 proto_tree
*pad_tree
,
423 const char *fmt
, ...)
433 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
435 tree
= proto_item_add_subtree(item
, ett_CSortSet
);
437 count
= tvb_get_letohl(tvb
, offset
);
438 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
441 for (i
=0; i
<count
; i
++) {
442 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_sortArray[%u]", i
);
443 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "sortArray[%u]", i
);
446 proto_item_set_end(item
, tvb
, offset
);
451 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
,
452 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
453 struct CFullPropSpec
*v
, const char *fmt
, ...)
455 static const value_string KIND
[] = {
456 {0, "PRSPEC_LPWSTR"},
457 {1, "PRSPEC_PROPID"},
461 struct GuidPropertySet
*pset
;
468 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
470 tree
= proto_item_add_subtree(item
, ett_CFullPropSpec
);
472 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingPropSet");
474 offset
= parse_guid(tvb
, offset
, tree
, &v
->guid
, "GUID");
475 pset
= GuidPropertySet_find_guid(&v
->guid
);
478 proto_item_append_text(item
, " \"%s\" (%s)", pset
->desc
, pset
->def
);
480 const char *guid_str
= guid_to_str(&v
->guid
);
481 proto_item_append_text(item
, " {%s}", guid_str
);
484 v
->kind
= tvb_get_letohl(tvb
, offset
);
485 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulKind: %s ", val_to_str(v
->kind
, KIND
, "(Unknown: 0x%x)"));
488 v
->u
.propid
= tvb_get_letohl(tvb
, offset
);
489 proto_tree_add_text(tree
, tvb
, offset
, 4, "propid: %u ", v
->u
.propid
);
492 if (v
->kind
== PRSPEC_LPWSTR
) {
493 int len
= 2*v
->u
.propid
;
494 v
->u
.name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
495 proto_tree_add_text(tree
, tvb
, offset
, len
, "name: \"%s\"", v
->u
.name
);
496 proto_item_append_text(item
, " \"%s\"", v
->u
.name
);
498 } else if (v
->kind
== PRSPEC_PROPID
) {
499 if (pset
&& pset
->id_map
) {
500 const char *str
= val_to_str(v
->u
.propid
, pset
->id_map
, "0x%08x");
501 proto_item_append_text(item
, " Id: %s", str
);
503 proto_item_append_text(item
, " 0x%08x", v
->u
.propid
);
506 proto_item_append_text(item
, "<INVALID>");
509 proto_item_set_end(item
, tvb
, offset
);
515 static const value_string PR_VALS
[] = {
523 {PRAllBits
, "PRAllBits"},
524 {PRSomeBits
, "PRSomeBits"},
530 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
531 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
532 const char *fmt
, ...)
540 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
543 tree
= proto_item_add_subtree(item
, ett_CPropertyRestriction
);
545 v
->relop
= tvb_get_letohl(tvb
, offset
);
546 str
= val_to_str(v
->relop
, PR_VALS
, "0x%04x");
547 proto_tree_add_text(tree
, tvb
, offset
, 4, "relop: %s (0x%04x)",
548 str
[0]=='\0' ? "" : str
, v
->relop
);
549 proto_item_append_text(item
, " Op: %s", str
);
552 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
554 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &v
->prval
, "prval");
556 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
558 v
->lcid
= tvb_get_letohl(tvb
, offset
);
559 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
562 proto_item_set_end(item
, tvb
, offset
);
567 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
568 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
569 const char *fmt
, ...)
576 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
579 tree
= proto_item_add_subtree(item
, ett_CCoercionRestriction
);
581 v
->value
= tvb_get_letohl(tvb
, offset
);
582 proto_tree_add_text(tree
, tvb
, offset
, 4, "value: %g", (double)v
->value
);
585 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &v
->child
, "child");
587 proto_item_set_end(item
, tvb
, offset
);
591 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
592 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
593 const char *fmt
, ...)
603 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
606 tree
= proto_item_add_subtree(item
, ett_CContentRestriction
);
608 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
610 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding1");
612 cc
= tvb_get_letohl(tvb
, offset
);
613 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
616 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
617 str
= tvb_get_unicode_string(tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
618 v
->phrase
= se_strdup(str
);
619 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
622 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding2");
624 v
->lcid
= tvb_get_letohl(tvb
, offset
);
625 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
628 v
->method
= tvb_get_letohl(tvb
, offset
);
629 proto_tree_add_text(tree
, tvb
, offset
, 4, "method: 0x%08x", v
->method
);
632 proto_item_set_end(item
, tvb
, offset
);
637 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
638 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
639 const char *fmt
, ...)
646 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
649 v
->whereId
= tvb_get_letohl(tvb
, offset
);
652 proto_item_append_text(item
, " Id: %u", v
->whereId
);
654 proto_item_set_end(item
, tvb
, offset
);
658 static value_string RT_VALS
[] = {
663 {RTContent
, "RTContent"},
664 {RTProperty
, "RTProperty"},
665 {RTProximity
, "RTProximity"},
667 {RTNatLanguage
, "RTNatLanguage"},
668 {RTScope
, "RTScope"},
669 {RTCoerce_Add
, "RTCoerce_Add"},
670 {RTCoerce_Multiply
, "RTCoerce_Multiply"},
671 {RTCoerce_Absolute
, "RTCoerce_Absolute"},
673 {RTFeedback
, "RTFeedback"},
674 {RTReldoc
, "RTReldoc"},
675 {RTReuseWhere
, "RTReuseWhere"},
676 {RTInternalProp
, "RTInternalProp"},
677 {RTPhrase
, "RTInternalProp"},
680 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
681 struct CRestriction
*v
, const char *fmt
, ...)
689 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
692 tree
= proto_item_add_subtree(item
, ett_CRestriction
);
695 v
->ulType
= tvb_get_letohl(tvb
, offset
);
696 str
= val_to_str(v
->ulType
, RT_VALS
, "0x%.8x");
697 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType: %s (0x%.8x)",
698 str
[0] == '0' ? "" : str
, v
->ulType
);
699 proto_item_append_text(item
, " Type: %s", str
);
702 v
->Weight
= tvb_get_letohl(tvb
, offset
);
703 proto_tree_add_text(tree
, tvb
, offset
, 4, "Weight: %u", v
->ulType
);
714 v
->u
.RTAnd
= ep_alloc(sizeof(struct CNodeRestriction
)); //XXX
715 offset
= parse_CNodeRestriction(tvb
, offset
, tree
, pad_tree
, v
->u
.RTAnd
, "CNodeRestriction");
720 v
->u
.RTNot
= ep_alloc(sizeof(struct CRestriction
)); //XXX
721 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
,
722 v
->u
.RTNot
, "CRestriction");
727 v
->u
.RTProperty
= ep_alloc(sizeof(struct CPropertyRestriction
)); //XXX
728 offset
= parse_CPropertyRestriction(tvb
, offset
, tree
, pad_tree
,
729 v
->u
.RTProperty
, "CPropertyRestriction");
733 case RTCoerce_Multiply
:
734 case RTCoerce_Absolute
:
736 v
->u
.RTCoerce_Add
= ep_alloc(sizeof(struct CCoercionRestriction
)); //XXX
737 offset
= parse_CCoercionRestriction(tvb
, offset
, tree
, pad_tree
,
738 v
->u
.RTCoerce_Add
, "CCoercionRestriction");
742 v
->u
.RTContent
= ep_alloc(sizeof(struct CContentRestriction
)); //XXX
743 offset
= parse_CContentRestriction(tvb
, offset
, tree
, pad_tree
,
744 v
->u
.RTContent
, "CContentRestriction");
748 v
->u
.RTReuseWhere
= ep_alloc(sizeof(struct CReuseWhere
)); //XXX
749 offset
= parse_CReuseWhere(tvb
, offset
, tree
, pad_tree
,
750 v
->u
.RTReuseWhere
, "CReuseWhere");
754 fprintf(stderr
, "CRestriciont 0x%08x not Supported\n", v
->ulType
);
755 proto_item_append_text(item
, " Not supported!");
758 proto_item_set_end(item
, tvb
, offset
);
762 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
763 const char *fmt
, ...)
765 guint8 present
, count
;
772 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
774 tree
= proto_item_add_subtree(item
, ett_CRestrictionArray
);
776 pad_tree
= tree
; //XXX
778 count
= tvb_get_guint8(tvb
, offset
);
779 proto_tree_add_text(tree
, tvb
, offset
, 1, "count: %u", count
);
782 present
= tvb_get_guint8(tvb
, offset
);
783 proto_tree_add_text(tree
, tvb
, offset
, 1, "present: %u", present
);
788 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCRestrictionPresent");
790 for (i
=0; i
<count
; i
++) {
791 struct CRestriction r
;
792 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "Restriction[%d]", i
);
795 proto_item_set_end(item
, tvb
, offset
);
799 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
800 proto_tree
*pad_tree
, struct CNodeRestriction
*v
,
801 const char *fmt
, ...)
809 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
811 tree
= proto_item_add_subtree(item
, ett_CNodeRestriction
);
813 v
->cNode
= tvb_get_letohl(tvb
, offset
);
814 proto_tree_add_text(tree
, tvb
, offset
, 4, "cNode: %u", v
->cNode
);
817 for (i
=0; i
<v
->cNode
; i
++) {
818 struct CRestriction r
;
820 // offset = parse_padding(tvb, offset, 4, tree, "padding_paNode[%u]", i); /*at begin or end of loop ????*/
821 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "paNode[%u]", i
);
822 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_paNode[%u]", i
); /*at begin or end of loop ????*/
824 // offset = parse_padding(tvb, offset, 4, pad_tree, "paNode[%u]", i); /*at begin or end of loop ????*/
827 proto_item_set_end(item
, tvb
, offset
);
832 /*****************************************************************************************/
834 static int vvalue_tvb_get0(tvbuff_t
*tvb _U_
, int offset _U_
, void *val _U_
)
839 static int vvalue_tvb_get1(tvbuff_t
*tvb
, int offset
, void *val
)
841 guint8
*ui1
= (guint8
*)val
;
842 *ui1
= tvb_get_guint8(tvb
, offset
);
846 static int vvalue_tvb_get2(tvbuff_t
*tvb
, int offset
, void *val
)
848 guint16
*ui2
= (guint16
*)val
;
849 *ui2
= tvb_get_letohs(tvb
, offset
);
853 static int vvalue_tvb_get4(tvbuff_t
*tvb
, int offset
, void *val
)
855 guint32
*ui4
= (guint32
*)val
;
856 *ui4
= tvb_get_letohl(tvb
, offset
);
860 static int vvalue_tvb_get8(tvbuff_t
*tvb
, int offset
, void *val
)
862 guint64
*ui8
= (guint64
*)val
;
863 *ui8
= tvb_get_letoh64(tvb
, offset
);
867 static int vvalue_tvb_blob(tvbuff_t
*tvb
, int offset
, void *val
)
869 struct data_blob
*blob
= (struct data_blob
*)val
;
870 guint32 len
= tvb_get_letohl(tvb
, offset
);
871 const guint8
*data
= tvb_get_ptr(tvb
, offset
+ 4, len
);
874 blob
->data
= se_memdup(data
, len
);
879 static int vvalue_tvb_bstr(tvbuff_t
*tvb
, int offset
, void *val
)
881 struct data_str
*str
= (struct data_str
*)val
;
882 guint32 len
= tvb_get_letohl(tvb
, offset
);
883 const void *ptr
= tvb_get_ptr(tvb
, offset
+ 4, len
);
885 //XXX this might be UTF-16
887 str
->str
= se_strndup(ptr
, len
);
891 static int vvalue_tvb_lpstr(tvbuff_t
*tvb
, int offset
, void *val
)
893 struct data_str
*str
= (struct data_str
*)val
;
896 str
->len
= tvb_get_letohl(tvb
, offset
);
897 str
->str
= tvb_get_seasonal_stringz(tvb
, offset
+ 4, &len
);
898 /* XXX test str->len == len */
902 static int vvalue_tvb_lpwstr(tvbuff_t
*tvb
, int offset
, void *val
)
904 struct data_str
*str
= (struct data_str
*)val
;
908 str
->len
= tvb_get_letohl(tvb
, offset
);
910 ptr
= tvb_get_ephemeral_unicode_stringz(tvb
, offset
+ 4, &len
, ENC_LITTLE_ENDIAN
);
911 str
->str
= se_strdup (ptr
);
916 static int vvalue_tvb_vector_internal(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
, int num
)
918 const int offset_in
= offset
;
919 const gboolean varsize
= (type
->size
== -1);
920 const int elsize
= varsize
? (int)sizeof(struct data_blob
) : type
->size
;
921 guint8
*data
= se_alloc(elsize
* num
);
925 val
->u
.vt_ui1
= data
;
926 DISSECTOR_ASSERT((void*)&val
->u
== ((void*)&val
->u
.vt_ui1
));
928 for (i
=0; i
<num
; i
++) {
929 len
= type
->tvb_get(tvb
, offset
, data
);
932 if (varsize
&& (offset
% 4) ) { /* at begin or end of loop ??? */
933 int padding
= 4 - (offset
% 4);
937 return offset
- offset_in
;
940 static int vvalue_tvb_vector(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
)
942 const int num
= tvb_get_letohl(tvb
, offset
);
943 return 4 + vvalue_tvb_vector_internal(tvb
, offset
+4, val
, type
, num
);
946 static void vvalue_strbuf_append_null(emem_strbuf_t
*strbuf _U_
, void *ptr _U_
)
949 static void vvalue_strbuf_append_i1(emem_strbuf_t
*strbuf
, void *ptr
)
951 gint8 i1
= *(gint8
*)ptr
;
952 ep_strbuf_append_printf(strbuf
, "%d", (int)i1
);
955 static void vvalue_strbuf_append_i2(emem_strbuf_t
*strbuf
, void *ptr
)
957 gint16 i2
= *(gint16
*)ptr
;
958 ep_strbuf_append_printf(strbuf
, "%d", (int)i2
);
961 static void vvalue_strbuf_append_i4(emem_strbuf_t
*strbuf
, void *ptr
)
963 gint32 i4
= *(gint32
*)ptr
;
964 ep_strbuf_append_printf(strbuf
, "%d", i4
);
967 static void vvalue_strbuf_append_i8(emem_strbuf_t
*strbuf
, void *ptr
)
969 gint64 i8
= *(gint64
*)ptr
;
970 ep_strbuf_append_printf(strbuf
, "%ld", i8
);
973 static void vvalue_strbuf_append_ui1(emem_strbuf_t
*strbuf
, void *ptr
)
975 guint8 ui1
= *(guint8
*)ptr
;
976 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui1
);
979 static void vvalue_strbuf_append_ui2(emem_strbuf_t
*strbuf
, void *ptr
)
981 guint16 ui2
= *(guint16
*)ptr
;
982 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui2
);
985 static void vvalue_strbuf_append_ui4(emem_strbuf_t
*strbuf
, void *ptr
)
987 guint32 ui4
= *(guint32
*)ptr
;
988 ep_strbuf_append_printf(strbuf
, "%d", ui4
);
991 static void vvalue_strbuf_append_ui8(emem_strbuf_t
*strbuf
, void *ptr
)
993 guint64 ui8
= *(guint64
*)ptr
;
994 ep_strbuf_append_printf(strbuf
, "%lu", ui8
);
997 static void vvalue_strbuf_append_r4(emem_strbuf_t
*strbuf
, void *ptr
)
999 float r4
= *(float*)ptr
;
1000 ep_strbuf_append_printf(strbuf
, "%g", (double)r4
);
1003 static void vvalue_strbuf_append_r8(emem_strbuf_t
*strbuf
, void *ptr
)
1005 double r8
= *(double*)ptr
;
1006 ep_strbuf_append_printf(strbuf
, "%g", r8
);
1009 static void vvalue_strbuf_append_str(emem_strbuf_t
*strbuf
, void *ptr
)
1011 struct data_str
*str
= (struct data_str
*)ptr
;
1012 ep_strbuf_append_printf(strbuf
, "\"%s\"", str
->str
);
1015 static void vvalue_strbuf_append_blob(emem_strbuf_t
*strbuf
, void *ptr
)
1017 struct data_blob
*blob
= (struct data_blob
*)ptr
;
1018 ep_strbuf_append_printf(strbuf
, "size: %d", (int)blob
->size
);
1021 static void vvalue_strbuf_append_bool(emem_strbuf_t
*strbuf
, void *ptr
)
1023 guint16 val
= *(guint
*)ptr
;
1026 ep_strbuf_append(strbuf
, "False");
1029 ep_strbuf_append(strbuf
, "True");
1032 ep_strbuf_append_printf(strbuf
, "Invalid (0x%4x)", val
);
1036 static void vvalue_strbuf_append_vector(emem_strbuf_t
*strbuf
, struct vt_vector val
, struct vtype
*type
)
1038 const int elsize
= (type
->size
== -1) ? (int)sizeof(struct data_blob
) : type
->size
;
1040 guint8
*data
= val
.u
.vt_ui1
;
1041 ep_strbuf_append_c(strbuf
, '[');
1042 for (i
=0; i
<val
.len
; i
++) {
1044 ep_strbuf_append_c(strbuf
, ',');
1046 type
->strbuf_append(strbuf
, data
);
1049 ep_strbuf_append_c(strbuf
, ']');
1053 static struct vtype VT_TYPE
[] = {
1054 {VT_EMPTY
, "VT_EMPTY", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
1055 {VT_NULL
, "VT_NULL", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
1056 {VT_I2
, "VT_I2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_i2
},
1057 {VT_I4
, "VT_I4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
1058 {VT_R4
, "VT_R4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_r4
},
1059 {VT_R8
, "VT_R8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
1060 {VT_CY
, "VT_CY", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1061 {VT_DATE
, "VT_DATE", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
1062 // {VT_BSTR, "VT_BSTR", -1, vvalue_tvb_bstr, vvalue_strbuf_append_str},
1063 {VT_BSTR
, "VT_BSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
1064 {VT_ERROR
, "VT_ERROR", 8, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1065 {VT_BOOL
, "VT_BOOL", 2, vvalue_tvb_get2
, vvalue_strbuf_append_bool
},
1066 {VT_VARIANT
, "VT_VARIANT", -1, NULL
, NULL
},
1067 {VT_DECIMAL
, "VT_DECIMAL", 16, NULL
, NULL
},
1068 {VT_I1
, "VT_I1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_i1
},
1069 {VT_UI1
, "VT_UI1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_ui1
},
1070 {VT_UI2
, "VT_UI2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_ui2
},
1071 {VT_UI4
, "VT_UI4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1072 {VT_I8
, "VT_I8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1073 {VT_UI8
, "VT_UI8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_ui8
},
1074 {VT_INT
, "VT_INT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
1075 {VT_UINT
, "VT_UINT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1076 {VT_LPSTR
, "VT_LPSTR", -1, vvalue_tvb_lpstr
, vvalue_strbuf_append_str
},
1077 {VT_LPWSTR
, "VT_LPWSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
1078 {VT_COMPRESSED_LPWSTR
, "VT_COMPRESSED_LPWSTR", -1, NULL
, vvalue_strbuf_append_str
},
1079 {VT_FILETIME
, "VT_FILETIME", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1080 {VT_BLOB
, "VT_BLOB", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
1081 {VT_BLOB_OBJECT
, "VT_BLOB_OBJECT", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
1082 {VT_CLSID
, "VT_CLSID", 16, NULL
, NULL
},
1085 static struct vtype
*vType_get_type(enum vType t
) {
1088 for (i
=0; i
<array_length(VT_TYPE
); i
++) {
1089 if (t
== VT_TYPE
[i
].tag
) {
1096 static char *str_CBaseStorageVariant(struct CBaseStorageVariant
*value
, gboolean print_type
)
1099 emem_strbuf_t
*strbuf
= ep_strbuf_new(NULL
);
1100 if (value
== NULL
) {
1104 if (value
->type
== NULL
) {
1109 ep_strbuf_append(strbuf
, value
->type
->str
);
1111 if (value
->vType
& 0xFF00) {
1112 ep_strbuf_append_printf(strbuf
, "[%d]", value
->vValue
.vt_vector
.len
);
1114 ep_strbuf_append(strbuf
, ": ");
1117 switch (value
->vType
& 0xFF00) {
1119 value
->type
->strbuf_append(strbuf
, &value
->vValue
);
1122 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_array
.vData
, value
->type
);
1125 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_vector
, value
->type
);
1128 ep_strbuf_append(strbuf
, "Invalid");
1134 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1135 struct CBaseStorageVariant
*value
, const char *text
)
1138 proto_item
*ti
, *ti_type
, *ti_val
;
1139 proto_tree
*tree
, *tr
;
1140 enum vType baseType
, highType
;
1142 ZERO_STRUCT(*value
);
1144 ti
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1145 tree
= proto_item_add_subtree(ti
, ett_CBaseStorageVariant
);
1147 value
->vType
= tvb_get_letohs(tvb
, offset
);
1148 value
->type
= vType_get_type(value
->vType
);
1150 ti_type
= proto_tree_add_text(tree
, tvb
, offset
, 2, "vType: %s", value
->type
->str
);
1153 value
->vData1
= tvb_get_guint8(tvb
, offset
);
1154 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData1: %d", value
->vData1
);
1157 value
->vData2
= tvb_get_guint8(tvb
, offset
);
1158 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData2: %d", value
->vData2
);
1161 baseType
= value
->vType
& 0x00FF;
1162 highType
= value
->vType
& 0xFF00;
1164 if (value
->type
== NULL
) {
1168 ti_val
= proto_tree_add_text(tree
, tvb
, offset
, 0, "vValue");
1172 len
= value
->type
->tvb_get(tvb
, offset
, &value
->vValue
.vt_single
);
1176 proto_item_append_text(ti_type
, "|VT_VECTOR");
1177 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Vector
);
1179 len
= vvalue_tvb_vector(tvb
, offset
, &value
->vValue
.vt_vector
, value
->type
);
1180 proto_tree_add_text(tr
, tvb
, offset
, 4, "num: %d", value
->vValue
.vt_vector
.len
);
1184 guint16 cDims
, fFeatures
;
1185 guint32 cbElements
, cElements
, lLbound
;
1188 proto_item_append_text(ti_type
, "|VT_ARRAY");
1189 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Array
);
1191 cDims
= tvb_get_letohs(tvb
, offset
);
1192 proto_tree_add_text(tr
, tvb
, offset
, 2, "cDims: %d", cDims
);
1195 fFeatures
= tvb_get_letohs(tvb
, offset
);
1196 proto_tree_add_text(tr
, tvb
, offset
, 2, "fFeaturess: %d", fFeatures
);
1199 cbElements
= tvb_get_letohl(tvb
, offset
);
1200 proto_tree_add_text(tr
, tvb
, offset
, 4, "cbElements: %d", cbElements
);
1202 for (i
=0; i
<cDims
; i
++) {
1203 cElements
= tvb_get_letohl(tvb
, offset
);
1204 lLbound
= tvb_get_letohl(tvb
, offset
+ 4);
1205 proto_tree_add_text(tr
, tvb
, offset
, 8, "Rgsabound[%d]: (%d:%d)", i
, cElements
, lLbound
);
1210 len
= vvalue_tvb_vector_internal(tvb
, offset
, &value
->vValue
.vt_array
.vData
, value
->type
, num
);
1215 proto_item_append_text(ti_type
, "|0x%x", highType
);
1217 proto_item_set_end(ti
, tvb
, offset
);
1218 proto_item_set_end(ti_val
, tvb
, offset
);
1220 proto_item_append_text(ti_val
, " %s", str_CBaseStorageVariant(value
, false));
1221 proto_item_append_text(ti
, " %s", str_CBaseStorageVariant(value
, true));
1226 proto_item_append_text(ti
, ": sorry, vType %02x not handled yet!", (unsigned)value
->vType
);
1232 DBKIND_GUID_NAME
= 0,
1233 DBKIND_GUID_PROPID
= 1
1236 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
)
1238 guint32 eKind
, ulId
;
1240 static const char *KIND
[] = {"DBKIND_GUID_NAME", "DBKIND_GUID_PROPID"};
1242 proto_item
*tree_item
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1243 proto_tree
*tree
= proto_item_add_subtree(tree_item
, ett_CDbColId
);
1245 eKind
= tvb_get_letohl(tvb
, offset
);
1246 proto_tree_add_text(tree
, tvb
, offset
, 4, "eKind: %s (%u)", eKind
< 2 ? KIND
[eKind
] : "???", eKind
);
1249 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingGuidAlign");
1251 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "GUID");
1253 ulId
= tvb_get_letohl(tvb
, offset
);
1254 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulId: %d", ulId
);
1257 if (eKind
== DBKIND_GUID_NAME
) {
1259 int len
= ulId
; //*2 ???
1260 name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
1261 proto_tree_add_text(tree
, tvb
, offset
, len
, "vString: \"%s\"", name
);
1262 proto_item_append_text(tree_item
, " \"%s\"", name
);
1264 } else if (eKind
== DBKIND_GUID_PROPID
) {
1265 proto_item_append_text(tree_item
, " %08x", ulId
);
1267 proto_item_append_text(tree_item
, "<INVALID>");
1270 proto_item_set_end(tree_item
, tvb
, offset
);
1275 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1276 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
1277 const char *fmt
, ...)
1279 static const value_string EMPTY_VS
[] = {{0, NULL
}};
1280 const value_string
*vs
= (propset
&& propset
->id_map
) ? propset
->id_map
: EMPTY_VS
;
1281 guint32 id
, opt
, status
;
1282 struct CBaseStorageVariant value
;
1289 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1292 tree
= proto_item_add_subtree(item
, ett_CDbProp
);
1294 id
= tvb_get_letohl(tvb
, offset
);
1295 str
= val_to_str(id
, vs
, "0x%08x");
1296 proto_tree_add_text(tree
, tvb
, offset
, 4, "Id: %s (0x%08x)", str
[0] == '0' ? "" : str
, id
);
1298 proto_item_append_text(item
, " Id: %s", str
);
1300 opt
= tvb_get_letohl(tvb
, offset
);
1301 proto_tree_add_text(tree
, tvb
, offset
, 4, "Options: %08x", opt
);
1304 status
= tvb_get_letohl(tvb
, offset
);
1305 proto_tree_add_text(tree
, tvb
, offset
, 4, "Status: %08x", status
);
1308 offset
= parse_CDbColId(tvb
, offset
, tree
, pad_tree
, "colid");
1310 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &value
, "vValue");
1312 str
= str_CBaseStorageVariant(&value
, true);
1313 proto_item_append_text(item
, " %s", str
);
1314 proto_item_set_end(item
, tvb
, offset
);
1319 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1320 proto_tree
*pad_tree
, const char *fmt
, ...)
1324 struct GuidPropertySet
*pset
;
1330 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1333 tree
= proto_item_add_subtree(item
, ett_CDbPropSet
);
1335 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "guidPropertySet");
1337 pset
= GuidPropertySet_find_guid(&guid
);
1340 proto_item_append_text(item
, " \"%s\" (%s)", pset
->desc
, pset
->def
);
1342 const char *guid_str
= guid_to_str(&guid
);
1343 proto_item_append_text(item
, " {%s}", guid_str
);
1346 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "guidPropertySet");
1348 num
= tvb_get_letohl(tvb
, offset
);
1349 proto_tree_add_text(tree
, tvb
, offset
, 4, "cProperties: %d", num
);
1351 proto_item_append_text(item
, " Num: %d", num
);
1353 for (i
= 0; i
<num
; i
++) {
1354 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "aProp[%d]", i
);
1355 offset
= parse_CDbProp(tvb
, offset
, tree
, pad_tree
, pset
, "aProp[%d]", i
);
1358 proto_item_set_end(item
, tvb
, offset
);
1362 static int parse_PropertySetArray(tvbuff_t
*tvb
, int offset
, int size_offset
,
1363 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1364 const char *fmt
, ...)
1366 const int offset_in
= offset
;
1374 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1377 tree
= proto_item_add_subtree(item
, ett_CDbPropSet_Array
);
1379 size
= tvb_get_letohl(tvb
, size_offset
);
1380 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_Blob1
, tvb
,
1381 size_offset
, 4, ENC_LITTLE_ENDIAN
);
1383 num
= tvb_get_letohl(tvb
, offset
);
1384 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_PropSets_num
, tvb
,
1385 offset
, 4, ENC_LITTLE_ENDIAN
);
1388 for (i
= 0; i
< (int)num
; i
++) {
1389 offset
= parse_CDbPropSet(tvb
, offset
, tree
, pad_tree
, "PropertySet[%d]", i
);
1392 proto_item_set_end(item
, tvb
, offset
);
1393 DISSECTOR_ASSERT(offset
- offset_in
== (int)size
);
1397 int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...)
1399 guint32 count
, v
, i
;
1405 item
= proto_tree_add_text_valist(tree
, tvb
, offset
, 0, fmt
, ap
);
1408 count
= tvb_get_letohl(tvb
, offset
);
1411 proto_item_append_text(item
, " Count %u [", count
);
1412 for (i
=0; i
<count
; i
++) {
1413 v
= tvb_get_letohl(tvb
, offset
);
1416 proto_item_append_text(item
, ",%u", v
);
1418 proto_item_append_text(item
, "%u", v
);
1421 proto_item_append_text(item
, "]");
1425 /* 2.2.1.23 RANGEBOUNDARY */
1426 int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1427 proto_tree
*pad_tree
, const char *fmt
, ...)
1430 guint8 labelPresent
;
1433 struct CBaseStorageVariant prval
;
1437 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1438 tree
= proto_item_add_subtree(item
, ett_RANGEBOUNDARY
);
1441 ulType
= tvb_get_letohl(tvb
, offset
);
1442 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType 0x%08x", ulType
);
1443 proto_item_append_text(item
, ": Type 0x%08x", ulType
);
1447 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &prval
, "prVal");
1449 labelPresent
= tvb_get_guint8(tvb
, offset
);
1450 proto_tree_add_text(tree
, tvb
, offset
, 1, "labelPresent: %s", labelPresent
? "True" : "False");
1456 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingLabelPresent");
1458 ccLabel
= tvb_get_letohl(tvb
, offset
);
1459 proto_tree_add_text(tree
, tvb
, offset
, 4, "ccLabel: %u", ccLabel
);
1462 label
= tvb_get_unicode_string(tvb
, offset
, 2*ccLabel
, ENC_LITTLE_ENDIAN
);
1463 proto_tree_add_text(tree
, tvb
, offset
, 2*ccLabel
, "Label: \"%s\"", label
);
1464 proto_item_append_text(item
, " Label: \"%s\"", label
);
1465 offset
+= 2*ccLabel
;
1468 proto_item_append_text(item
, " Val: %s", str_CBaseStorageVariant(&prval
, true));
1470 proto_item_set_end(item
, tvb
, offset
);
1475 /* 2.2.1.22 CRangeCategSpec */
1476 int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
1477 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1478 const char *fmt
, ...)
1484 guint32 lcid
, cRange
;
1487 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1488 tree
= proto_item_add_subtree(item
, ett_CRangeCategSpec
);
1491 lcid
= tvb_get_letohl(tvb
, offset
);
1492 proto_tree_add_text(tree
, tvb
, offset
, 4, "Lcid 0x%08x", lcid
);
1495 cRange
= tvb_get_letohl(tvb
, offset
);
1496 proto_tree_add_text(tree
, tvb
, offset
, 4, "cRange 0x%08x", cRange
);
1499 for (i
=0; i
<cRange
; i
++) {
1500 offset
= parse_RANGEBOUNDARY(tvb
, offset
, tree
, pad_tree
, "aRangeBegin[%u]", i
);
1504 proto_item_set_end(item
, tvb
, offset
);
1508 /* 2.2.1.21 CCategSpec */
1509 int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
1510 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1511 const char *fmt
, ...)
1520 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1521 tree
= proto_item_add_subtree(item
, ett_CCategSpec
);
1524 type
= tvb_get_letohl(tvb
, offset
);
1525 proto_tree_add_text(tree
, tvb
, offset
, 4, "Type 0x%08x", type
);
1526 proto_item_append_text(item
, " Type %u", type
);
1529 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "CSort");
1531 offset
= parse_CRangeCategSpec(tvb
, offset
, tree
, pad_tree
, "CRangeCategSpec");
1533 proto_item_set_end(item
, tvb
, offset
);
1537 /* 2.2.1.25 CAggregSpec */
1538 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
1539 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1540 const char *fmt
, ...)
1546 guint32 ccAlias
, idColumn
, ulMaxNumToReturn
, idRepresentative
;
1550 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1551 tree
= proto_item_add_subtree(item
, ett_CAggregSpec
);
1554 type
= tvb_get_guint8(tvb
, offset
);
1555 proto_tree_add_text(tree
, tvb
, offset
, 1, "type: %u", type
);
1556 proto_item_append_text(item
, "type: %u", type
);
1559 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding");
1561 ccAlias
= tvb_get_letohl(tvb
, offset
);
1562 proto_tree_add_text(tree
, tvb
, offset
, 1, "ccAlias: %u", ccAlias
);
1565 alias
= tvb_get_unicode_string(tvb
, offset
, 2*ccAlias
, ENC_LITTLE_ENDIAN
);
1566 proto_tree_add_text(tree
, tvb
, offset
, 2*ccAlias
, "Alias: %s", alias
);
1567 offset
+= 2*ccAlias
;
1569 idColumn
= tvb_get_letohl(tvb
, offset
);
1570 proto_tree_add_text(tree
, tvb
, offset
, 1, "idColumn: %u", idColumn
);
1573 ulMaxNumToReturn, idRepresentative;
1575 fprintf(stderr
, "WARNING, dont know if optional members are present!\n ");
1577 proto_item_set_end(item
, tvb
, offset
);
1581 /* 2.2.1.24 CAggregSet */
1582 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
1583 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1584 const char *fmt
, ...)
1593 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1594 tree
= proto_item_add_subtree(item
, ett_CAggregSet
);
1597 cCount
= tvb_get_letohl(tvb
, offset
);
1598 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1601 for (i
=0; i
<cCount
; i
++) {
1602 /* 2.2.1.25 CAggregSpec */
1603 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "AggregSpecs[%u]", i
);
1606 proto_item_set_end(item
, tvb
, offset
);
1610 /* 2.2.1.27 CAggregSortKey */
1611 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
1612 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1613 const char *fmt
, ...)
1622 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1623 tree
= proto_item_add_subtree(item
, ett_CAggregSortKey
);
1626 order
= tvb_get_letohl(tvb
, offset
);
1627 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", order
);
1630 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "ColumnSpec");
1632 proto_item_set_end(item
, tvb
, offset
);
1637 /* 2.2.1.26 CSortAggregSet */
1638 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
1639 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1640 const char *fmt
, ...)
1649 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1650 tree
= proto_item_add_subtree(item
, ett_CSortAggregSet
);
1653 cCount
= tvb_get_letohl(tvb
, offset
);
1654 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1657 for (i
=0; i
<cCount
; i
++) {
1658 /* 2.2.1.27 CAggregSortKey */
1659 offset
= parse_CAggregSortKey(tvb
, offset
, tree
, pad_tree
, "SortKeys[%u]", i
);
1662 proto_item_set_end(item
, tvb
, offset
);
1666 enum CInGroupSortAggregSet_type
{
1667 GroupIdDefault
= 0x00, /* The default for all ranges. */
1668 GroupIdMinValue
= 0x01, /*The first range in the parent's group.*/
1669 GroupIdNull
= 0x02, /*The last range in the parent's group.*/
1670 GroupIdValue
= 0x03,
1673 /* 2.2.1.29 CInGroupSortAggregSet */
1674 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
1675 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1676 const char *fmt
, ...)
1681 enum CInGroupSortAggregSet_type type
;
1684 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1685 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSet
);
1688 type
= tvb_get_guint8(tvb
, offset
);
1689 proto_tree_add_text(tree
, tvb
, offset
, 1, "Type: 0x%02x", (unsigned)type
);
1692 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "CInGroupSortAggregSet");
1694 if (type
== GroupIdValue
) {
1695 struct CBaseStorageVariant id
;
1696 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &id
, "inGroupId");
1699 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1701 proto_item_set_end(item
, tvb
, offset
);
1706 /* 2.2.1.28 CInGroupSortAggregSets */
1707 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
1708 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1709 const char *fmt
, ...)
1718 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1719 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSets
);
1722 cCount
= tvb_get_letohl(tvb
, offset
);
1723 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1726 for (i
=0; i
<cCount
; i
++) {
1727 /* 2.2.1.29 CInGroupSortAggregSet */
1728 offset
= parse_CInGroupSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortSets[%u]", i
);
1731 proto_item_set_end(item
, tvb
, offset
);
1735 /* 2.2.1.20 CCategorizationSpec */
1736 int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
1737 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1738 const char *fmt
, ...)
1740 guint32 cMaxResults
;
1747 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1748 tree
= proto_item_add_subtree(item
, ett_CCategorizationSpec
);
1751 /* 2.2.1.18 CColumnSet */
1752 offset
= parse_CColumnSet(tvb
, offset
, tree
, "csColumns");
1754 /* 2.2.1.21 CCategSpec */
1755 offset
= parse_CCategSpec(tvb
, offset
, tree
, pad_tree
, "Spec");
1757 /* 2.2.1.24 CAggregSet */
1758 offset
= parse_CAggregSet(tvb
, offset
, tree
, pad_tree
, "AggregSet");
1760 /* 2.2.1.26 CSortAggregSet */
1761 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1763 /* 2.2.1.28 CInGroupSortAggregSets */
1764 offset
= parse_CInGroupSortAggregSets(tvb
, offset
, tree
, pad_tree
, "InGroupSortAggregSets");
1766 cMaxResults
= tvb_get_letohl(tvb
, offset
);
1767 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", cMaxResults
);
1770 proto_item_set_end(item
, tvb
, offset
);
1774 int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
1775 proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1776 const char *fmt
, ...)
1778 guint32 opt
, maxres
, timeout
;
1785 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1786 tree
= proto_item_add_subtree(item
, ett_CRowsetProperties
);
1789 opt
= tvb_get_letohl(tvb
, offset
);
1790 proto_tree_add_text(tree
, tvb
, offset
, 4, "uBooleanOptions: 0x%08x", opt
);
1793 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMaxOpenRows (ignored)");
1796 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMemoryUsage (ignored)");
1799 maxres
= tvb_get_letohl(tvb
, offset
);
1800 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", maxres
);
1803 timeout
= tvb_get_letohl(tvb
, offset
);
1804 proto_tree_add_text(tree
, tvb
, offset
, 4, "cCmdTimeout: %u", timeout
);
1807 proto_item_set_end(item
, tvb
, offset
);
1811 int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
1812 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1813 const char *fmt
, ...)
1821 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1822 tree
= proto_item_add_subtree(item
, ett_CPidMapper
);
1825 count
= tvb_get_letohl(tvb
, offset
);
1826 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
1829 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "CPidMapper_PropSpec");
1831 for (i
=0; i
<count
; i
++) {
1832 struct CFullPropSpec v
;
1834 offset
= parse_padding(tvb
, offset
, 4, pad_tree
,
1835 "CPidMapper_PropSpec[%u]", i
); //at begin or end of loop???
1836 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
, "PropSpec[%u]", i
);
1839 proto_item_set_end(item
, tvb
, offset
);
1843 /* Code to actually dissect the packets */
1845 static int dissect_CPMConnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
1853 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
1854 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
1855 proto_item_set_text(ti
, "CPMConnect%s", in
? "In" : "Out");
1856 col_append_str(pinfo
->cinfo
, COL_INFO
, "Connect");
1858 version
= tvb_get_letohl(tvb
, offset
);
1859 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_Connect_Version
, tvb
,
1860 offset
, 4, ENC_LITTLE_ENDIAN
);
1861 if (version
& 0xffff0000) {
1862 proto_item_append_text(ti
, " 64 bit");
1864 switch (version
& 0xffff) {
1866 proto_item_append_text(ti
, " w2k8 or vista");
1869 proto_item_append_text(ti
, " XP or w2k3, with Windows Search 4.0");
1872 proto_item_append_text(ti
, " win7 or w2k8r2");
1878 guint32 blob_size1_off
, blob_size2_off
;
1879 proto_tree
*pad_tree
;
1881 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
1882 pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
1884 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_ClientIsRemote
, tvb
,
1885 offset
, 4, ENC_LITTLE_ENDIAN
);
1889 blob_size1_off
= offset
;
1892 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcbBlob2");
1895 blob_size2_off
= offset
;
1898 offset
= parse_padding(tvb
, offset
, 16, pad_tree
, "_padding");
1900 len
= tvb_unicode_strsize(tvb
, offset
);
1901 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_MachineName
, tvb
,
1902 offset
, len
, ENC_UTF_16
);
1903 /*This shouldnt be necessary, is this a bug or is there some GUI setting I've missed?*/
1904 proto_item_set_text(ti
, "Remote machine: %s",
1905 tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
1908 len
= tvb_unicode_strsize(tvb
, offset
);
1909 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_UserName
, tvb
,
1910 offset
, len
, ENC_UTF_16
);
1911 proto_item_set_text(ti
, "User: %s", tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
1914 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcPropSets");
1916 offset
= parse_PropertySetArray(tvb
, offset
, blob_size1_off
, tree
, pad_tree
, "PropSets");
1918 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingExtPropset");
1920 offset
= parse_PropertySetArray(tvb
, offset
, blob_size2_off
, tree
, pad_tree
, "ExtPropset");
1922 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "???");
1924 DISSECTOR_ASSERT(offset
== (int)tvb_length(tvb
));
1926 /* make "Padding" the last item */
1927 proto_tree_move_item(tree
, ti
, proto_tree_get_parent(pad_tree
));
1931 return tvb_length(tvb
);
1934 static int dissect_CPMDisconnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1936 col_append_str(pinfo
->cinfo
, COL_INFO
, "Disconnect");
1937 return tvb_length(tvb
);
1940 static int dissect_CPMCreateQuery(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
1946 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
1947 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
1949 proto_item_set_text(ti
, "CPMCreateQuery%s", in
? "In" : "Out");
1950 col_append_str(pinfo
->cinfo
, COL_INFO
, "CreateQuery");
1953 proto_item
*ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
1954 proto_tree
*pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
1955 guint8 CColumnSetPresent
, CRestrictionPresent
, CSortSetPresent
, CCategorizationSetPresent
;
1956 guint32 size
= tvb_get_letohl(tvb
, offset
);
1957 proto_tree_add_text(tree
, tvb
, offset
, 4, "size");
1958 proto_tree_add_text(tree
, tvb
, offset
, size
, "ALL");
1961 CColumnSetPresent
= tvb_get_guint8(tvb
, offset
);
1962 proto_tree_add_text(tree
, tvb
, offset
, 1, "CColumnSetPresent: %s", CColumnSetPresent
? "True" : "False");
1965 if (CColumnSetPresent
) {
1966 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCColumnSetPresent");
1967 offset
= parse_CColumnSet(tvb
, offset
, tree
, "CColumnSet");
1970 CRestrictionPresent
= tvb_get_guint8(tvb
, offset
);
1971 proto_tree_add_text(tree
, tvb
, offset
, 1, "CRestrictionPresent: %s", CColumnSetPresent
? "True" : "False");
1973 if (CRestrictionPresent
) {
1974 offset
= parse_CRestrictionArray(tvb
, offset
, tree
, pad_tree
, "RestrictionArray");
1977 CSortSetPresent
= tvb_get_guint8(tvb
, offset
);
1978 proto_tree_add_text(tree
, tvb
, offset
, 1, "CSortSetPresent: %s", CSortSetPresent
? "True" : "False");
1980 if (CSortSetPresent
) {
1981 offset
= parse_padding(tvb
, offset
, 4, tree
, "paddingCSortSetPresent");
1983 proto_tree_add_text(tree
, tvb
, offset
, 8, "XXX");
1986 offset
= parse_CSortSet(tvb
, offset
, tree
, pad_tree
, "SortSet");
1989 CCategorizationSetPresent
= tvb_get_guint8(tvb
, offset
);
1990 proto_tree_add_text(tree
, tvb
, offset
, 1, "CCategorizationSetPresent: %s", CCategorizationSetPresent
? "True" : "False");
1993 if (CCategorizationSetPresent
) {
1995 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCCategorizationSetPresent");
1996 /* 2.2.1.19 CCategorizationSet */
1997 count
= tvb_get_letohl(tvb
, offset
);
1998 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2000 for (i
=0; i
<count
; i
++) {
2001 offset
= parse_CCategorizationSpec(tvb
, offset
, tree
, pad_tree
, "categories[%u]", i
);
2005 offset
= parse_padding(tvb
, offset
, 4, tree
, "XXXX"); //XXX
2007 offset
= parse_CRowsetProperties(tvb
, offset
, tree
, pad_tree
, "RowSetProperties");
2009 offset
= parse_CPidMapper(tvb
, offset
, tree
, pad_tree
, "PidMapper");
2012 return tvb_length(tvb
);
2015 static int dissect_CPMFreeCursor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2017 col_append_str(pinfo
->cinfo
, COL_INFO
, "FreeCursor");
2018 return tvb_length(tvb
);
2021 static int dissect_CPMGetRows(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2023 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRows");
2024 return tvb_length(tvb
);
2027 static int dissect_CPMRatioFinished(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2029 col_append_str(pinfo
->cinfo
, COL_INFO
, "RatioFinished");
2030 return tvb_length(tvb
);
2033 static int dissect_CPMCompareBmk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2035 col_append_str(pinfo
->cinfo
, COL_INFO
, "CompareBmk");
2036 return tvb_length(tvb
);
2039 static int dissect_CPMGetApproximatePosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2041 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetApproximatePosition");
2042 return tvb_length(tvb
);
2045 static int dissect_CPMSetBindings(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2047 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetBindings");
2048 return tvb_length(tvb
);
2051 static int dissect_CPMGetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2053 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetNotify");
2054 return tvb_length(tvb
);
2057 static int dissect_CPMSendNotifyOut(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2059 col_append_str(pinfo
->cinfo
, COL_INFO
, "SendNotify");
2060 return tvb_length(tvb
);
2063 static int dissect_CPMGetQueryStatus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2065 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatus");
2066 return tvb_length(tvb
);
2069 static int dissect_CPMCiState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2071 col_append_str(pinfo
->cinfo
, COL_INFO
, "CiState");
2072 return tvb_length(tvb
);
2075 static int dissect_CPMFetchValue(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2077 col_append_str(pinfo
->cinfo
, COL_INFO
, "FetchValue");
2078 return tvb_length(tvb
);
2081 static int dissect_CPMGetQueryStatusEx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2083 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatusEx");
2084 return tvb_length(tvb
);
2087 static int dissect_CPMRestartPosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2089 col_append_str(pinfo
->cinfo
, COL_INFO
, "RestartPosition");
2090 return tvb_length(tvb
);
2093 static int dissect_CPMSetCatState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2095 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetCatState");
2096 return tvb_length(tvb
);
2099 static int dissect_CPMGetRowsetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2101 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRowsetNotify");
2102 return tvb_length(tvb
);
2105 static int dissect_CPMFindIndices(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2107 col_append_str(pinfo
->cinfo
, COL_INFO
, "FindIndices");
2108 return tvb_length(tvb
);
2111 static int dissect_CPMSetScopePrioritization(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2113 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetScopePrioritization");
2114 return tvb_length(tvb
);
2117 static int dissect_CPMGetScopeStatistics(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2119 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetScopeStatistics");
2120 return tvb_length(tvb
);
2125 dissect_mswsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gboolean in
)
2127 static const char *dbg_wait
= NULL
;
2128 static int wait_frame
= -1;
2130 proto_tree
*mswsp_tree
= NULL
;
2137 int (*fn
)(tvbuff_t
*, packet_info
*, proto_tree
*, gboolean
);
2139 if (tvb_length(tvb
) < 16) {
2143 if (dbg_wait
== NULL
) {
2144 dbg_wait
= getenv("DBG_FRAME");
2145 if (dbg_wait
== NULL
) {
2148 wait_frame
= atoi(dbg_wait
);
2152 if ((int)pinfo
->fd
->num
== wait_frame
) {
2153 static volatile gboolean wait
= 1;
2159 hdr
.msg
= tvb_get_letohl(tvb
, 0);
2163 fn
= dissect_CPMConnect
;
2166 fn
= dissect_CPMDisconnect
;
2169 fn
= dissect_CPMCreateQuery
;
2172 fn
= dissect_CPMFreeCursor
;
2175 fn
= dissect_CPMGetRows
;
2178 fn
= dissect_CPMRatioFinished
;
2181 fn
= dissect_CPMCompareBmk
;
2184 fn
= dissect_CPMGetApproximatePosition
;
2187 fn
= dissect_CPMSetBindings
;
2190 fn
= dissect_CPMGetNotify
;
2193 fn
= dissect_CPMSendNotifyOut
;
2196 fn
= dissect_CPMGetQueryStatus
;
2199 fn
= dissect_CPMCiState
;
2202 fn
= dissect_CPMFetchValue
;
2205 fn
= dissect_CPMGetQueryStatusEx
;
2208 fn
= dissect_CPMRestartPosition
;
2211 fn
= dissect_CPMSetCatState
;
2214 fn
= dissect_CPMGetRowsetNotify
;
2217 fn
= dissect_CPMFindIndices
;
2220 fn
= dissect_CPMSetScopePrioritization
;
2223 fn
= dissect_CPMGetScopeStatistics
;
2229 hdr
.status
= tvb_get_letohl(tvb
, 4);
2230 hdr
.checksum
= tvb_get_letohl(tvb
, 8);
2232 /* col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS-WSP"); */
2233 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, " WSP");
2234 /* col_clear(pinfo->cinfo, COL_INFO); */
2236 col_set_str(pinfo
->cinfo
, COL_INFO
, "WSP ");
2237 col_append_str(pinfo
->cinfo
, COL_INFO
, in
? "Request: " : "Response: ");
2240 proto_tree
*hdr_tree
;
2241 proto_item
*ti
, *hti
;
2243 ti
= proto_tree_add_item(tree
, proto_mswsp
, tvb
, 0, -1, ENC_NA
);
2244 mswsp_tree
= proto_item_add_subtree(ti
, ett_mswsp
);
2246 hti
= proto_tree_add_item(mswsp_tree
, hf_mswsp_hdr
, tvb
, 0, 16, ENC_NA
);
2247 hdr_tree
= proto_item_add_subtree(hti
, ett_mswsp_hdr
);
2249 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_msg
, tvb
,
2250 0, 4, ENC_LITTLE_ENDIAN
);
2251 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_status
,
2252 tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
2253 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_checksum
,
2254 tvb
, 8, 4, ENC_LITTLE_ENDIAN
);
2255 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_reserved
, tvb
,
2256 12, 4, ENC_LITTLE_ENDIAN
);
2259 fn(tvb
, pinfo
, mswsp_tree
, in
);
2261 /* Return the amount of data this dissector was able to dissect */
2262 return tvb_length(tvb
);
2266 /* Register the protocol with Wireshark */
2268 /* this format is require because a script is used to build the C function
2269 that calls all the protocol registration.
2273 proto_register_mswsp(void)
2275 module_t
*mswsp_module
;
2277 /* Setup list of header fields See Section 1.6.1 for details*/
2278 static const value_string msg_ids
[] = {
2279 {0x000000C8, "CPMConnect"}, /* In/Out */
2280 {0x000000C9, "CPMDisconnect"},
2281 {0x000000CA, "CPMCreateQuery"}, /* In/Out */
2282 {0x000000CB, "CPMFreeCursor"}, /* In/Out */
2283 {0x000000CC, "CPMGetRows"}, /* In/Out */
2284 {0x000000CD, "CPMRatioFinished"}, /* In/Out */
2285 {0x000000CE, "CPMCompareBmk"}, /* In/Out */
2286 {0x000000CF, "CPMGetApproximatePosition"}, /* In/Out */
2287 {0x000000D0, "CPMSetBindingsIn"},
2288 {0x000000D1, "CPMGetNotify"},
2289 {0x000000D2, "CPMSendNotifyOut"},
2290 {0x000000D7, "CPMGetQueryStatusIn"}, /* In/Out */
2291 {0x000000D9, "CPMCiStateInOut"},
2292 {0x000000E4, "CPMFetchValue"}, /* In/Out */
2293 {0x000000E7, "CPMGetQueryStatusEx"}, /* In/Out */
2294 {0x000000E8, "CPMRestartPositionIn"},
2295 {0x000000EC, "CPMSetCatStateIn"}, /* (not supported) */
2296 {0x000000F1, "CPMGetRowsetNotify"}, /* In/Out */
2297 {0x000000F2, "CPMFindIndices"}, /* In/Out */
2298 {0x000000F3, "CPMSetScopePrioritization"}, /* In/Out */
2299 {0x000000F4, "CPMGetScopeStatistics"}, /* In/Out */
2301 static hf_register_info hf
[] = {
2303 { "Header", "mswsp.hdr",
2304 FT_NONE
, BASE_NONE
, NULL
, 0,
2305 "Message header", HFILL
}
2307 { &hf_mswsp_hdr_msg
,
2308 { "Msg id", "mswsp.hdr.id",
2309 FT_UINT32
, BASE_HEX
, VALS(msg_ids
), 0,
2310 "Message id", HFILL
}
2312 { &hf_mswsp_hdr_status
,
2313 { "Status", "mswsp.hdr.status",
2314 FT_UINT32
, BASE_HEX
, NULL
, 0,
2317 { &hf_mswsp_hdr_checksum
,
2318 { "checksum", "mswsp.hdr.checksum",
2319 FT_UINT32
, BASE_HEX
, NULL
, 0,
2322 { &hf_mswsp_hdr_reserved
,
2323 { "Reserved", "mswsp.hdr.reserved",
2324 FT_UINT32
, BASE_HEX
, NULL
, 0,
2328 { "msg", "mswsp.msg",
2329 FT_NONE
, BASE_NONE
, NULL
, 0,
2332 { &hf_mswsp_msg_Connect_Version
,
2333 { "Version", "mswsp.Connect.version",
2334 FT_UINT32
, BASE_HEX
, NULL
, 0,
2337 { &hf_mswsp_msg_ConnectIn_ClientIsRemote
,
2338 { "Remote", "mswsp.ConnectIn.isRemote",
2339 FT_BOOLEAN
, BASE_HEX
, NULL
, 0,
2340 "Client is remote",HFILL
}
2342 { &hf_mswsp_msg_ConnectIn_Blob1
,
2343 { "Size", "mswsp.ConnectIn.propset.size",
2344 FT_UINT32
, BASE_DEC
, NULL
, 0,
2345 "Size of PropSet fields",HFILL
}
2347 { &hf_mswsp_msg_ConnectIn_Blob2
,
2348 { "Size", "mswsp.ConnectIn.extpropset.size",
2349 FT_UINT32
, BASE_DEC
, NULL
, 0,
2350 "Size of ExtPropSet fields",HFILL
}
2352 { &hf_mswsp_msg_ConnectIn_MachineName
,
2353 { "Remote machine", "mswsp.ConnectIn.machine",
2354 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2355 "Name of remote machine",HFILL
}
2357 { &hf_mswsp_msg_ConnectIn_UserName
,
2358 { "User", "mswsp.ConnectIn.user",
2359 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2360 "Name of remote user",HFILL
}
2362 { &hf_mswsp_msg_ConnectIn_PropSets_num
,
2363 { "Num", "mswsp.ConnectIn.propset.num",
2364 FT_UINT32
, BASE_DEC
, NULL
, 0,
2365 "Number of Property Sets", HFILL
}
2367 { &hf_mswsp_msg_ConnectIn_ExtPropSets_num
,
2368 { "Num", "mswsp.ConnectIn.extpropset.num",
2369 FT_UINT32
, BASE_DEC
, NULL
, 0,
2370 "Number of extended Property Sets", HFILL
}
2375 /* Setup protocol subtree array */
2376 static gint
*ett
[] = {
2381 &ett_mswsp_property_restriction
,
2382 &ett_CRestrictionArray
,
2383 &ett_CBaseStorageVariant
,
2384 &ett_CBaseStorageVariant_Vector
,
2385 &ett_CBaseStorageVariant_Array
,
2390 &ett_CDbPropSet_Array
,
2392 &ett_CNodeRestriction
,
2393 &ett_CPropertyRestriction
,
2394 &ett_CCoercionRestriction
,
2395 &ett_CContentRestriction
,
2397 &ett_CRangeCategSpec
,
2401 &ett_CCategorizationSpec
,
2402 &ett_CAggregSortKey
,
2403 &ett_CSortAggregSet
,
2404 &ett_CInGroupSortAggregSet
,
2405 &ett_CInGroupSortAggregSets
,
2406 &ett_CRowsetProperties
,
2415 /* Register the protocol name and description */
2416 proto_mswsp
= proto_register_protocol("Windows Search Protocol",
2419 /* Required function calls to register the header fields and subtrees used */
2420 proto_register_field_array(proto_mswsp
, hf
, array_length(hf
));
2421 proto_register_subtree_array(ett
, array_length(ett
));
2423 for (i
=0; i
<(int)array_length(GuidPropertySet
); i
++) {
2424 guids_add_guid(&GuidPropertySet
[i
].guid
, GuidPropertySet
[i
].def
);
2428 /* Register preferences module (See Section 2.6 for more on preferences) */
2429 /* (Registration of a prefs callback is not required if there are no */
2430 /* prefs-dependent registration functions (eg: a port pref). */
2431 /* See proto_reg_handoff below. */
2432 /* If a prefs callback is not needed, use NULL instead of */
2433 /* proto_reg_handoff_mswsp in the following). */
2434 mswsp_module
= prefs_register_protocol(proto_mswsp
,
2435 proto_reg_handoff_mswsp
);
2437 /* Register preferences module under preferences subtree.
2438 Use this function instead of prefs_register_protocol if you want to group
2439 preferences of several protocols under one preferences subtree.
2440 Argument subtree identifies grouping tree node name, several subnodes can be
2441 specified using slash '/' (e.g. "OSI/X.500" - protocol preferences will be
2442 accessible under Protocols->OSI->X.500-><PROTOSHORTNAME> preferences node.
2444 /* mswsp_module = prefs_register_protocol_subtree(subtree, */
2445 /* proto_mswsp, proto_reg_handoff_mswsp); */
2447 /* Register a sample preference */
2448 prefs_register_bool_preference(mswsp_module
, "show_hex",
2449 "Display numbers in Hex",
2450 "Enable to display numerical values in hexadecimal.",
2453 /* Register a sample port preference */
2454 prefs_register_uint_preference(mswsp_module
, "tcp.port", "mswsp TCP Port",
2455 " mswsp TCP port if other than the default",
2459 static int dissect_mswsp_smb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2460 smb_info_t
*si
= pinfo
->private_data
;
2461 gboolean in
= si
->request
;
2463 smb_transact_info_t
*tri
= (si
->sip
->extra_info_type
== SMB_EI_TRI
) ? si
->sip
->extra_info
: NULL
;
2464 smb_fid_info_t
*fid_info
= NULL
;
2467 fprintf(stderr
, "dissect_mswsp_smb %s frame: %d tid: %d op: %02x ",
2468 in
? "Request" : "Response",
2469 pinfo
->fd
->num
, si
->tid
, si
->cmd
);
2472 fprintf(stderr
, " extra_info_type: %d\n", si
->sip
->extra_info_type
);
2476 for (iter
= si
->ct
->GSL_fid_info
; iter
; iter
= g_slist_next(iter
)) {
2477 smb_fid_info_t
*info
= iter
->data
;
2478 if ((info
->tid
== si
->tid
) && (info
->fid
== tri
->fid
)) {
2484 if ((fid_info
->fsi
== NULL
) || (fid_info
->fsi
->filename
== NULL
)) {
2485 fprintf(stderr
, " no %s\n", fid_info
->fsi
? "filename" : "fsi");
2489 fprintf(stderr
, " file: %s\n", fid_info
->fsi
->filename
);
2491 if (strcasecmp(fid_info
->fsi
->filename
, "\\MsFteWds") != 0) {
2495 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2499 static int dissect_mswsp_smb2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2500 smb2_info_t
*si
= pinfo
->private_data
;
2501 gboolean in
= !(si
->flags
& SMB2_FLAGS_RESPONSE
);
2503 //si->tree->share_type == SMB2_SHARE_TYPE_PIPE
2504 //si->tree->connect_frame
2506 fprintf(stderr
, "dissect_mswsp %d <> %d : op %02x %s %s type: %d extra_file: %s\n",
2507 pinfo
->fd
->num
, si
->tree
? (int)si
->tree
->connect_frame
: -1,
2509 pinfo
->dcerpc_procedure_name
? pinfo
->dcerpc_procedure_name
: "<NULL>",
2510 in
? "Request" : "Response", si
->tree
? si
->tree
->share_type
: -1,
2511 si
->saved
? (si
->saved
->extra_info_type
== SMB2_EI_FILENAME
? (char*)si
->saved
->extra_info
: "<OTHER>") : "<NONE>"
2515 if (strcmp(pinfo
->dcerpc_procedure_name
, "File: MsFteWds") != 0) {
2519 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2524 /* If this dissector uses sub-dissector registration add a registration routine.
2525 This exact format is required because a script is used to find these
2526 routines and create the code that calls these routines.
2528 If this function is registered as a prefs callback (see prefs_register_protocol
2529 above) this function is also called by preferences whenever "Apply" is pressed;
2530 In that case, it should accommodate being called more than once.
2532 Simple form of proto_reg_handoff_mswsp which can be used if there are
2533 no prefs-dependent registration function calls.
2537 proto_reg_handoff_mswsp(void)
2539 heur_dissector_add("smb_transact", dissect_mswsp_smb
, proto_mswsp
);
2540 heur_dissector_add("smb2_heur_subdissectors", dissect_mswsp_smb2
, proto_mswsp
);
2545 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2550 * indent-tabs-mode: nil
2553 * vi: set shiftwidth=4 tabstop=8 expandtab:
2554 * :indentSize=4:tabSize=8:noTabs=true: