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 static int parse_padding(tvbuff_t
*tvb
, int offset
, int alignment
, proto_tree
*pad_tree
, const char *fmt
, ...)
119 if (offset
% alignment
) {
120 const int padding
= alignment
- (offset
% alignment
);
124 ti
= proto_tree_add_text_valist(pad_tree
, tvb
, offset
, padding
, fmt
, ap
);
127 proto_item_append_text(ti
, " (%d)", padding
);
130 DISSECTOR_ASSERT((offset
% alignment
) == 0);
134 static int parse_guid(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, e_guid_t
*guid
, const char *text
)
136 const char *guid_str
, *name
, *bytes
;
140 tvb_get_letohguid(tvb
, offset
, guid
);
141 guid_str
= guid_to_str(guid
);
142 name
= guids_get_guid_name(guid
);
144 ti
= proto_tree_add_text(tree
, tvb
, offset
, 16, "%s: %s {%s}", text
, name
? name
: "", guid_str
);
145 tr
= proto_item_add_subtree(ti
, ett_GUID
);
147 proto_tree_add_text(tr
, tvb
, offset
, 4, "time-low: 0x%08x", guid
->data1
);
149 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-mid: 0x%04x", guid
->data2
);
151 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-high-and-version: 0x%04x", guid
->data3
);
153 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_hi_and_reserved: 0x%02x", guid
->data4
[0]);
155 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_low: 0x%02x", guid
->data4
[1]);
157 bytes
= bytestring_to_str(&guid
->data4
[2], 6, ':');
158 proto_tree_add_text(tr
, tvb
, offset
, 6, "node: %s", bytes
);
164 /*****************************************************************************************/
165 /* 2.2.1.1 CBaseStorageVariant */
166 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
167 struct CBaseStorageVariant
*value
, const char *text
);
169 /* 2.2.1.2 CFullPropSpec */
170 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
171 struct CFullPropSpec
*v
, const char *fmt
, ...);
173 /* 2.2.1.3 CContentRestriction */
174 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
175 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
176 const char *fmt
, ...);
177 /* 2.2.1.6 CNodeRestriction */
178 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
179 struct CNodeRestriction
*v
, const char* fmt
, ...);
181 /* 2.2.1.7 CPropertyRestriction */
182 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
183 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
184 const char *fmt
, ...);
186 /* 2.2.1.8 CReuseWhere */
187 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
188 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
189 const char *fmt
, ...);
192 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
193 proto_tree
*pad_tree _U_
,
194 const char *fmt
, ...);
196 /* 2.2.1.12 CCoercionRestriction */
197 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
198 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
199 const char *fmt
, ...);
200 /* 2.2.1.16 CRestrictionArray */
201 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
202 const char *fmt
, ...);
204 /* 2.2.1.17 CRestriction */
205 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
206 struct CRestriction
*v
, const char *fmt
, ...);
208 /* 2.2.1.18 CColumnSet */
209 static int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...);
211 /* 2.2.1.20 CCategorizationSpec */
212 static int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
213 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
214 const char *fmt
, ...);
216 /* 2.2.1.21 CCategSpec */
217 static int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
218 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
219 const char *fmt
, ...);
221 /* 2.2.1.22 CRangeCategSpec */
222 static int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
223 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
224 const char *fmt
, ...);
226 /* 2.2.1.23 RANGEBOUNDARY */
227 static int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
228 proto_tree
*pad_tree
, const char *fmt
, ...);
230 /* 2.2.1.24 CAggregSet */
231 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
232 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
233 const char *fmt
, ...);
235 /* 2.2.1.25 CAggregSpec */
236 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
237 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
238 const char *fmt
, ...);
240 /* 2.2.1.26 CSortAggregSet */
241 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
242 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
243 const char *fmt
, ...);
245 /* 2.2.1.27 CAggregSortKey */
246 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
247 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
248 const char *fmt
, ...);
250 /* 2.2.1.28 CInGroupSortAggregSets */
251 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
252 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
253 const char *fmt
, ...);
255 /* 2.2.1.29 CInGroupSortAggregSet */
256 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
257 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
258 const char *fmt
, ...);
259 /* 2.2.1.30 CDbColId */
260 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
,
261 proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
);
263 /* 2.2.1.31 CDbProp */
264 struct GuidPropertySet
;
265 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
266 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
267 const char *fmt
, ...);
269 /* 2.2.1.32 CDbPropSet */
270 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
271 proto_tree
*pad_tree
, const char *fmt
, ...);
272 /* 2.2.1.33 CPidMapper */
273 static int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
274 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
275 const char *fmt
, ...);
277 /* 2.2.1.41 CRowsetProperties */
278 static int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
279 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
280 const char *fmt
, ...);
282 /* 2.2.1.43 CSortSet */
283 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
,
284 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
285 const char *fmt
, ...);
288 2.2.1.4 CInternalPropertyRestriction
289 2.2.1.5 CNatLanguageRestriction
290 2.2.1.9 CScopeRestriction
291 2.2.1.11 CVectorRestriction
292 2.2.1.13 CRelDocRestriction
293 2.2.1.14 CProbRestriction
294 2.2.1.15 CFeedbackRestriction
295 2.2.1.19 CCategorizationSet
296 2.2.1.34 CColumnGroupArray
297 2.2.1.35 CColumnGroup
300 2.2.1.38 CRowSeekAtRatio
301 2.2.1.39 CRowSeekByBookmark
302 2.2.1.40 CRowSeekNext
304 2.2.1.44 CTableColumn
305 2.2.1.45 SERIALIZEDPROPERTYVALUE
306 2.2.1.46 CCompletionCategSp
309 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
310 proto_tree
*pad_tree _U_
,
311 const char *fmt
, ...)
313 guint32 col
, ord
, ind
, lcid
;
321 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
323 tree
= proto_item_add_subtree(item
, ett_CSort
);
325 col
= tvb_get_letohl(tvb
, offset
);
326 proto_tree_add_text(tree
, tvb
, offset
, 4, "column: %u", col
);
329 ord
= tvb_get_letohl(tvb
, offset
);
330 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", ord
);
333 ind
= tvb_get_letohl(tvb
, offset
);
334 proto_tree_add_text(tree
, tvb
, offset
, 4, "individual: %u", ind
);
337 lcid
= tvb_get_letohl(tvb
, offset
);
338 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", lcid
);
341 proto_item_set_end(item
, tvb
, offset
);
345 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
346 proto_tree
*pad_tree
,
347 const char *fmt
, ...)
357 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
359 tree
= proto_item_add_subtree(item
, ett_CSortSet
);
361 count
= tvb_get_letohl(tvb
, offset
);
362 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
365 for (i
=0; i
<count
; i
++) {
366 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_sortArray[%u]", i
);
367 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "sortArray[%u]", i
);
370 proto_item_set_end(item
, tvb
, offset
);
375 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
,
376 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
377 struct CFullPropSpec
*v
, const char *fmt
, ...)
379 static const value_string KIND
[] = {
380 {0, "PRSPEC_LPWSTR"},
381 {1, "PRSPEC_PROPID"},
385 const char *guid_str
;
391 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
393 tree
= proto_item_add_subtree(item
, ett_CFullPropSpec
);
395 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingPropSet");
397 offset
= parse_guid(tvb
, offset
, tree
, &v
->guid
, "GUID");
398 guid_str
= guids_resolve_guid_to_str(&v
->guid
);
399 proto_item_append_text(item
, " {%s}", guid_str
);
401 v
->kind
= tvb_get_letohl(tvb
, offset
);
402 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulKind: %s ", val_to_str(v
->kind
, KIND
, "(Unknown: 0x%x)"));
405 v
->u
.propid
= tvb_get_letohl(tvb
, offset
);
406 proto_tree_add_text(tree
, tvb
, offset
, 4, "propid: %u ", v
->u
.propid
);
409 if (v
->kind
== PRSPEC_LPWSTR
) {
410 int len
= 2*v
->u
.propid
;
411 v
->u
.name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
412 proto_tree_add_text(tree
, tvb
, offset
, len
, "name: \"%s\"", v
->u
.name
);
413 proto_item_append_text(item
, " \"%s\"", v
->u
.name
);
415 } else if (v
->kind
== PRSPEC_PROPID
) {
416 proto_item_append_text(item
, " 0x%08x", v
->u
.propid
);
418 proto_item_append_text(item
, "<INVALID>");
421 proto_item_set_end(item
, tvb
, offset
);
427 static const value_string PR_VALS
[] = {
435 {PRAllBits
, "PRAllBits"},
436 {PRSomeBits
, "PRSomeBits"},
442 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
443 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
444 const char *fmt
, ...)
452 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
455 tree
= proto_item_add_subtree(item
, ett_CPropertyRestriction
);
457 v
->relop
= tvb_get_letohl(tvb
, offset
);
458 str
= val_to_str(v
->relop
, PR_VALS
, "0x%04x");
459 proto_tree_add_text(tree
, tvb
, offset
, 4, "relop: %s (0x%04x)",
460 str
[0]=='\0' ? "" : str
, v
->relop
);
461 proto_item_append_text(item
, " Op: %s", str
);
464 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
466 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &v
->prval
, "prval");
468 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
470 v
->lcid
= tvb_get_letohl(tvb
, offset
);
471 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
474 proto_item_set_end(item
, tvb
, offset
);
479 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
480 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
481 const char *fmt
, ...)
488 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
491 tree
= proto_item_add_subtree(item
, ett_CCoercionRestriction
);
493 v
->value
= tvb_get_letohl(tvb
, offset
);
494 proto_tree_add_text(tree
, tvb
, offset
, 4, "value: %g", (double)v
->value
);
497 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &v
->child
, "child");
499 proto_item_set_end(item
, tvb
, offset
);
503 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
504 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
505 const char *fmt
, ...)
515 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
518 tree
= proto_item_add_subtree(item
, ett_CContentRestriction
);
520 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
522 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding1");
524 cc
= tvb_get_letohl(tvb
, offset
);
525 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
528 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
529 str
= tvb_get_unicode_string(tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
530 v
->phrase
= se_strdup(str
);
531 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
534 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding2");
536 v
->lcid
= tvb_get_letohl(tvb
, offset
);
537 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
540 v
->method
= tvb_get_letohl(tvb
, offset
);
541 proto_tree_add_text(tree
, tvb
, offset
, 4, "method: 0x%08x", v
->method
);
544 proto_item_set_end(item
, tvb
, offset
);
549 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
550 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
551 const char *fmt
, ...)
558 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
561 v
->whereId
= tvb_get_letohl(tvb
, offset
);
564 proto_item_append_text(item
, " Id: %u", v
->whereId
);
566 proto_item_set_end(item
, tvb
, offset
);
570 static value_string RT_VALS
[] = {
575 {RTContent
, "RTContent"},
576 {RTProperty
, "RTProperty"},
577 {RTProximity
, "RTProximity"},
579 {RTNatLanguage
, "RTNatLanguage"},
580 {RTScope
, "RTScope"},
581 {RTCoerce_Add
, "RTCoerce_Add"},
582 {RTCoerce_Multiply
, "RTCoerce_Multiply"},
583 {RTCoerce_Absolute
, "RTCoerce_Absolute"},
585 {RTFeedback
, "RTFeedback"},
586 {RTReldoc
, "RTReldoc"},
587 {RTReuseWhere
, "RTReuseWhere"},
588 {RTInternalProp
, "RTInternalProp"},
589 {RTPhrase
, "RTInternalProp"},
592 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
593 struct CRestriction
*v
, const char *fmt
, ...)
601 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
604 tree
= proto_item_add_subtree(item
, ett_CRestriction
);
607 v
->ulType
= tvb_get_letohl(tvb
, offset
);
608 str
= val_to_str(v
->ulType
, RT_VALS
, "0x%.8x");
609 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType: %s (0x%.8x)",
610 str
[0] == '0' ? "" : str
, v
->ulType
);
611 proto_item_append_text(item
, " Type: %s", str
);
614 v
->Weight
= tvb_get_letohl(tvb
, offset
);
615 proto_tree_add_text(tree
, tvb
, offset
, 4, "Weight: %u", v
->ulType
);
626 v
->u
.RTAnd
= ep_alloc(sizeof(struct CNodeRestriction
)); //XXX
627 offset
= parse_CNodeRestriction(tvb
, offset
, tree
, pad_tree
, v
->u
.RTAnd
, "CNodeRestriction");
632 v
->u
.RTNot
= ep_alloc(sizeof(struct CRestriction
)); //XXX
633 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
,
634 v
->u
.RTNot
, "CRestriction");
639 v
->u
.RTProperty
= ep_alloc(sizeof(struct CPropertyRestriction
)); //XXX
640 offset
= parse_CPropertyRestriction(tvb
, offset
, tree
, pad_tree
,
641 v
->u
.RTProperty
, "CPropertyRestriction");
645 case RTCoerce_Multiply
:
646 case RTCoerce_Absolute
:
648 v
->u
.RTCoerce_Add
= ep_alloc(sizeof(struct CCoercionRestriction
)); //XXX
649 offset
= parse_CCoercionRestriction(tvb
, offset
, tree
, pad_tree
,
650 v
->u
.RTCoerce_Add
, "CCoercionRestriction");
654 v
->u
.RTContent
= ep_alloc(sizeof(struct CContentRestriction
)); //XXX
655 offset
= parse_CContentRestriction(tvb
, offset
, tree
, pad_tree
,
656 v
->u
.RTContent
, "CContentRestriction");
660 v
->u
.RTReuseWhere
= ep_alloc(sizeof(struct CReuseWhere
)); //XXX
661 offset
= parse_CReuseWhere(tvb
, offset
, tree
, pad_tree
,
662 v
->u
.RTReuseWhere
, "CReuseWhere");
666 fprintf(stderr
, "CRestriciont 0x%08x not Supported\n", v
->ulType
);
667 proto_item_append_text(item
, " Not supported!");
670 proto_item_set_end(item
, tvb
, offset
);
674 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
675 const char *fmt
, ...)
677 guint8 present
, count
;
684 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
686 tree
= proto_item_add_subtree(item
, ett_CRestrictionArray
);
688 pad_tree
= tree
; //XXX
690 count
= tvb_get_guint8(tvb
, offset
);
691 proto_tree_add_text(tree
, tvb
, offset
, 1, "count: %u", count
);
694 present
= tvb_get_guint8(tvb
, offset
);
695 proto_tree_add_text(tree
, tvb
, offset
, 1, "present: %u", present
);
700 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCRestrictionPresent");
702 for (i
=0; i
<count
; i
++) {
703 struct CRestriction r
;
704 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "Restriction[%d]", i
);
707 proto_item_set_end(item
, tvb
, offset
);
711 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
712 proto_tree
*pad_tree
, struct CNodeRestriction
*v
,
713 const char *fmt
, ...)
721 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
723 tree
= proto_item_add_subtree(item
, ett_CNodeRestriction
);
725 v
->cNode
= tvb_get_letohl(tvb
, offset
);
726 proto_tree_add_text(tree
, tvb
, offset
, 4, "cNode: %u", v
->cNode
);
729 for (i
=0; i
<v
->cNode
; i
++) {
730 struct CRestriction r
;
732 // offset = parse_padding(tvb, offset, 4, tree, "padding_paNode[%u]", i); /*at begin or end of loop ????*/
733 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "paNode[%u]", i
);
734 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_paNode[%u]", i
); /*at begin or end of loop ????*/
736 // offset = parse_padding(tvb, offset, 4, pad_tree, "paNode[%u]", i); /*at begin or end of loop ????*/
739 proto_item_set_end(item
, tvb
, offset
);
744 /*****************************************************************************************/
746 static int vvalue_tvb_get0(tvbuff_t
*tvb _U_
, int offset _U_
, void *val _U_
)
751 static int vvalue_tvb_get1(tvbuff_t
*tvb
, int offset
, void *val
)
753 guint8
*ui1
= (guint8
*)val
;
754 *ui1
= tvb_get_guint8(tvb
, offset
);
758 static int vvalue_tvb_get2(tvbuff_t
*tvb
, int offset
, void *val
)
760 guint16
*ui2
= (guint16
*)val
;
761 *ui2
= tvb_get_letohs(tvb
, offset
);
765 static int vvalue_tvb_get4(tvbuff_t
*tvb
, int offset
, void *val
)
767 guint32
*ui4
= (guint32
*)val
;
768 *ui4
= tvb_get_letohl(tvb
, offset
);
772 static int vvalue_tvb_get8(tvbuff_t
*tvb
, int offset
, void *val
)
774 guint64
*ui8
= (guint64
*)val
;
775 *ui8
= tvb_get_letoh64(tvb
, offset
);
779 static int vvalue_tvb_blob(tvbuff_t
*tvb
, int offset
, void *val
)
781 struct data_blob
*blob
= (struct data_blob
*)val
;
782 guint32 len
= tvb_get_letohl(tvb
, offset
);
783 const guint8
*data
= tvb_get_ptr(tvb
, offset
+ 4, len
);
786 blob
->data
= se_memdup(data
, len
);
791 static int vvalue_tvb_bstr(tvbuff_t
*tvb
, int offset
, void *val
)
793 struct data_str
*str
= (struct data_str
*)val
;
794 guint32 len
= tvb_get_letohl(tvb
, offset
);
795 const void *ptr
= tvb_get_ptr(tvb
, offset
+ 4, len
);
797 //XXX this might be UTF-16
799 str
->str
= se_strndup(ptr
, len
);
803 static int vvalue_tvb_lpstr(tvbuff_t
*tvb
, int offset
, void *val
)
805 struct data_str
*str
= (struct data_str
*)val
;
808 str
->len
= tvb_get_letohl(tvb
, offset
);
809 str
->str
= tvb_get_seasonal_stringz(tvb
, offset
+ 4, &len
);
810 /* XXX test str->len == len */
814 static int vvalue_tvb_lpwstr(tvbuff_t
*tvb
, int offset
, void *val
)
816 struct data_str
*str
= (struct data_str
*)val
;
820 str
->len
= tvb_get_letohl(tvb
, offset
);
822 ptr
= tvb_get_ephemeral_unicode_stringz(tvb
, offset
+ 4, &len
, ENC_LITTLE_ENDIAN
);
823 str
->str
= se_strdup (ptr
);
828 static int vvalue_tvb_vector_internal(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
, int num
)
830 const int offset_in
= offset
;
831 const gboolean varsize
= (type
->size
== -1);
832 const int elsize
= varsize
? (int)sizeof(struct data_blob
) : type
->size
;
833 guint8
*data
= se_alloc(elsize
* num
);
837 val
->u
.vt_ui1
= data
;
838 DISSECTOR_ASSERT((void*)&val
->u
== ((void*)&val
->u
.vt_ui1
));
840 for (i
=0; i
<num
; i
++) {
841 len
= type
->tvb_get(tvb
, offset
, data
);
844 if (varsize
&& (offset
% 4) ) { /* at begin or end of loop ??? */
845 int padding
= 4 - (offset
% 4);
849 return offset
- offset_in
;
852 static int vvalue_tvb_vector(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
)
854 const int num
= tvb_get_letohl(tvb
, offset
);
855 return 4 + vvalue_tvb_vector_internal(tvb
, offset
+4, val
, type
, num
);
858 static void vvalue_strbuf_append_null(emem_strbuf_t
*strbuf _U_
, void *ptr _U_
)
861 static void vvalue_strbuf_append_i1(emem_strbuf_t
*strbuf
, void *ptr
)
863 gint8 i1
= *(gint8
*)ptr
;
864 ep_strbuf_append_printf(strbuf
, "%d", (int)i1
);
867 static void vvalue_strbuf_append_i2(emem_strbuf_t
*strbuf
, void *ptr
)
869 gint16 i2
= *(gint16
*)ptr
;
870 ep_strbuf_append_printf(strbuf
, "%d", (int)i2
);
873 static void vvalue_strbuf_append_i4(emem_strbuf_t
*strbuf
, void *ptr
)
875 gint32 i4
= *(gint32
*)ptr
;
876 ep_strbuf_append_printf(strbuf
, "%d", i4
);
879 static void vvalue_strbuf_append_i8(emem_strbuf_t
*strbuf
, void *ptr
)
881 gint64 i8
= *(gint64
*)ptr
;
882 ep_strbuf_append_printf(strbuf
, "%ld", i8
);
885 static void vvalue_strbuf_append_ui1(emem_strbuf_t
*strbuf
, void *ptr
)
887 guint8 ui1
= *(guint8
*)ptr
;
888 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui1
);
891 static void vvalue_strbuf_append_ui2(emem_strbuf_t
*strbuf
, void *ptr
)
893 guint16 ui2
= *(guint16
*)ptr
;
894 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui2
);
897 static void vvalue_strbuf_append_ui4(emem_strbuf_t
*strbuf
, void *ptr
)
899 guint32 ui4
= *(guint32
*)ptr
;
900 ep_strbuf_append_printf(strbuf
, "%d", ui4
);
903 static void vvalue_strbuf_append_ui8(emem_strbuf_t
*strbuf
, void *ptr
)
905 guint64 ui8
= *(guint64
*)ptr
;
906 ep_strbuf_append_printf(strbuf
, "%lu", ui8
);
909 static void vvalue_strbuf_append_r4(emem_strbuf_t
*strbuf
, void *ptr
)
911 float r4
= *(float*)ptr
;
912 ep_strbuf_append_printf(strbuf
, "%g", (double)r4
);
915 static void vvalue_strbuf_append_r8(emem_strbuf_t
*strbuf
, void *ptr
)
917 double r8
= *(double*)ptr
;
918 ep_strbuf_append_printf(strbuf
, "%g", r8
);
921 static void vvalue_strbuf_append_str(emem_strbuf_t
*strbuf
, void *ptr
)
923 struct data_str
*str
= (struct data_str
*)ptr
;
924 ep_strbuf_append_printf(strbuf
, "\"%s\"", str
->str
);
927 static void vvalue_strbuf_append_blob(emem_strbuf_t
*strbuf
, void *ptr
)
929 struct data_blob
*blob
= (struct data_blob
*)ptr
;
930 ep_strbuf_append_printf(strbuf
, "size: %d", (int)blob
->size
);
933 static void vvalue_strbuf_append_bool(emem_strbuf_t
*strbuf
, void *ptr
)
935 guint16 val
= *(guint
*)ptr
;
938 ep_strbuf_append(strbuf
, "False");
941 ep_strbuf_append(strbuf
, "True");
944 ep_strbuf_append_printf(strbuf
, "Invalid (0x%4x)", val
);
948 static void vvalue_strbuf_append_vector(emem_strbuf_t
*strbuf
, struct vt_vector val
, struct vtype
*type
)
950 const int elsize
= (type
->size
== -1) ? (int)sizeof(struct data_blob
) : type
->size
;
952 guint8
*data
= val
.u
.vt_ui1
;
953 ep_strbuf_append_c(strbuf
, '[');
954 for (i
=0; i
<val
.len
; i
++) {
956 ep_strbuf_append_c(strbuf
, ',');
958 type
->strbuf_append(strbuf
, data
);
961 ep_strbuf_append_c(strbuf
, ']');
965 static struct vtype VT_TYPE
[] = {
966 {VT_EMPTY
, "VT_EMPTY", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
967 {VT_NULL
, "VT_NULL", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
968 {VT_I2
, "VT_I2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_i2
},
969 {VT_I4
, "VT_I4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
970 {VT_R4
, "VT_R4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_r4
},
971 {VT_R8
, "VT_R8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
972 {VT_CY
, "VT_CY", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
973 {VT_DATE
, "VT_DATE", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
974 // {VT_BSTR, "VT_BSTR", -1, vvalue_tvb_bstr, vvalue_strbuf_append_str},
975 {VT_BSTR
, "VT_BSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
976 {VT_ERROR
, "VT_ERROR", 8, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
977 {VT_BOOL
, "VT_BOOL", 2, vvalue_tvb_get2
, vvalue_strbuf_append_bool
},
978 {VT_VARIANT
, "VT_VARIANT", -1, NULL
, NULL
},
979 {VT_DECIMAL
, "VT_DECIMAL", 16, NULL
, NULL
},
980 {VT_I1
, "VT_I1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_i1
},
981 {VT_UI1
, "VT_UI1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_ui1
},
982 {VT_UI2
, "VT_UI2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_ui2
},
983 {VT_UI4
, "VT_UI4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
984 {VT_I8
, "VT_I8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
985 {VT_UI8
, "VT_UI8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_ui8
},
986 {VT_INT
, "VT_INT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
987 {VT_UINT
, "VT_UINT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
988 {VT_LPSTR
, "VT_LPSTR", -1, vvalue_tvb_lpstr
, vvalue_strbuf_append_str
},
989 {VT_LPWSTR
, "VT_LPWSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
990 {VT_COMPRESSED_LPWSTR
, "VT_COMPRESSED_LPWSTR", -1, NULL
, vvalue_strbuf_append_str
},
991 {VT_FILETIME
, "VT_FILETIME", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
992 {VT_BLOB
, "VT_BLOB", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
993 {VT_BLOB_OBJECT
, "VT_BLOB_OBJECT", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
994 {VT_CLSID
, "VT_CLSID", 16, NULL
, NULL
},
997 static struct vtype
*vType_get_type(enum vType t
) {
1000 for (i
=0; i
<array_length(VT_TYPE
); i
++) {
1001 if (t
== VT_TYPE
[i
].tag
) {
1008 static char *str_CBaseStorageVariant(struct CBaseStorageVariant
*value
, gboolean print_type
)
1011 emem_strbuf_t
*strbuf
= ep_strbuf_new(NULL
);
1012 if (value
== NULL
) {
1016 if (value
->type
== NULL
) {
1021 ep_strbuf_append(strbuf
, value
->type
->str
);
1023 if (value
->vType
& 0xFF00) {
1024 ep_strbuf_append_printf(strbuf
, "[%d]", value
->vValue
.vt_vector
.len
);
1026 ep_strbuf_append(strbuf
, ": ");
1029 switch (value
->vType
& 0xFF00) {
1031 value
->type
->strbuf_append(strbuf
, &value
->vValue
);
1034 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_array
.vData
, value
->type
);
1037 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_vector
, value
->type
);
1040 ep_strbuf_append(strbuf
, "Invalid");
1046 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1047 struct CBaseStorageVariant
*value
, const char *text
)
1050 proto_item
*ti
, *ti_type
, *ti_val
;
1051 proto_tree
*tree
, *tr
;
1052 enum vType baseType
, highType
;
1054 ZERO_STRUCT(*value
);
1056 ti
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1057 tree
= proto_item_add_subtree(ti
, ett_CBaseStorageVariant
);
1059 value
->vType
= tvb_get_letohs(tvb
, offset
);
1060 value
->type
= vType_get_type(value
->vType
);
1062 ti_type
= proto_tree_add_text(tree
, tvb
, offset
, 2, "vType: %s", value
->type
->str
);
1065 value
->vData1
= tvb_get_guint8(tvb
, offset
);
1066 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData1: %d", value
->vData1
);
1069 value
->vData2
= tvb_get_guint8(tvb
, offset
);
1070 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData2: %d", value
->vData2
);
1073 baseType
= value
->vType
& 0x00FF;
1074 highType
= value
->vType
& 0xFF00;
1076 if (value
->type
== NULL
) {
1080 ti_val
= proto_tree_add_text(tree
, tvb
, offset
, 0, "vValue");
1084 len
= value
->type
->tvb_get(tvb
, offset
, &value
->vValue
.vt_single
);
1088 proto_item_append_text(ti_type
, "|VT_VECTOR");
1089 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Vector
);
1091 len
= vvalue_tvb_vector(tvb
, offset
, &value
->vValue
.vt_vector
, value
->type
);
1092 proto_tree_add_text(tr
, tvb
, offset
, 4, "num: %d", value
->vValue
.vt_vector
.len
);
1096 guint16 cDims
, fFeatures
;
1097 guint32 cbElements
, cElements
, lLbound
;
1100 proto_item_append_text(ti_type
, "|VT_ARRAY");
1101 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Array
);
1103 cDims
= tvb_get_letohs(tvb
, offset
);
1104 proto_tree_add_text(tr
, tvb
, offset
, 2, "cDims: %d", cDims
);
1107 fFeatures
= tvb_get_letohs(tvb
, offset
);
1108 proto_tree_add_text(tr
, tvb
, offset
, 2, "fFeaturess: %d", fFeatures
);
1111 cbElements
= tvb_get_letohl(tvb
, offset
);
1112 proto_tree_add_text(tr
, tvb
, offset
, 4, "cbElements: %d", cbElements
);
1114 for (i
=0; i
<cDims
; i
++) {
1115 cElements
= tvb_get_letohl(tvb
, offset
);
1116 lLbound
= tvb_get_letohl(tvb
, offset
+ 4);
1117 proto_tree_add_text(tr
, tvb
, offset
, 8, "Rgsabound[%d]: (%d:%d)", i
, cElements
, lLbound
);
1122 len
= vvalue_tvb_vector_internal(tvb
, offset
, &value
->vValue
.vt_array
.vData
, value
->type
, num
);
1127 proto_item_append_text(ti_type
, "|0x%x", highType
);
1129 proto_item_set_end(ti
, tvb
, offset
);
1130 proto_item_set_end(ti_val
, tvb
, offset
);
1132 proto_item_append_text(ti_val
, " %s", str_CBaseStorageVariant(value
, false));
1133 proto_item_append_text(ti
, " %s", str_CBaseStorageVariant(value
, true));
1138 proto_item_append_text(ti
, ": sorry, vType %02x not handled yet!", (unsigned)value
->vType
);
1144 DBKIND_GUID_NAME
= 0,
1145 DBKIND_GUID_PROPID
= 1
1148 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
)
1150 guint32 eKind
, ulId
;
1152 static const char *KIND
[] = {"DBKIND_GUID_NAME", "DBKIND_GUID_PROPID"};
1154 proto_item
*tree_item
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1155 proto_tree
*tree
= proto_item_add_subtree(tree_item
, ett_CDbColId
);
1157 eKind
= tvb_get_letohl(tvb
, offset
);
1158 proto_tree_add_text(tree
, tvb
, offset
, 4, "eKind: %s (%u)", eKind
< 2 ? KIND
[eKind
] : "???", eKind
);
1161 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingGuidAlign");
1163 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "GUID");
1165 ulId
= tvb_get_letohl(tvb
, offset
);
1166 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulId: %d", ulId
);
1169 if (eKind
== DBKIND_GUID_NAME
) {
1171 int len
= ulId
; //*2 ???
1172 name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
1173 proto_tree_add_text(tree
, tvb
, offset
, len
, "vString: \"%s\"", name
);
1174 proto_item_append_text(tree_item
, " \"%s\"", name
);
1176 } else if (eKind
== DBKIND_GUID_PROPID
) {
1177 proto_item_append_text(tree_item
, " %08x", ulId
);
1179 proto_item_append_text(tree_item
, "<INVALID>");
1182 proto_item_set_end(tree_item
, tvb
, offset
);
1187 struct GuidPropertySet
{
1191 const value_string
*id_map
;
1194 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1195 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
1196 const char *fmt
, ...)
1198 static const value_string EMPTY_VS
[] = {{0, NULL
}};
1199 const value_string
*vs
= (propset
&& propset
->id_map
) ? propset
->id_map
: EMPTY_VS
;
1200 guint32 id
, opt
, status
;
1201 struct CBaseStorageVariant value
;
1208 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1211 tree
= proto_item_add_subtree(item
, ett_CDbProp
);
1213 id
= tvb_get_letohl(tvb
, offset
);
1214 str
= val_to_str(id
, vs
, "0x%08x");
1215 proto_tree_add_text(tree
, tvb
, offset
, 4, "Id: %s (0x%08x)", str
[0] == '0' ? "" : str
, id
);
1217 proto_item_append_text(item
, " Id: %s", str
);
1219 opt
= tvb_get_letohl(tvb
, offset
);
1220 proto_tree_add_text(tree
, tvb
, offset
, 4, "Options: %08x", opt
);
1223 status
= tvb_get_letohl(tvb
, offset
);
1224 proto_tree_add_text(tree
, tvb
, offset
, 4, "Status: %08x", status
);
1227 offset
= parse_CDbColId(tvb
, offset
, tree
, pad_tree
, "colid");
1229 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &value
, "vValue");
1231 str
= str_CBaseStorageVariant(&value
, true);
1232 proto_item_append_text(item
, " %s", str
);
1233 proto_item_set_end(item
, tvb
, offset
);
1239 static const value_string DBPROPSET_FSCIFRMWRK_EXT_IDS
[] = {
1240 {0x02, "DBPROP_CI_CATALOG_NAME"},
1241 {0x03, "DBPROP_CI_INCLUDE_SCOPES"},
1242 {0x04, "DBPROP_CI_SCOPE_FLAGS"},
1243 {0x07, "DBPROP_CI_QUERY_TYPE"},
1247 static const value_string DBPROPSET_QUERYEXT_IDS
[] = {
1248 {0x02, "DBPROP_USECONTENTINDEX"},
1249 {0x03, "DBPROP_DEFERNONINDEXEDTRIMMING"},
1250 {0x04, "DBPROP_USEEXTENDEDDBTYPES"},
1251 {0x05, "DBPROP_IGNORENOISEONLYCLAUSES"},
1252 {0x06, "DBPROP_GENERICOPTIONS_STRING"},
1253 {0x07, "DBPROP_FIRSTROWS"},
1254 {0x08, "DBPROP_DEFERCATALOGVERIFICATION"},
1255 {0x0a, "DBPROP_GENERATEPARSETREE"},
1256 {0x0c, "DBPROP_FREETEXTANYTERM"},
1257 {0x0d, "DBPROP_FREETEXTUSESTEMMING"},
1258 {0x0e, "DBPROP_IGNORESBRI"},
1259 {0x10, "DBPROP_ENABLEROWSETEVENTS"},
1263 static const value_string DBPROPSET_CIFRMWRKCORE_EXT_IDS
[] = {
1264 {0x02, "DBPROP_MACHINE"},
1265 {0x03, "DBPROP_CLIENT_CLSID"},
1269 static const value_string DBPROPSET_MSIDXS_ROWSETEXT_IDS
[] = {
1270 {0x02, "MSIDXSPROP_ROWSETQUERYSTATUS"},
1271 {0x03, "MSIDXSPROP_COMMAND_LOCALE_STRING"},
1272 {0x04, "MSIDXSPROP_QUERY_RESTRICTION"},
1273 {0x05, "MSIDXSPROP_PARSE_TREE"},
1274 {0x06, "MSIDXSPROP_MAX_RANK"},
1275 {0x07, "MSIDXSPROP_RESULTS_FOUND"},
1279 static struct GuidPropertySet GuidPropertySet
[] = {
1280 {{0xa9bd1526, 0x6a80, 0x11d0, {0x8c, 0x9d, 0x00, 0x20, 0xaf, 0x1d, 0x74, 0x0e}},
1281 "DBPROPSET_FSCIFRMWRK_EXT", "File system content index framework",
1282 DBPROPSET_FSCIFRMWRK_EXT_IDS
},
1283 {{0xa7ac77ed, 0xf8d7, 0x11ce, {0xa7, 0x98, 0x00, 0x20, 0xf8, 0x00, 0x80, 0x25}},
1284 "DBPROPSET_QUERYEXT", "Query extension",
1285 DBPROPSET_QUERYEXT_IDS
},
1286 {{0xafafaca5, 0xb5d1, 0x11d0, {0x8c, 0x62, 0x00, 0xc0, 0x4f, 0xc2, 0xdb, 0x8d}},
1287 "DBPROPSET_CIFRMWRKCORE_EXT", "Content index framework core",
1288 DBPROPSET_CIFRMWRKCORE_EXT_IDS
},
1289 {{0xAA6EE6B0, 0xE828, 0x11D0, {0xB2, 0x3E, 0x00, 0xAA, 0x00, 0x47, 0xFC, 0x01}},
1290 "DBPROPSET_MSIDXS_ROWSETEXT", "???",
1291 DBPROPSET_MSIDXS_ROWSETEXT_IDS
},
1294 static struct GuidPropertySet
*GuidPropertySet_find_guid(const e_guid_t
*guid
)
1297 for (i
=0; i
<array_length(GuidPropertySet
); i
++) {
1298 if (guid_cmp(&GuidPropertySet
[i
].guid
, guid
) == 0) {
1299 return &GuidPropertySet
[i
];
1305 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1306 proto_tree
*pad_tree
, const char *fmt
, ...)
1310 struct GuidPropertySet
*pset
;
1316 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1319 tree
= proto_item_add_subtree(item
, ett_CDbPropSet
);
1321 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "guidPropertySet");
1323 pset
= GuidPropertySet_find_guid(&guid
);
1326 proto_item_append_text(item
, " \"%s\" (%s)", pset
->desc
, pset
->def
);
1328 const char *guid_str
= guid_to_str(&guid
);
1329 proto_item_append_text(item
, " {%s}", guid_str
);
1332 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "guidPropertySet");
1334 num
= tvb_get_letohl(tvb
, offset
);
1335 proto_tree_add_text(tree
, tvb
, offset
, 4, "cProperties: %d", num
);
1337 proto_item_append_text(item
, " Num: %d", num
);
1339 for (i
= 0; i
<num
; i
++) {
1340 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "aProp[%d]", i
);
1341 offset
= parse_CDbProp(tvb
, offset
, tree
, pad_tree
, pset
, "aProp[%d]", i
);
1344 proto_item_set_end(item
, tvb
, offset
);
1348 static int parse_PropertySetArray(tvbuff_t
*tvb
, int offset
, int size_offset
,
1349 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1350 const char *fmt
, ...)
1352 const int offset_in
= offset
;
1360 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1363 tree
= proto_item_add_subtree(item
, ett_CDbPropSet_Array
);
1365 size
= tvb_get_letohl(tvb
, size_offset
);
1366 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_Blob1
, tvb
,
1367 size_offset
, 4, ENC_LITTLE_ENDIAN
);
1369 num
= tvb_get_letohl(tvb
, offset
);
1370 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_PropSets_num
, tvb
,
1371 offset
, 4, ENC_LITTLE_ENDIAN
);
1374 for (i
= 0; i
< (int)num
; i
++) {
1375 offset
= parse_CDbPropSet(tvb
, offset
, tree
, pad_tree
, "PropertySet[%d]", i
);
1378 proto_item_set_end(item
, tvb
, offset
);
1379 DISSECTOR_ASSERT(offset
- offset_in
== (int)size
);
1383 int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...)
1385 guint32 count
, v
, i
;
1391 item
= proto_tree_add_text_valist(tree
, tvb
, offset
, 0, fmt
, ap
);
1394 count
= tvb_get_letohl(tvb
, offset
);
1397 proto_item_append_text(item
, " Count %u [", count
);
1398 for (i
=0; i
<count
; i
++) {
1399 v
= tvb_get_letohl(tvb
, offset
);
1402 proto_item_append_text(item
, ",%u", v
);
1404 proto_item_append_text(item
, "%u", v
);
1407 proto_item_append_text(item
, "]");
1411 /* 2.2.1.23 RANGEBOUNDARY */
1412 int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1413 proto_tree
*pad_tree
, const char *fmt
, ...)
1416 guint8 labelPresent
;
1419 struct CBaseStorageVariant prval
;
1423 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1424 tree
= proto_item_add_subtree(item
, ett_RANGEBOUNDARY
);
1427 ulType
= tvb_get_letohl(tvb
, offset
);
1428 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType 0x%08x", ulType
);
1429 proto_item_append_text(item
, ": Type 0x%08x", ulType
);
1433 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &prval
, "prVal");
1435 labelPresent
= tvb_get_guint8(tvb
, offset
);
1436 proto_tree_add_text(tree
, tvb
, offset
, 1, "labelPresent: %s", labelPresent
? "True" : "False");
1442 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingLabelPresent");
1444 ccLabel
= tvb_get_letohl(tvb
, offset
);
1445 proto_tree_add_text(tree
, tvb
, offset
, 4, "ccLabel: %u", ccLabel
);
1448 label
= tvb_get_unicode_string(tvb
, offset
, 2*ccLabel
, ENC_LITTLE_ENDIAN
);
1449 proto_tree_add_text(tree
, tvb
, offset
, 2*ccLabel
, "Label: \"%s\"", label
);
1450 proto_item_append_text(item
, " Label: \"%s\"", label
);
1451 offset
+= 2*ccLabel
;
1454 proto_item_append_text(item
, " Val: %s", str_CBaseStorageVariant(&prval
, true));
1456 proto_item_set_end(item
, tvb
, offset
);
1461 /* 2.2.1.22 CRangeCategSpec */
1462 int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
1463 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1464 const char *fmt
, ...)
1470 guint32 lcid
, cRange
;
1473 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1474 tree
= proto_item_add_subtree(item
, ett_CRangeCategSpec
);
1477 lcid
= tvb_get_letohl(tvb
, offset
);
1478 proto_tree_add_text(tree
, tvb
, offset
, 4, "Lcid 0x%08x", lcid
);
1481 cRange
= tvb_get_letohl(tvb
, offset
);
1482 proto_tree_add_text(tree
, tvb
, offset
, 4, "cRange 0x%08x", cRange
);
1485 for (i
=0; i
<cRange
; i
++) {
1486 offset
= parse_RANGEBOUNDARY(tvb
, offset
, tree
, pad_tree
, "aRangeBegin[%u]", i
);
1490 proto_item_set_end(item
, tvb
, offset
);
1494 /* 2.2.1.21 CCategSpec */
1495 int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
1496 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1497 const char *fmt
, ...)
1506 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1507 tree
= proto_item_add_subtree(item
, ett_CCategSpec
);
1510 type
= tvb_get_letohl(tvb
, offset
);
1511 proto_tree_add_text(tree
, tvb
, offset
, 4, "Type 0x%08x", type
);
1512 proto_item_append_text(item
, " Type %u", type
);
1515 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "CSort");
1517 offset
= parse_CRangeCategSpec(tvb
, offset
, tree
, pad_tree
, "CRangeCategSpec");
1519 proto_item_set_end(item
, tvb
, offset
);
1523 /* 2.2.1.25 CAggregSpec */
1524 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
1525 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1526 const char *fmt
, ...)
1532 guint32 ccAlias
, idColumn
, ulMaxNumToReturn
, idRepresentative
;
1536 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1537 tree
= proto_item_add_subtree(item
, ett_CAggregSpec
);
1540 type
= tvb_get_guint8(tvb
, offset
);
1541 proto_tree_add_text(tree
, tvb
, offset
, 1, "type: %u", type
);
1542 proto_item_append_text(item
, "type: %u", type
);
1545 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding");
1547 ccAlias
= tvb_get_letohl(tvb
, offset
);
1548 proto_tree_add_text(tree
, tvb
, offset
, 1, "ccAlias: %u", ccAlias
);
1551 alias
= tvb_get_unicode_string(tvb
, offset
, 2*ccAlias
, ENC_LITTLE_ENDIAN
);
1552 proto_tree_add_text(tree
, tvb
, offset
, 2*ccAlias
, "Alias: %s", alias
);
1553 offset
+= 2*ccAlias
;
1555 idColumn
= tvb_get_letohl(tvb
, offset
);
1556 proto_tree_add_text(tree
, tvb
, offset
, 1, "idColumn: %u", idColumn
);
1559 ulMaxNumToReturn, idRepresentative;
1561 fprintf(stderr
, "WARNING, dont know if optional members are present!\n ");
1563 proto_item_set_end(item
, tvb
, offset
);
1567 /* 2.2.1.24 CAggregSet */
1568 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
1569 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1570 const char *fmt
, ...)
1579 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1580 tree
= proto_item_add_subtree(item
, ett_CAggregSet
);
1583 cCount
= tvb_get_letohl(tvb
, offset
);
1584 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1587 for (i
=0; i
<cCount
; i
++) {
1588 /* 2.2.1.25 CAggregSpec */
1589 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "AggregSpecs[%u]", i
);
1592 proto_item_set_end(item
, tvb
, offset
);
1596 /* 2.2.1.27 CAggregSortKey */
1597 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
1598 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1599 const char *fmt
, ...)
1608 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1609 tree
= proto_item_add_subtree(item
, ett_CAggregSortKey
);
1612 order
= tvb_get_letohl(tvb
, offset
);
1613 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", order
);
1616 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "ColumnSpec");
1618 proto_item_set_end(item
, tvb
, offset
);
1623 /* 2.2.1.26 CSortAggregSet */
1624 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
1625 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1626 const char *fmt
, ...)
1635 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1636 tree
= proto_item_add_subtree(item
, ett_CSortAggregSet
);
1639 cCount
= tvb_get_letohl(tvb
, offset
);
1640 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1643 for (i
=0; i
<cCount
; i
++) {
1644 /* 2.2.1.27 CAggregSortKey */
1645 offset
= parse_CAggregSortKey(tvb
, offset
, tree
, pad_tree
, "SortKeys[%u]", i
);
1648 proto_item_set_end(item
, tvb
, offset
);
1652 enum CInGroupSortAggregSet_type
{
1653 GroupIdDefault
= 0x00, /* The default for all ranges. */
1654 GroupIdMinValue
= 0x01, /*The first range in the parent's group.*/
1655 GroupIdNull
= 0x02, /*The last range in the parent's group.*/
1656 GroupIdValue
= 0x03,
1659 /* 2.2.1.29 CInGroupSortAggregSet */
1660 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
1661 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1662 const char *fmt
, ...)
1667 enum CInGroupSortAggregSet_type type
;
1670 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1671 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSet
);
1674 type
= tvb_get_guint8(tvb
, offset
);
1675 proto_tree_add_text(tree
, tvb
, offset
, 1, "Type: 0x%02x", (unsigned)type
);
1678 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "CInGroupSortAggregSet");
1680 if (type
== GroupIdValue
) {
1681 struct CBaseStorageVariant id
;
1682 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &id
, "inGroupId");
1685 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1687 proto_item_set_end(item
, tvb
, offset
);
1692 /* 2.2.1.28 CInGroupSortAggregSets */
1693 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
1694 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1695 const char *fmt
, ...)
1704 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1705 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSets
);
1708 cCount
= tvb_get_letohl(tvb
, offset
);
1709 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1712 for (i
=0; i
<cCount
; i
++) {
1713 /* 2.2.1.29 CInGroupSortAggregSet */
1714 offset
= parse_CInGroupSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortSets[%u]", i
);
1717 proto_item_set_end(item
, tvb
, offset
);
1721 /* 2.2.1.20 CCategorizationSpec */
1722 int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
1723 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1724 const char *fmt
, ...)
1726 guint32 cMaxResults
;
1733 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1734 tree
= proto_item_add_subtree(item
, ett_CCategorizationSpec
);
1737 /* 2.2.1.18 CColumnSet */
1738 offset
= parse_CColumnSet(tvb
, offset
, tree
, "csColumns");
1740 /* 2.2.1.21 CCategSpec */
1741 offset
= parse_CCategSpec(tvb
, offset
, tree
, pad_tree
, "Spec");
1743 /* 2.2.1.24 CAggregSet */
1744 offset
= parse_CAggregSet(tvb
, offset
, tree
, pad_tree
, "AggregSet");
1746 /* 2.2.1.26 CSortAggregSet */
1747 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1749 /* 2.2.1.28 CInGroupSortAggregSets */
1750 offset
= parse_CInGroupSortAggregSets(tvb
, offset
, tree
, pad_tree
, "InGroupSortAggregSets");
1752 cMaxResults
= tvb_get_letohl(tvb
, offset
);
1753 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", cMaxResults
);
1756 proto_item_set_end(item
, tvb
, offset
);
1760 int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
1761 proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1762 const char *fmt
, ...)
1764 guint32 opt
, maxres
, timeout
;
1771 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1772 tree
= proto_item_add_subtree(item
, ett_CRowsetProperties
);
1775 opt
= tvb_get_letohl(tvb
, offset
);
1776 proto_tree_add_text(tree
, tvb
, offset
, 4, "uBooleanOptions: 0x%08x", opt
);
1779 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMaxOpenRows (ignored)");
1782 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMemoryUsage (ignored)");
1785 maxres
= tvb_get_letohl(tvb
, offset
);
1786 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", maxres
);
1789 timeout
= tvb_get_letohl(tvb
, offset
);
1790 proto_tree_add_text(tree
, tvb
, offset
, 4, "cCmdTimeout: %u", timeout
);
1793 proto_item_set_end(item
, tvb
, offset
);
1797 int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
1798 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1799 const char *fmt
, ...)
1807 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1808 tree
= proto_item_add_subtree(item
, ett_CPidMapper
);
1811 count
= tvb_get_letohl(tvb
, offset
);
1812 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
1815 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "CPidMapper_PropSpec");
1817 for (i
=0; i
<count
; i
++) {
1818 struct CFullPropSpec v
;
1820 offset
= parse_padding(tvb
, offset
, 4, pad_tree
,
1821 "CPidMapper_PropSpec[%u]", i
); //at begin or end of loop???
1822 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
, "PropSpec[%u]", i
);
1825 proto_item_set_end(item
, tvb
, offset
);
1829 /* Code to actually dissect the packets */
1831 static int dissect_CPMConnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
1839 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
1840 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
1841 proto_item_set_text(ti
, "CPMConnect%s", in
? "In" : "Out");
1842 col_append_str(pinfo
->cinfo
, COL_INFO
, "Connect");
1844 version
= tvb_get_letohl(tvb
, offset
);
1845 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_Connect_Version
, tvb
,
1846 offset
, 4, ENC_LITTLE_ENDIAN
);
1847 if (version
& 0xffff0000) {
1848 proto_item_append_text(ti
, " 64 bit");
1850 switch (version
& 0xffff) {
1852 proto_item_append_text(ti
, " w2k8 or vista");
1855 proto_item_append_text(ti
, " XP or w2k3, with Windows Search 4.0");
1858 proto_item_append_text(ti
, " win7 or w2k8r2");
1864 guint32 blob_size1_off
, blob_size2_off
;
1865 proto_tree
*pad_tree
;
1867 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
1868 pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
1870 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_ClientIsRemote
, tvb
,
1871 offset
, 4, ENC_LITTLE_ENDIAN
);
1875 blob_size1_off
= offset
;
1878 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcbBlob2");
1881 blob_size2_off
= offset
;
1884 offset
= parse_padding(tvb
, offset
, 16, pad_tree
, "_padding");
1886 len
= tvb_unicode_strsize(tvb
, offset
);
1887 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_MachineName
, tvb
,
1888 offset
, len
, ENC_UTF_16
);
1889 /*This shouldnt be necessary, is this a bug or is there some GUI setting I've missed?*/
1890 proto_item_set_text(ti
, "Remote machine: %s",
1891 tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
1894 len
= tvb_unicode_strsize(tvb
, offset
);
1895 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_UserName
, tvb
,
1896 offset
, len
, ENC_UTF_16
);
1897 proto_item_set_text(ti
, "User: %s", tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
1900 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcPropSets");
1902 offset
= parse_PropertySetArray(tvb
, offset
, blob_size1_off
, tree
, pad_tree
, "PropSets");
1904 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingExtPropset");
1906 offset
= parse_PropertySetArray(tvb
, offset
, blob_size2_off
, tree
, pad_tree
, "ExtPropset");
1908 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "???");
1910 DISSECTOR_ASSERT(offset
== (int)tvb_length(tvb
));
1912 /* make "Padding" the last item */
1913 proto_tree_move_item(tree
, ti
, proto_tree_get_parent(pad_tree
));
1917 return tvb_length(tvb
);
1920 static int dissect_CPMDisconnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1922 col_append_str(pinfo
->cinfo
, COL_INFO
, "Disconnect");
1923 return tvb_length(tvb
);
1926 static int dissect_CPMCreateQuery(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
1932 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
1933 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
1935 proto_item_set_text(ti
, "CPMCreateQuery%s", in
? "In" : "Out");
1936 col_append_str(pinfo
->cinfo
, COL_INFO
, "CreateQuery");
1939 proto_item
*ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
1940 proto_tree
*pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
1941 guint8 CColumnSetPresent
, CRestrictionPresent
, CSortSetPresent
, CCategorizationSetPresent
;
1942 guint32 size
= tvb_get_letohl(tvb
, offset
);
1943 proto_tree_add_text(tree
, tvb
, offset
, 4, "size");
1944 proto_tree_add_text(tree
, tvb
, offset
, size
, "ALL");
1947 CColumnSetPresent
= tvb_get_guint8(tvb
, offset
);
1948 proto_tree_add_text(tree
, tvb
, offset
, 1, "CColumnSetPresent: %s", CColumnSetPresent
? "True" : "False");
1951 if (CColumnSetPresent
) {
1952 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCColumnSetPresent");
1953 offset
= parse_CColumnSet(tvb
, offset
, tree
, "CColumnSet");
1956 CRestrictionPresent
= tvb_get_guint8(tvb
, offset
);
1957 proto_tree_add_text(tree
, tvb
, offset
, 1, "CRestrictionPresent: %s", CColumnSetPresent
? "True" : "False");
1959 if (CRestrictionPresent
) {
1960 offset
= parse_CRestrictionArray(tvb
, offset
, tree
, pad_tree
, "RestrictionArray");
1963 CSortSetPresent
= tvb_get_guint8(tvb
, offset
);
1964 proto_tree_add_text(tree
, tvb
, offset
, 1, "CSortSetPresent: %s", CSortSetPresent
? "True" : "False");
1966 if (CSortSetPresent
) {
1967 offset
= parse_padding(tvb
, offset
, 4, tree
, "paddingCSortSetPresent");
1969 proto_tree_add_text(tree
, tvb
, offset
, 8, "XXX");
1972 offset
= parse_CSortSet(tvb
, offset
, tree
, pad_tree
, "SortSet");
1975 CCategorizationSetPresent
= tvb_get_guint8(tvb
, offset
);
1976 proto_tree_add_text(tree
, tvb
, offset
, 1, "CCategorizationSetPresent: %s", CCategorizationSetPresent
? "True" : "False");
1979 if (CCategorizationSetPresent
) {
1981 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCCategorizationSetPresent");
1982 /* 2.2.1.19 CCategorizationSet */
1983 count
= tvb_get_letohl(tvb
, offset
);
1984 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
1986 for (i
=0; i
<count
; i
++) {
1987 offset
= parse_CCategorizationSpec(tvb
, offset
, tree
, pad_tree
, "categories[%u]", i
);
1991 offset
= parse_padding(tvb
, offset
, 4, tree
, "XXXX"); //XXX
1993 offset
= parse_CRowsetProperties(tvb
, offset
, tree
, pad_tree
, "RowSetProperties");
1995 offset
= parse_CPidMapper(tvb
, offset
, tree
, pad_tree
, "PidMapper");
1998 return tvb_length(tvb
);
2001 static int dissect_CPMFreeCursor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2003 col_append_str(pinfo
->cinfo
, COL_INFO
, "FreeCursor");
2004 return tvb_length(tvb
);
2007 static int dissect_CPMGetRows(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2009 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRows");
2010 return tvb_length(tvb
);
2013 static int dissect_CPMRatioFinished(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2015 col_append_str(pinfo
->cinfo
, COL_INFO
, "RatioFinished");
2016 return tvb_length(tvb
);
2019 static int dissect_CPMCompareBmk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2021 col_append_str(pinfo
->cinfo
, COL_INFO
, "CompareBmk");
2022 return tvb_length(tvb
);
2025 static int dissect_CPMGetApproximatePosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2027 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetApproximatePosition");
2028 return tvb_length(tvb
);
2031 static int dissect_CPMSetBindings(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2033 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetBindings");
2034 return tvb_length(tvb
);
2037 static int dissect_CPMGetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2039 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetNotify");
2040 return tvb_length(tvb
);
2043 static int dissect_CPMSendNotifyOut(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2045 col_append_str(pinfo
->cinfo
, COL_INFO
, "SendNotify");
2046 return tvb_length(tvb
);
2049 static int dissect_CPMGetQueryStatus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2051 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatus");
2052 return tvb_length(tvb
);
2055 static int dissect_CPMCiState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2057 col_append_str(pinfo
->cinfo
, COL_INFO
, "CiState");
2058 return tvb_length(tvb
);
2061 static int dissect_CPMFetchValue(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2063 col_append_str(pinfo
->cinfo
, COL_INFO
, "FetchValue");
2064 return tvb_length(tvb
);
2067 static int dissect_CPMGetQueryStatusEx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2069 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatusEx");
2070 return tvb_length(tvb
);
2073 static int dissect_CPMRestartPosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2075 col_append_str(pinfo
->cinfo
, COL_INFO
, "RestartPosition");
2076 return tvb_length(tvb
);
2079 static int dissect_CPMSetCatState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2081 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetCatState");
2082 return tvb_length(tvb
);
2085 static int dissect_CPMGetRowsetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2087 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRowsetNotify");
2088 return tvb_length(tvb
);
2091 static int dissect_CPMFindIndices(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2093 col_append_str(pinfo
->cinfo
, COL_INFO
, "FindIndices");
2094 return tvb_length(tvb
);
2097 static int dissect_CPMSetScopePrioritization(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2099 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetScopePrioritization");
2100 return tvb_length(tvb
);
2103 static int dissect_CPMGetScopeStatistics(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2105 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetScopeStatistics");
2106 return tvb_length(tvb
);
2111 dissect_mswsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gboolean in
)
2113 static const char *dbg_wait
= NULL
;
2114 static int wait_frame
= -1;
2116 proto_tree
*mswsp_tree
= NULL
;
2123 int (*fn
)(tvbuff_t
*, packet_info
*, proto_tree
*, gboolean
);
2125 if (tvb_length(tvb
) < 16) {
2129 if (dbg_wait
== NULL
) {
2130 dbg_wait
= getenv("DBG_FRAME");
2131 if (dbg_wait
== NULL
) {
2134 wait_frame
= atoi(dbg_wait
);
2138 if ((int)pinfo
->fd
->num
== wait_frame
) {
2139 static volatile gboolean wait
= 1;
2145 hdr
.msg
= tvb_get_letohl(tvb
, 0);
2149 fn
= dissect_CPMConnect
;
2152 fn
= dissect_CPMDisconnect
;
2155 fn
= dissect_CPMCreateQuery
;
2158 fn
= dissect_CPMFreeCursor
;
2161 fn
= dissect_CPMGetRows
;
2164 fn
= dissect_CPMRatioFinished
;
2167 fn
= dissect_CPMCompareBmk
;
2170 fn
= dissect_CPMGetApproximatePosition
;
2173 fn
= dissect_CPMSetBindings
;
2176 fn
= dissect_CPMGetNotify
;
2179 fn
= dissect_CPMSendNotifyOut
;
2182 fn
= dissect_CPMGetQueryStatus
;
2185 fn
= dissect_CPMCiState
;
2188 fn
= dissect_CPMFetchValue
;
2191 fn
= dissect_CPMGetQueryStatusEx
;
2194 fn
= dissect_CPMRestartPosition
;
2197 fn
= dissect_CPMSetCatState
;
2200 fn
= dissect_CPMGetRowsetNotify
;
2203 fn
= dissect_CPMFindIndices
;
2206 fn
= dissect_CPMSetScopePrioritization
;
2209 fn
= dissect_CPMGetScopeStatistics
;
2215 hdr
.status
= tvb_get_letohl(tvb
, 4);
2216 hdr
.checksum
= tvb_get_letohl(tvb
, 8);
2218 /* col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS-WSP"); */
2219 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, " WSP");
2220 /* col_clear(pinfo->cinfo, COL_INFO); */
2222 col_set_str(pinfo
->cinfo
, COL_INFO
, "WSP ");
2223 col_append_str(pinfo
->cinfo
, COL_INFO
, in
? "Request: " : "Response: ");
2226 proto_tree
*hdr_tree
;
2227 proto_item
*ti
, *hti
;
2229 ti
= proto_tree_add_item(tree
, proto_mswsp
, tvb
, 0, -1, ENC_NA
);
2230 mswsp_tree
= proto_item_add_subtree(ti
, ett_mswsp
);
2232 hti
= proto_tree_add_item(mswsp_tree
, hf_mswsp_hdr
, tvb
, 0, 16, ENC_NA
);
2233 hdr_tree
= proto_item_add_subtree(hti
, ett_mswsp_hdr
);
2235 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_msg
, tvb
,
2236 0, 4, ENC_LITTLE_ENDIAN
);
2237 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_status
,
2238 tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
2239 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_checksum
,
2240 tvb
, 8, 4, ENC_LITTLE_ENDIAN
);
2241 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_reserved
, tvb
,
2242 12, 4, ENC_LITTLE_ENDIAN
);
2245 fn(tvb
, pinfo
, mswsp_tree
, in
);
2247 /* Return the amount of data this dissector was able to dissect */
2248 return tvb_length(tvb
);
2252 /* Register the protocol with Wireshark */
2254 /* this format is require because a script is used to build the C function
2255 that calls all the protocol registration.
2259 proto_register_mswsp(void)
2261 module_t
*mswsp_module
;
2263 /* Setup list of header fields See Section 1.6.1 for details*/
2264 static const value_string msg_ids
[] = {
2265 {0x000000C8, "CPMConnect"}, /* In/Out */
2266 {0x000000C9, "CPMDisconnect"},
2267 {0x000000CA, "CPMCreateQuery"}, /* In/Out */
2268 {0x000000CB, "CPMFreeCursor"}, /* In/Out */
2269 {0x000000CC, "CPMGetRows"}, /* In/Out */
2270 {0x000000CD, "CPMRatioFinished"}, /* In/Out */
2271 {0x000000CE, "CPMCompareBmk"}, /* In/Out */
2272 {0x000000CF, "CPMGetApproximatePosition"}, /* In/Out */
2273 {0x000000D0, "CPMSetBindingsIn"},
2274 {0x000000D1, "CPMGetNotify"},
2275 {0x000000D2, "CPMSendNotifyOut"},
2276 {0x000000D7, "CPMGetQueryStatusIn"}, /* In/Out */
2277 {0x000000D9, "CPMCiStateInOut"},
2278 {0x000000E4, "CPMFetchValue"}, /* In/Out */
2279 {0x000000E7, "CPMGetQueryStatusEx"}, /* In/Out */
2280 {0x000000E8, "CPMRestartPositionIn"},
2281 {0x000000EC, "CPMSetCatStateIn"}, /* (not supported) */
2282 {0x000000F1, "CPMGetRowsetNotify"}, /* In/Out */
2283 {0x000000F2, "CPMFindIndices"}, /* In/Out */
2284 {0x000000F3, "CPMSetScopePrioritization"}, /* In/Out */
2285 {0x000000F4, "CPMGetScopeStatistics"}, /* In/Out */
2287 static hf_register_info hf
[] = {
2289 { "Header", "mswsp.hdr",
2290 FT_NONE
, BASE_NONE
, NULL
, 0,
2291 "Message header", HFILL
}
2293 { &hf_mswsp_hdr_msg
,
2294 { "Msg id", "mswsp.hdr.id",
2295 FT_UINT32
, BASE_HEX
, VALS(msg_ids
), 0,
2296 "Message id", HFILL
}
2298 { &hf_mswsp_hdr_status
,
2299 { "Status", "mswsp.hdr.status",
2300 FT_UINT32
, BASE_HEX
, NULL
, 0,
2303 { &hf_mswsp_hdr_checksum
,
2304 { "checksum", "mswsp.hdr.checksum",
2305 FT_UINT32
, BASE_HEX
, NULL
, 0,
2308 { &hf_mswsp_hdr_reserved
,
2309 { "Reserved", "mswsp.hdr.reserved",
2310 FT_UINT32
, BASE_HEX
, NULL
, 0,
2314 { "msg", "mswsp.msg",
2315 FT_NONE
, BASE_NONE
, NULL
, 0,
2318 { &hf_mswsp_msg_Connect_Version
,
2319 { "Version", "mswsp.Connect.version",
2320 FT_UINT32
, BASE_HEX
, NULL
, 0,
2323 { &hf_mswsp_msg_ConnectIn_ClientIsRemote
,
2324 { "Remote", "mswsp.ConnectIn.isRemote",
2325 FT_BOOLEAN
, BASE_HEX
, NULL
, 0,
2326 "Client is remote",HFILL
}
2328 { &hf_mswsp_msg_ConnectIn_Blob1
,
2329 { "Size", "mswsp.ConnectIn.propset.size",
2330 FT_UINT32
, BASE_DEC
, NULL
, 0,
2331 "Size of PropSet fields",HFILL
}
2333 { &hf_mswsp_msg_ConnectIn_Blob2
,
2334 { "Size", "mswsp.ConnectIn.extpropset.size",
2335 FT_UINT32
, BASE_DEC
, NULL
, 0,
2336 "Size of ExtPropSet fields",HFILL
}
2338 { &hf_mswsp_msg_ConnectIn_MachineName
,
2339 { "Remote machine", "mswsp.ConnectIn.machine",
2340 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2341 "Name of remote machine",HFILL
}
2343 { &hf_mswsp_msg_ConnectIn_UserName
,
2344 { "User", "mswsp.ConnectIn.user",
2345 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2346 "Name of remote user",HFILL
}
2348 { &hf_mswsp_msg_ConnectIn_PropSets_num
,
2349 { "Num", "mswsp.ConnectIn.propset.num",
2350 FT_UINT32
, BASE_DEC
, NULL
, 0,
2351 "Number of Property Sets", HFILL
}
2353 { &hf_mswsp_msg_ConnectIn_ExtPropSets_num
,
2354 { "Num", "mswsp.ConnectIn.extpropset.num",
2355 FT_UINT32
, BASE_DEC
, NULL
, 0,
2356 "Number of extended Property Sets", HFILL
}
2361 /* Setup protocol subtree array */
2362 static gint
*ett
[] = {
2367 &ett_mswsp_property_restriction
,
2368 &ett_CRestrictionArray
,
2369 &ett_CBaseStorageVariant
,
2370 &ett_CBaseStorageVariant_Vector
,
2371 &ett_CBaseStorageVariant_Array
,
2376 &ett_CDbPropSet_Array
,
2378 &ett_CNodeRestriction
,
2379 &ett_CPropertyRestriction
,
2380 &ett_CCoercionRestriction
,
2381 &ett_CContentRestriction
,
2383 &ett_CRangeCategSpec
,
2387 &ett_CCategorizationSpec
,
2388 &ett_CAggregSortKey
,
2389 &ett_CSortAggregSet
,
2390 &ett_CInGroupSortAggregSet
,
2391 &ett_CInGroupSortAggregSets
,
2392 &ett_CRowsetProperties
,
2401 /* Register the protocol name and description */
2402 proto_mswsp
= proto_register_protocol("Windows Search Protocol",
2405 /* Required function calls to register the header fields and subtrees used */
2406 proto_register_field_array(proto_mswsp
, hf
, array_length(hf
));
2407 proto_register_subtree_array(ett
, array_length(ett
));
2409 for (i
=0; i
<(int)array_length(GuidPropertySet
); i
++) {
2410 guids_add_guid(&GuidPropertySet
[i
].guid
, GuidPropertySet
[i
].def
);
2414 /* Register preferences module (See Section 2.6 for more on preferences) */
2415 /* (Registration of a prefs callback is not required if there are no */
2416 /* prefs-dependent registration functions (eg: a port pref). */
2417 /* See proto_reg_handoff below. */
2418 /* If a prefs callback is not needed, use NULL instead of */
2419 /* proto_reg_handoff_mswsp in the following). */
2420 mswsp_module
= prefs_register_protocol(proto_mswsp
,
2421 proto_reg_handoff_mswsp
);
2423 /* Register preferences module under preferences subtree.
2424 Use this function instead of prefs_register_protocol if you want to group
2425 preferences of several protocols under one preferences subtree.
2426 Argument subtree identifies grouping tree node name, several subnodes can be
2427 specified using slash '/' (e.g. "OSI/X.500" - protocol preferences will be
2428 accessible under Protocols->OSI->X.500-><PROTOSHORTNAME> preferences node.
2430 /* mswsp_module = prefs_register_protocol_subtree(subtree, */
2431 /* proto_mswsp, proto_reg_handoff_mswsp); */
2433 /* Register a sample preference */
2434 prefs_register_bool_preference(mswsp_module
, "show_hex",
2435 "Display numbers in Hex",
2436 "Enable to display numerical values in hexadecimal.",
2439 /* Register a sample port preference */
2440 prefs_register_uint_preference(mswsp_module
, "tcp.port", "mswsp TCP Port",
2441 " mswsp TCP port if other than the default",
2445 static int dissect_mswsp_smb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2446 smb_info_t
*si
= pinfo
->private_data
;
2447 gboolean in
= si
->request
;
2449 smb_transact_info_t
*tri
= (si
->sip
->extra_info_type
== SMB_EI_TRI
) ? si
->sip
->extra_info
: NULL
;
2450 smb_fid_info_t
*fid_info
= NULL
;
2453 fprintf(stderr
, "dissect_mswsp_smb %s frame: %d tid: %d op: %02x ",
2454 in
? "Request" : "Response",
2455 pinfo
->fd
->num
, si
->tid
, si
->cmd
);
2458 fprintf(stderr
, " extra_info_type: %d\n", si
->sip
->extra_info_type
);
2462 for (iter
= si
->ct
->GSL_fid_info
; iter
; iter
= g_slist_next(iter
)) {
2463 smb_fid_info_t
*info
= iter
->data
;
2464 if ((info
->tid
== si
->tid
) && (info
->fid
== tri
->fid
)) {
2470 if ((fid_info
->fsi
== NULL
) || (fid_info
->fsi
->filename
== NULL
)) {
2471 fprintf(stderr
, " no %s\n", fid_info
->fsi
? "filename" : "fsi");
2475 fprintf(stderr
, " file: %s\n", fid_info
->fsi
->filename
);
2477 if (strcasecmp(fid_info
->fsi
->filename
, "\\MsFteWds") != 0) {
2481 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2485 static int dissect_mswsp_smb2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2486 smb2_info_t
*si
= pinfo
->private_data
;
2487 gboolean in
= !(si
->flags
& SMB2_FLAGS_RESPONSE
);
2489 //si->tree->share_type == SMB2_SHARE_TYPE_PIPE
2490 //si->tree->connect_frame
2492 fprintf(stderr
, "dissect_mswsp %d <> %d : op %02x %s %s type: %d extra_file: %s\n",
2493 pinfo
->fd
->num
, si
->tree
? (int)si
->tree
->connect_frame
: -1,
2495 pinfo
->dcerpc_procedure_name
? pinfo
->dcerpc_procedure_name
: "<NULL>",
2496 in
? "Request" : "Response", si
->tree
? si
->tree
->share_type
: -1,
2497 si
->saved
? (si
->saved
->extra_info_type
== SMB2_EI_FILENAME
? (char*)si
->saved
->extra_info
: "<OTHER>") : "<NONE>"
2501 if (strcmp(pinfo
->dcerpc_procedure_name
, "File: MsFteWds") != 0) {
2505 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2510 /* If this dissector uses sub-dissector registration add a registration routine.
2511 This exact format is required because a script is used to find these
2512 routines and create the code that calls these routines.
2514 If this function is registered as a prefs callback (see prefs_register_protocol
2515 above) this function is also called by preferences whenever "Apply" is pressed;
2516 In that case, it should accommodate being called more than once.
2518 Simple form of proto_reg_handoff_mswsp which can be used if there are
2519 no prefs-dependent registration function calls.
2523 proto_reg_handoff_mswsp(void)
2525 heur_dissector_add("smb_transact", dissect_mswsp_smb
, proto_mswsp
);
2526 heur_dissector_add("smb2_heur_subdissectors", dissect_mswsp_smb2
, proto_mswsp
);
2531 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2536 * indent-tabs-mode: nil
2539 * vi: set shiftwidth=4 tabstop=8 expandtab:
2540 * :indentSize=4:tabSize=8:noTabs=true: