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
, ...);
201 /* 2.2.1.17 CRestriction */
202 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
203 struct CRestriction
*v
, const char *fmt
, ...);
205 /* 2.2.1.18 CColumnSet */
206 static int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...);
208 /* 2.2.1.20 CCategorizationSpec */
209 static int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
210 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
211 const char *fmt
, ...);
213 /* 2.2.1.21 CCategSpec */
214 static int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
215 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
216 const char *fmt
, ...);
218 /* 2.2.1.22 CRangeCategSpec */
219 static int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
220 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
221 const char *fmt
, ...);
223 /* 2.2.1.23 RANGEBOUNDARY */
224 static int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
225 proto_tree
*pad_tree
, const char *fmt
, ...);
227 /* 2.2.1.24 CAggregSet */
228 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
229 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
230 const char *fmt
, ...);
232 /* 2.2.1.25 CAggregSpec */
233 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
234 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
235 const char *fmt
, ...);
237 /* 2.2.1.26 CSortAggregSet */
238 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
239 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
240 const char *fmt
, ...);
242 /* 2.2.1.27 CAggregSortKey */
243 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
244 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
245 const char *fmt
, ...);
247 /* 2.2.1.28 CInGroupSortAggregSets */
248 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
249 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
250 const char *fmt
, ...);
252 /* 2.2.1.29 CInGroupSortAggregSet */
253 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
254 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
255 const char *fmt
, ...);
256 /* 2.2.1.30 CDbColId */
257 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
,
258 proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
);
260 /* 2.2.1.31 CDbProp */
261 struct GuidPropertySet
;
262 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
263 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
264 const char *fmt
, ...);
266 /* 2.2.1.32 CDbPropSet */
267 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
268 proto_tree
*pad_tree
, const char *fmt
, ...);
269 /* 2.2.1.33 CPidMapper */
270 static int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
271 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
272 const char *fmt
, ...);
274 /* 2.2.1.41 CRowsetProperties */
275 static int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
276 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
277 const char *fmt
, ...);
279 /* 2.2.1.43 CSortSet */
280 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
,
281 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
282 const char *fmt
, ...);
285 2.2.1.4 CInternalPropertyRestriction
286 2.2.1.5 CNatLanguageRestriction
287 2.2.1.9 CScopeRestriction
288 2.2.1.11 CVectorRestriction
289 2.2.1.13 CRelDocRestriction
290 2.2.1.14 CProbRestriction
291 2.2.1.15 CFeedbackRestriction
292 2.2.1.16 CRestrictionArray
293 2.2.1.19 CCategorizationSet
294 2.2.1.34 CColumnGroupArray
295 2.2.1.35 CColumnGroup
298 2.2.1.38 CRowSeekAtRatio
299 2.2.1.39 CRowSeekByBookmark
300 2.2.1.40 CRowSeekNext
302 2.2.1.44 CTableColumn
303 2.2.1.45 SERIALIZEDPROPERTYVALUE
304 2.2.1.46 CCompletionCategSp
307 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
308 proto_tree
*pad_tree _U_
,
309 const char *fmt
, ...)
311 guint32 col
, ord
, ind
, lcid
;
319 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
321 tree
= proto_item_add_subtree(item
, ett_CSort
);
323 col
= tvb_get_letohl(tvb
, offset
);
324 proto_tree_add_text(tree
, tvb
, offset
, 4, "column: %u", col
);
327 ord
= tvb_get_letohl(tvb
, offset
);
328 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", ord
);
331 ind
= tvb_get_letohl(tvb
, offset
);
332 proto_tree_add_text(tree
, tvb
, offset
, 4, "individual: %u", ind
);
335 lcid
= tvb_get_letohl(tvb
, offset
);
336 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", lcid
);
339 proto_item_set_end(item
, tvb
, offset
);
343 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
344 proto_tree
*pad_tree
,
345 const char *fmt
, ...)
355 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
357 tree
= proto_item_add_subtree(item
, ett_CSortSet
);
359 count
= tvb_get_letohl(tvb
, offset
);
360 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
363 for (i
=0; i
<count
; i
++) {
364 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "sortArray[%u]", i
);
367 proto_item_set_end(item
, tvb
, offset
);
372 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
,
373 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
374 struct CFullPropSpec
*v
, const char *fmt
, ...)
376 static const value_string KIND
[] = {
377 {0, "PRSPEC_LPWSTR"},
378 {1, "PRSPEC_PROPID"},
382 const char *guid_str
;
388 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
390 tree
= proto_item_add_subtree(item
, ett_CFullPropSpec
);
392 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingPropSet");
394 offset
= parse_guid(tvb
, offset
, tree
, &v
->guid
, "GUID");
395 guid_str
= guids_resolve_guid_to_str(&v
->guid
);
396 proto_item_append_text(item
, " {%s}", guid_str
);
398 v
->kind
= tvb_get_letohl(tvb
, offset
);
399 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulKind: %s ", val_to_str(v
->kind
, KIND
, "(Unknown: 0x%x)"));
402 v
->u
.propid
= tvb_get_letohl(tvb
, offset
);
403 proto_tree_add_text(tree
, tvb
, offset
, 4, "propid: %u ", v
->u
.propid
);
406 if (v
->kind
== PRSPEC_LPWSTR
) {
407 int len
= 2*v
->u
.propid
;
408 v
->u
.name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
409 proto_tree_add_text(tree
, tvb
, offset
, len
, "name: \"%s\"", v
->u
.name
);
410 proto_item_append_text(item
, " \"%s\"", v
->u
.name
);
412 } else if (v
->kind
== PRSPEC_PROPID
) {
413 proto_item_append_text(item
, " 0x%08x", v
->u
.propid
);
415 proto_item_append_text(item
, "<INVALID>");
418 proto_item_set_end(item
, tvb
, offset
);
424 static const value_string PR_VALS
[] = {
432 {PRAllBits
, "PRAllBits"},
433 {PRSomeBits
, "PRSomeBits"},
439 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
440 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
441 const char *fmt
, ...)
449 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
452 tree
= proto_item_add_subtree(item
, ett_CPropertyRestriction
);
454 v
->relop
= tvb_get_letohl(tvb
, offset
);
455 str
= val_to_str(v
->relop
, PR_VALS
, "0x%04x");
456 proto_tree_add_text(tree
, tvb
, offset
, 4, "relop: %s (0x%04x)",
457 str
[0]=='\0' ? "" : str
, v
->relop
);
458 proto_item_append_text(item
, " Op: %s", str
);
461 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
463 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &v
->prval
, "prval");
465 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
467 v
->lcid
= tvb_get_letohl(tvb
, offset
);
468 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
471 proto_item_set_end(item
, tvb
, offset
);
476 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
477 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
478 const char *fmt
, ...)
485 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
488 tree
= proto_item_add_subtree(item
, ett_CCoercionRestriction
);
490 v
->value
= tvb_get_letohl(tvb
, offset
);
491 proto_tree_add_text(tree
, tvb
, offset
, 4, "value: %g", (double)v
->value
);
494 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &v
->child
, "child");
496 proto_item_set_end(item
, tvb
, offset
);
500 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
501 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
502 const char *fmt
, ...)
512 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
515 tree
= proto_item_add_subtree(item
, ett_CContentRestriction
);
517 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
519 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding1");
521 cc
= tvb_get_letohl(tvb
, offset
);
522 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
525 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
526 str
= tvb_get_unicode_string(tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
527 v
->phrase
= se_strdup(str
);
528 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
531 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding2");
533 v
->lcid
= tvb_get_letohl(tvb
, offset
);
534 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
537 v
->method
= tvb_get_letohl(tvb
, offset
);
538 proto_tree_add_text(tree
, tvb
, offset
, 4, "method: 0x%08x", v
->method
);
541 proto_item_set_end(item
, tvb
, offset
);
546 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
547 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
548 const char *fmt
, ...)
555 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
558 v
->whereId
= tvb_get_letohl(tvb
, offset
);
561 proto_item_append_text(item
, "Id: %u", v
->whereId
);
563 proto_item_set_end(item
, tvb
, offset
);
567 static value_string RT_VALS
[] = {
572 {RTContent
, "RTContent"},
573 {RTProperty
, "RTProperty"},
574 {RTProximity
, "RTProximity"},
576 {RTNatLanguage
, "RTNatLanguage"},
577 {RTScope
, "RTScope"},
578 {RTCoerce_Add
, "RTCoerce_Add"},
579 {RTCoerce_Multiply
, "RTCoerce_Multiply"},
580 {RTCoerce_Absolute
, "RTCoerce_Absolute"},
582 {RTFeedback
, "RTFeedback"},
583 {RTReldoc
, "RTReldoc"},
584 {RTReuseWhere
, "RTReuseWhere"},
585 {RTInternalProp
, "RTInternalProp"},
586 {RTPhrase
, "RTInternalProp"},
589 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
590 struct CRestriction
*v
, const char *fmt
, ...)
593 proto_item
*item
, *ti
;
598 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
601 tree
= proto_item_add_subtree(item
, ett_CRestriction
);
604 v
->ulType
= tvb_get_letohl(tvb
, offset
);
605 str
= val_to_str(v
->ulType
, RT_VALS
, "0x%.8x");
606 ti
= proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType: %s (0x%.8x)",
607 str
[0] == '0' ? "" : str
, v
->ulType
);
608 proto_item_append_text(item
, " Type: %s", str
);
611 v
->Weight
= tvb_get_letohl(tvb
, offset
);
612 ti
= proto_tree_add_text(tree
, tvb
, offset
, 4, "Weight: %u", v
->ulType
);
623 v
->u
.RTAnd
= ep_alloc(sizeof(struct CNodeRestriction
)); //XXX
624 offset
= parse_CNodeRestriction(tvb
, offset
, tree
, pad_tree
, v
->u
.RTAnd
, "CNodeRestriction");
629 v
->u
.RTNot
= ep_alloc(sizeof(struct CRestriction
)); //XXX
630 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
,
631 v
->u
.RTNot
, "CRestriction");
636 v
->u
.RTProperty
= ep_alloc(sizeof(struct CPropertyRestriction
)); //XXX
637 offset
= parse_CPropertyRestriction(tvb
, offset
, tree
, pad_tree
,
638 v
->u
.RTProperty
, "CPropertyRestriction");
642 case RTCoerce_Multiply
:
643 case RTCoerce_Absolute
:
645 v
->u
.RTCoerce_Add
= ep_alloc(sizeof(struct CCoercionRestriction
)); //XXX
646 offset
= parse_CCoercionRestriction(tvb
, offset
, tree
, pad_tree
,
647 v
->u
.RTCoerce_Add
, "CCoercionRestriction");
651 v
->u
.RTContent
= ep_alloc(sizeof(struct CContentRestriction
)); //XXX
652 offset
= parse_CContentRestriction(tvb
, offset
, tree
, pad_tree
,
653 v
->u
.RTContent
, "CContentRestriction");
657 v
->u
.RTReuseWhere
= ep_alloc(sizeof(struct CReuseWhere
)); //XXX
658 offset
= parse_CReuseWhere(tvb
, offset
, tree
, pad_tree
,
659 v
->u
.RTReuseWhere
, "CReuseWhere");
663 fprintf(stderr
, "CRestriciont 0x%08x not Supported\n", v
->ulType
);
664 proto_item_append_text(item
, " Not supported!");
667 proto_item_set_end(item
, tvb
, offset
);
671 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
672 proto_tree
*pad_tree
, struct CNodeRestriction
*v
,
673 const char *fmt
, ...)
676 proto_item
*item
, *ti
;
681 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
683 tree
= proto_item_add_subtree(item
, ett_CNodeRestriction
);
685 v
->cNode
= tvb_get_letohl(tvb
, offset
);
686 ti
= proto_tree_add_text(tree
, tvb
, offset
, 4, "cNode: %u", v
->cNode
);
688 for (i
=0; i
<v
->cNode
; i
++) {
689 struct CRestriction r
;
691 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paNode[%u]", i
); /*at begin or end of loop ????*/
692 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "paNode[%u]", i
);
694 // offset = parse_padding(tvb, offset, 4, pad_tree, "paNode[%u]", i); /*at begin or end of loop ????*/
697 proto_item_set_end(item
, tvb
, offset
);
702 /*****************************************************************************************/
704 static int vvalue_tvb_get0(tvbuff_t
*tvb _U_
, int offset _U_
, void *val _U_
)
709 static int vvalue_tvb_get1(tvbuff_t
*tvb
, int offset
, void *val
)
711 guint8
*ui1
= (guint8
*)val
;
712 *ui1
= tvb_get_guint8(tvb
, offset
);
716 static int vvalue_tvb_get2(tvbuff_t
*tvb
, int offset
, void *val
)
718 guint16
*ui2
= (guint16
*)val
;
719 *ui2
= tvb_get_letohs(tvb
, offset
);
723 static int vvalue_tvb_get4(tvbuff_t
*tvb
, int offset
, void *val
)
725 guint32
*ui4
= (guint32
*)val
;
726 *ui4
= tvb_get_letohl(tvb
, offset
);
730 static int vvalue_tvb_get8(tvbuff_t
*tvb
, int offset
, void *val
)
732 guint64
*ui8
= (guint64
*)val
;
733 *ui8
= tvb_get_letoh64(tvb
, offset
);
737 static int vvalue_tvb_blob(tvbuff_t
*tvb
, int offset
, void *val
)
739 struct data_blob
*blob
= (struct data_blob
*)val
;
740 guint32 len
= tvb_get_letohl(tvb
, offset
);
741 const guint8
*data
= tvb_get_ptr(tvb
, offset
+ 4, len
);
744 blob
->data
= se_memdup(data
, len
);
749 static int vvalue_tvb_bstr(tvbuff_t
*tvb
, int offset
, void *val
)
751 struct data_str
*str
= (struct data_str
*)val
;
752 guint32 len
= tvb_get_letohl(tvb
, offset
);
753 const void *ptr
= tvb_get_ptr(tvb
, offset
+ 4, len
);
755 //XXX this might be UTF-16
757 str
->str
= se_strndup(ptr
, len
);
761 static int vvalue_tvb_lpstr(tvbuff_t
*tvb
, int offset
, void *val
)
763 struct data_str
*str
= (struct data_str
*)val
;
766 str
->len
= tvb_get_letohl(tvb
, offset
);
767 str
->str
= tvb_get_seasonal_stringz(tvb
, offset
+ 4, &len
);
768 /* XXX test str->len == len */
772 static int vvalue_tvb_lpwstr(tvbuff_t
*tvb
, int offset
, void *val
)
774 struct data_str
*str
= (struct data_str
*)val
;
778 str
->len
= tvb_get_letohl(tvb
, offset
);
780 ptr
= tvb_get_ephemeral_unicode_stringz(tvb
, offset
+ 4, &len
, ENC_LITTLE_ENDIAN
);
781 str
->str
= se_strdup (ptr
);
786 static int vvalue_tvb_vector_internal(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
, int num
)
788 const int offset_in
= offset
;
789 const gboolean varsize
= (type
->size
== -1);
790 const int elsize
= varsize
? (int)sizeof(struct data_blob
) : type
->size
;
791 guint8
*data
= se_alloc(elsize
* num
);
795 val
->u
.vt_ui1
= data
;
796 DISSECTOR_ASSERT((void*)&val
->u
== ((void*)&val
->u
.vt_ui1
));
798 for (i
=0; i
<num
; i
++) {
799 len
= type
->tvb_get(tvb
, offset
, data
);
802 if (varsize
&& (offset
% 4) ) { /* at begin or end of loop ??? */
803 int padding
= 4 - (offset
% 4);
807 return offset
- offset_in
;
810 static int vvalue_tvb_vector(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
)
812 const int num
= tvb_get_letohl(tvb
, offset
);
813 return 4 + vvalue_tvb_vector_internal(tvb
, offset
+4, val
, type
, num
);
816 static void vvalue_strbuf_append_null(emem_strbuf_t
*strbuf _U_
, void *ptr _U_
)
819 static void vvalue_strbuf_append_i1(emem_strbuf_t
*strbuf
, void *ptr
)
821 gint8 i1
= *(gint8
*)ptr
;
822 ep_strbuf_append_printf(strbuf
, "%d", (int)i1
);
825 static void vvalue_strbuf_append_i2(emem_strbuf_t
*strbuf
, void *ptr
)
827 gint16 i2
= *(gint16
*)ptr
;
828 ep_strbuf_append_printf(strbuf
, "%d", (int)i2
);
831 static void vvalue_strbuf_append_i4(emem_strbuf_t
*strbuf
, void *ptr
)
833 gint32 i4
= *(gint32
*)ptr
;
834 ep_strbuf_append_printf(strbuf
, "%d", i4
);
837 static void vvalue_strbuf_append_i8(emem_strbuf_t
*strbuf
, void *ptr
)
839 gint64 i8
= *(gint64
*)ptr
;
840 ep_strbuf_append_printf(strbuf
, "%ld", i8
);
843 static void vvalue_strbuf_append_ui1(emem_strbuf_t
*strbuf
, void *ptr
)
845 guint8 ui1
= *(guint8
*)ptr
;
846 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui1
);
849 static void vvalue_strbuf_append_ui2(emem_strbuf_t
*strbuf
, void *ptr
)
851 guint16 ui2
= *(guint16
*)ptr
;
852 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui2
);
855 static void vvalue_strbuf_append_ui4(emem_strbuf_t
*strbuf
, void *ptr
)
857 guint32 ui4
= *(guint32
*)ptr
;
858 ep_strbuf_append_printf(strbuf
, "%d", ui4
);
861 static void vvalue_strbuf_append_ui8(emem_strbuf_t
*strbuf
, void *ptr
)
863 guint64 ui8
= *(guint64
*)ptr
;
864 ep_strbuf_append_printf(strbuf
, "%lu", ui8
);
867 static void vvalue_strbuf_append_r4(emem_strbuf_t
*strbuf
, void *ptr
)
869 float r4
= *(float*)ptr
;
870 ep_strbuf_append_printf(strbuf
, "%g", (double)r4
);
873 static void vvalue_strbuf_append_r8(emem_strbuf_t
*strbuf
, void *ptr
)
875 double r8
= *(double*)ptr
;
876 ep_strbuf_append_printf(strbuf
, "%g", r8
);
879 static void vvalue_strbuf_append_str(emem_strbuf_t
*strbuf
, void *ptr
)
881 struct data_str
*str
= (struct data_str
*)ptr
;
882 ep_strbuf_append_printf(strbuf
, "\"%s\"", str
->str
);
885 static void vvalue_strbuf_append_blob(emem_strbuf_t
*strbuf
, void *ptr
)
887 struct data_blob
*blob
= (struct data_blob
*)ptr
;
888 ep_strbuf_append_printf(strbuf
, "size: %d", (int)blob
->size
);
891 static void vvalue_strbuf_append_bool(emem_strbuf_t
*strbuf
, void *ptr
)
893 guint16 val
= *(guint
*)ptr
;
896 ep_strbuf_append(strbuf
, "False");
899 ep_strbuf_append(strbuf
, "True");
902 ep_strbuf_append_printf(strbuf
, "Invalid (0x%4x)", val
);
906 static void vvalue_strbuf_append_vector(emem_strbuf_t
*strbuf
, struct vt_vector val
, struct vtype
*type
)
908 const int elsize
= (type
->size
== -1) ? (int)sizeof(struct data_blob
) : type
->size
;
910 guint8
*data
= val
.u
.vt_ui1
;
911 ep_strbuf_append_c(strbuf
, '[');
912 for (i
=0; i
<val
.len
; i
++) {
914 ep_strbuf_append_c(strbuf
, ',');
916 type
->strbuf_append(strbuf
, data
);
919 ep_strbuf_append_c(strbuf
, ']');
923 static struct vtype VT_TYPE
[] = {
924 {VT_EMPTY
, "VT_EMPTY", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
925 {VT_NULL
, "VT_NULL", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
926 {VT_I2
, "VT_I2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_i2
},
927 {VT_I4
, "VT_I4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
928 {VT_R4
, "VT_R4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_r4
},
929 {VT_R8
, "VT_R8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
930 {VT_CY
, "VT_CY", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
931 {VT_DATE
, "VT_DATE", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
932 // {VT_BSTR, "VT_BSTR", -1, vvalue_tvb_bstr, vvalue_strbuf_append_str},
933 {VT_BSTR
, "VT_BSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
934 {VT_ERROR
, "VT_ERROR", 8, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
935 {VT_BOOL
, "VT_BOOL", 2, vvalue_tvb_get2
, vvalue_strbuf_append_bool
},
936 {VT_VARIANT
, "VT_VARIANT", -1, NULL
, NULL
},
937 {VT_DECIMAL
, "VT_DECIMAL", 16, NULL
, NULL
},
938 {VT_I1
, "VT_I1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_i1
},
939 {VT_UI1
, "VT_UI1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_ui1
},
940 {VT_UI2
, "VT_UI2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_ui2
},
941 {VT_UI4
, "VT_UI4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
942 {VT_I8
, "VT_I8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
943 {VT_UI8
, "VT_UI8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_ui8
},
944 {VT_INT
, "VT_INT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
945 {VT_UINT
, "VT_UINT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
946 {VT_LPSTR
, "VT_LPSTR", -1, vvalue_tvb_lpstr
, vvalue_strbuf_append_str
},
947 {VT_LPWSTR
, "VT_LPWSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
948 {VT_COMPRESSED_LPWSTR
, "VT_COMPRESSED_LPWSTR", -1, NULL
, vvalue_strbuf_append_str
},
949 {VT_FILETIME
, "VT_FILETIME", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
950 {VT_BLOB
, "VT_BLOB", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
951 {VT_BLOB_OBJECT
, "VT_BLOB_OBJECT", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
952 {VT_CLSID
, "VT_CLSID", 16, NULL
, NULL
},
955 static struct vtype
*vType_get_type(enum vType t
) {
958 for (i
=0; i
<array_length(VT_TYPE
); i
++) {
959 if (t
== VT_TYPE
[i
].tag
) {
966 static char *str_CBaseStorageVariant(struct CBaseStorageVariant
*value
, gboolean print_type
)
969 emem_strbuf_t
*strbuf
= ep_strbuf_new(NULL
);
974 if (value
->type
== NULL
) {
979 ep_strbuf_append(strbuf
, value
->type
->str
);
981 if (value
->vType
& 0xFF00) {
982 ep_strbuf_append_printf(strbuf
, "[%d]", value
->vValue
.vt_vector
.len
);
984 ep_strbuf_append(strbuf
, ": ");
987 switch (value
->vType
& 0xFF00) {
989 value
->type
->strbuf_append(strbuf
, &value
->vValue
);
992 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_array
.vData
, value
->type
);
995 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_vector
, value
->type
);
998 ep_strbuf_append(strbuf
, "Invalid");
1004 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1005 struct CBaseStorageVariant
*value
, const char *text
)
1008 proto_item
*ti
, *ti_type
, *ti_val
;
1009 proto_tree
*tree
, *tr
;
1010 enum vType baseType
, highType
;
1012 ZERO_STRUCT(*value
);
1014 ti
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1015 tree
= proto_item_add_subtree(ti
, ett_CBaseStorageVariant
);
1017 value
->vType
= tvb_get_letohs(tvb
, offset
);
1018 value
->type
= vType_get_type(value
->vType
);
1020 ti_type
= proto_tree_add_text(tree
, tvb
, offset
, 2, "vType: %s", value
->type
->str
);
1023 value
->vData1
= tvb_get_guint8(tvb
, offset
);
1024 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData1: %d", value
->vData1
);
1027 value
->vData2
= tvb_get_guint8(tvb
, offset
);
1028 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData2: %d", value
->vData2
);
1031 baseType
= value
->vType
& 0x00FF;
1032 highType
= value
->vType
& 0xFF00;
1034 if (value
->type
== NULL
) {
1038 ti_val
= proto_tree_add_text(tree
, tvb
, offset
, 0, "vValue");
1042 len
= value
->type
->tvb_get(tvb
, offset
, &value
->vValue
.vt_single
);
1046 proto_item_append_text(ti_type
, "|VT_VECTOR");
1047 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Vector
);
1049 len
= vvalue_tvb_vector(tvb
, offset
, &value
->vValue
.vt_vector
, value
->type
);
1050 proto_tree_add_text(tr
, tvb
, offset
, 4, "num: %d", value
->vValue
.vt_vector
.len
);
1054 guint16 cDims
, fFeatures
;
1055 guint32 cbElements
, cElements
, lLbound
;
1058 proto_item_append_text(ti_type
, "|VT_ARRAY");
1059 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Array
);
1061 cDims
= tvb_get_letohs(tvb
, offset
);
1062 proto_tree_add_text(tr
, tvb
, offset
, 2, "cDims: %d", cDims
);
1065 fFeatures
= tvb_get_letohs(tvb
, offset
);
1066 proto_tree_add_text(tr
, tvb
, offset
, 2, "fFeaturess: %d", fFeatures
);
1069 cbElements
= tvb_get_letohl(tvb
, offset
);
1070 proto_tree_add_text(tr
, tvb
, offset
, 4, "cbElements: %d", cbElements
);
1072 for (i
=0; i
<cDims
; i
++) {
1073 cElements
= tvb_get_letohl(tvb
, offset
);
1074 lLbound
= tvb_get_letohl(tvb
, offset
+ 4);
1075 proto_tree_add_text(tr
, tvb
, offset
, 8, "Rgsabound[%d]: (%d:%d)", i
, cElements
, lLbound
);
1080 len
= vvalue_tvb_vector_internal(tvb
, offset
, &value
->vValue
.vt_array
.vData
, value
->type
, num
);
1085 proto_item_append_text(ti_type
, "|0x%x", highType
);
1087 proto_item_set_end(ti
, tvb
, offset
);
1088 proto_item_set_end(ti_val
, tvb
, offset
);
1090 proto_item_append_text(ti_val
, " %s", str_CBaseStorageVariant(value
, false));
1091 proto_item_append_text(ti
, " %s", str_CBaseStorageVariant(value
, true));
1096 proto_item_append_text(ti
, ": sorry, vType %02x not handled yet!", (unsigned)value
->vType
);
1102 DBKIND_GUID_NAME
= 0,
1103 DBKIND_GUID_PROPID
= 1
1106 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
)
1108 guint32 eKind
, ulId
;
1110 static const char *KIND
[] = {"DBKIND_GUID_NAME", "DBKIND_GUID_PROPID"};
1112 proto_item
*tree_item
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1113 proto_tree
*tree
= proto_item_add_subtree(tree_item
, ett_CDbColId
);
1115 eKind
= tvb_get_letohl(tvb
, offset
);
1116 proto_tree_add_text(tree
, tvb
, offset
, 4, "eKind: %s (%u)", eKind
< 2 ? KIND
[eKind
] : "???", eKind
);
1119 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingGuidAlign");
1121 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "GUID");
1123 ulId
= tvb_get_letohl(tvb
, offset
);
1124 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulId: %d", ulId
);
1127 if (eKind
== DBKIND_GUID_NAME
) {
1129 int len
= ulId
; //*2 ???
1130 name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
1131 proto_tree_add_text(tree
, tvb
, offset
, len
, "vString: \"%s\"", name
);
1132 proto_item_append_text(tree_item
, " \"%s\"", name
);
1134 } else if (eKind
== DBKIND_GUID_PROPID
) {
1135 proto_item_append_text(tree_item
, " %08x", ulId
);
1137 proto_item_append_text(tree_item
, "<INVALID>");
1140 proto_item_set_end(tree_item
, tvb
, offset
);
1145 struct GuidPropertySet
{
1149 const value_string
*id_map
;
1152 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1153 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
1154 const char *fmt
, ...)
1156 static const value_string EMPTY_VS
[] = {{0, NULL
}};
1157 const value_string
*vs
= (propset
&& propset
->id_map
) ? propset
->id_map
: EMPTY_VS
;
1158 guint32 id
, opt
, status
;
1159 struct CBaseStorageVariant value
;
1166 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1169 tree
= proto_item_add_subtree(item
, ett_CDbProp
);
1171 id
= tvb_get_letohl(tvb
, offset
);
1172 str
= val_to_str(id
, vs
, "0x%08x");
1173 proto_tree_add_text(tree
, tvb
, offset
, 4, "Id: %s (0x%08x)", str
[0] == '0' ? "" : str
, id
);
1175 proto_item_append_text(item
, " Id: %s", str
);
1177 opt
= tvb_get_letohl(tvb
, offset
);
1178 proto_tree_add_text(tree
, tvb
, offset
, 4, "Options: %08x", opt
);
1181 status
= tvb_get_letohl(tvb
, offset
);
1182 proto_tree_add_text(tree
, tvb
, offset
, 4, "Status: %08x", status
);
1185 offset
= parse_CDbColId(tvb
, offset
, tree
, pad_tree
, "colid");
1187 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &value
, "vValue");
1189 str
= str_CBaseStorageVariant(&value
, true);
1190 proto_item_append_text(item
, " %s", str
);
1191 proto_item_set_end(item
, tvb
, offset
);
1197 static const value_string DBPROPSET_FSCIFRMWRK_EXT_IDS
[] = {
1198 {0x02, "DBPROP_CI_CATALOG_NAME"},
1199 {0x03, "DBPROP_CI_INCLUDE_SCOPES"},
1200 {0x04, "DBPROP_CI_SCOPE_FLAGS"},
1201 {0x07, "DBPROP_CI_QUERY_TYPE"},
1205 static const value_string DBPROPSET_QUERYEXT_IDS
[] = {
1206 {0x02, "DBPROP_USECONTENTINDEX"},
1207 {0x03, "DBPROP_DEFERNONINDEXEDTRIMMING"},
1208 {0x04, "DBPROP_USEEXTENDEDDBTYPES"},
1209 {0x05, "DBPROP_IGNORENOISEONLYCLAUSES"},
1210 {0x06, "DBPROP_GENERICOPTIONS_STRING"},
1211 {0x07, "DBPROP_FIRSTROWS"},
1212 {0x08, "DBPROP_DEFERCATALOGVERIFICATION"},
1213 {0x0a, "DBPROP_GENERATEPARSETREE"},
1214 {0x0c, "DBPROP_FREETEXTANYTERM"},
1215 {0x0d, "DBPROP_FREETEXTUSESTEMMING"},
1216 {0x0e, "DBPROP_IGNORESBRI"},
1217 {0x10, "DBPROP_ENABLEROWSETEVENTS"},
1221 static const value_string DBPROPSET_CIFRMWRKCORE_EXT_IDS
[] = {
1222 {0x02, "DBPROP_MACHINE"},
1223 {0x03, "DBPROP_CLIENT_CLSID"},
1227 static const value_string DBPROPSET_MSIDXS_ROWSETEXT_IDS
[] = {
1228 {0x02, "MSIDXSPROP_ROWSETQUERYSTATUS"},
1229 {0x03, "MSIDXSPROP_COMMAND_LOCALE_STRING"},
1230 {0x04, "MSIDXSPROP_QUERY_RESTRICTION"},
1231 {0x05, "MSIDXSPROP_PARSE_TREE"},
1232 {0x06, "MSIDXSPROP_MAX_RANK"},
1233 {0x07, "MSIDXSPROP_RESULTS_FOUND"},
1237 static struct GuidPropertySet GuidPropertySet
[] = {
1238 {{0xa9bd1526, 0x6a80, 0x11d0, {0x8c, 0x9d, 0x00, 0x20, 0xaf, 0x1d, 0x74, 0x0e}},
1239 "DBPROPSET_FSCIFRMWRK_EXT", "File system content index framework",
1240 DBPROPSET_FSCIFRMWRK_EXT_IDS
},
1241 {{0xa7ac77ed, 0xf8d7, 0x11ce, {0xa7, 0x98, 0x00, 0x20, 0xf8, 0x00, 0x80, 0x25}},
1242 "DBPROPSET_QUERYEXT", "Query extension",
1243 DBPROPSET_QUERYEXT_IDS
},
1244 {{0xafafaca5, 0xb5d1, 0x11d0, {0x8c, 0x62, 0x00, 0xc0, 0x4f, 0xc2, 0xdb, 0x8d}},
1245 "DBPROPSET_CIFRMWRKCORE_EXT", "Content index framework core",
1246 DBPROPSET_CIFRMWRKCORE_EXT_IDS
},
1247 {{0xAA6EE6B0, 0xE828, 0x11D0, {0xB2, 0x3E, 0x00, 0xAA, 0x00, 0x47, 0xFC, 0x01}},
1248 "DBPROPSET_MSIDXS_ROWSETEXT", "???",
1249 DBPROPSET_MSIDXS_ROWSETEXT_IDS
},
1252 static struct GuidPropertySet
*GuidPropertySet_find_guid(const e_guid_t
*guid
)
1255 for (i
=0; i
<array_length(GuidPropertySet
); i
++) {
1256 if (guid_cmp(&GuidPropertySet
[i
].guid
, guid
) == 0) {
1257 return &GuidPropertySet
[i
];
1263 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1264 proto_tree
*pad_tree
, const char *fmt
, ...)
1268 struct GuidPropertySet
*pset
;
1274 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1277 tree
= proto_item_add_subtree(item
, ett_CDbPropSet
);
1279 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "guidPropertySet");
1281 pset
= GuidPropertySet_find_guid(&guid
);
1284 proto_item_append_text(item
, " \"%s\" (%s)", pset
->desc
, pset
->def
);
1286 const char *guid_str
= guid_to_str(&guid
);
1287 proto_item_append_text(item
, " {%s}", guid_str
);
1290 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "guidPropertySet");
1292 num
= tvb_get_letohl(tvb
, offset
);
1293 proto_tree_add_text(tree
, tvb
, offset
, 4, "cProperties: %d", num
);
1295 proto_item_append_text(item
, " Num: %d", num
);
1297 for (i
= 0; i
<num
; i
++) {
1298 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "aProp[%d]", i
);
1299 offset
= parse_CDbProp(tvb
, offset
, tree
, pad_tree
, pset
, "aProp[%d]", i
);
1302 proto_item_set_end(item
, tvb
, offset
);
1306 static int parse_PropertySetArray(tvbuff_t
*tvb
, int offset
, int size_offset
,
1307 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1308 const char *fmt
, ...)
1310 const int offset_in
= offset
;
1318 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1321 tree
= proto_item_add_subtree(item
, ett_CDbPropSet_Array
);
1323 size
= tvb_get_letohl(tvb
, size_offset
);
1324 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_Blob1
, tvb
,
1325 size_offset
, 4, ENC_LITTLE_ENDIAN
);
1327 num
= tvb_get_letohl(tvb
, offset
);
1328 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_PropSets_num
, tvb
,
1329 offset
, 4, ENC_LITTLE_ENDIAN
);
1332 for (i
= 0; i
< (int)num
; i
++) {
1333 offset
= parse_CDbPropSet(tvb
, offset
, tree
, pad_tree
, "PropertySet[%d]", i
);
1336 proto_item_set_end(item
, tvb
, offset
);
1337 DISSECTOR_ASSERT(offset
- offset_in
== (int)size
);
1341 int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...)
1343 guint32 count
, v
, i
;
1349 item
= proto_tree_add_text_valist(tree
, tvb
, offset
, 0, fmt
, ap
);
1352 count
= tvb_get_letohl(tvb
, offset
);
1355 proto_item_append_text(item
, " Count %u [", count
);
1356 for (i
=0; i
<count
; i
++) {
1357 v
= tvb_get_letohl(tvb
, offset
);
1360 proto_item_append_text(item
, ",%u", v
);
1362 proto_item_append_text(item
, "%u", v
);
1365 proto_item_append_text(item
, "]");
1369 /* 2.2.1.23 RANGEBOUNDARY */
1370 int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1371 proto_tree
*pad_tree
, const char *fmt
, ...)
1374 guint8 labelPresent
;
1377 struct CBaseStorageVariant prval
;
1381 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1382 tree
= proto_item_add_subtree(item
, ett_RANGEBOUNDARY
);
1385 ulType
= tvb_get_letohl(tvb
, offset
);
1386 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType 0x%08x", ulType
);
1387 proto_item_append_text(item
, ": Type 0x%08x", ulType
);
1391 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &prval
, "prVal");
1393 labelPresent
= tvb_get_guint8(tvb
, offset
);
1394 proto_tree_add_text(tree
, tvb
, offset
, 1, "labelPresent: %s", labelPresent
? "True" : "False");
1400 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingLabelPresent");
1402 ccLabel
= tvb_get_letohl(tvb
, offset
);
1403 proto_tree_add_text(tree
, tvb
, offset
, 4, "ccLabel: %u", ccLabel
);
1406 label
= tvb_get_unicode_string(tvb
, offset
, 2*ccLabel
, ENC_LITTLE_ENDIAN
);
1407 proto_tree_add_text(tree
, tvb
, offset
, 2*ccLabel
, "Label: \"%s\"", label
);
1408 proto_item_append_text(item
, " Label: \"%s\"", label
);
1409 offset
+= 2*ccLabel
;
1412 proto_item_append_text(item
, " Val: %s", str_CBaseStorageVariant(&prval
, true));
1414 proto_item_set_end(item
, tvb
, offset
);
1419 /* 2.2.1.22 CRangeCategSpec */
1420 int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
1421 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1422 const char *fmt
, ...)
1428 guint32 lcid
, cRange
;
1431 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1432 tree
= proto_item_add_subtree(item
, ett_CRangeCategSpec
);
1435 lcid
= tvb_get_letohl(tvb
, offset
);
1436 proto_tree_add_text(tree
, tvb
, offset
, 4, "Lcid 0x%08x", lcid
);
1439 cRange
= tvb_get_letohl(tvb
, offset
);
1440 proto_tree_add_text(tree
, tvb
, offset
, 4, "cRange 0x%08x", cRange
);
1443 for (i
=0; i
<cRange
; i
++) {
1444 offset
= parse_RANGEBOUNDARY(tvb
, offset
, tree
, pad_tree
, "aRangeBegin[%u]", i
);
1448 proto_item_set_end(item
, tvb
, offset
);
1452 /* 2.2.1.21 CCategSpec */
1453 int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
1454 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1455 const char *fmt
, ...)
1464 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1465 tree
= proto_item_add_subtree(item
, ett_CCategSpec
);
1468 type
= tvb_get_letohl(tvb
, offset
);
1469 proto_tree_add_text(tree
, tvb
, offset
, 4, "Type 0x%08x", type
);
1470 proto_item_append_text(item
, " Type %u", type
);
1473 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "CSort");
1475 offset
= parse_CRangeCategSpec(tvb
, offset
, tree
, pad_tree
, "CRangeCategSpec");
1477 proto_item_set_end(item
, tvb
, offset
);
1481 /* 2.2.1.25 CAggregSpec */
1482 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
1483 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1484 const char *fmt
, ...)
1490 guint32 ccAlias
, idColumn
, ulMaxNumToReturn
, idRepresentative
;
1494 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1495 tree
= proto_item_add_subtree(item
, ett_CAggregSpec
);
1498 type
= tvb_get_guint8(tvb
, offset
);
1499 proto_tree_add_text(tree
, tvb
, offset
, 1, "type: %u", type
);
1500 proto_item_append_text(item
, "type: %u", type
);
1503 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding");
1505 ccAlias
= tvb_get_letohl(tvb
, offset
);
1506 proto_tree_add_text(tree
, tvb
, offset
, 1, "ccAlias: %u", ccAlias
);
1509 alias
= tvb_get_unicode_string(tvb
, offset
, 2*ccAlias
, ENC_LITTLE_ENDIAN
);
1510 proto_tree_add_text(tree
, tvb
, offset
, 2*ccAlias
, "Alias: %s", alias
);
1511 offset
+= 2*ccAlias
;
1513 idColumn
= tvb_get_letohl(tvb
, offset
);
1514 proto_tree_add_text(tree
, tvb
, offset
, 1, "idColumn: %u", idColumn
);
1517 ulMaxNumToReturn, idRepresentative;
1519 fprintf(stderr
, "WARNING, dont know if optional members are present!\n ");
1521 proto_item_set_end(item
, tvb
, offset
);
1525 /* 2.2.1.24 CAggregSet */
1526 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
1527 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1528 const char *fmt
, ...)
1537 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1538 tree
= proto_item_add_subtree(item
, ett_CAggregSet
);
1541 cCount
= tvb_get_letohl(tvb
, offset
);
1542 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1545 for (i
=0; i
<cCount
; i
++) {
1546 /* 2.2.1.25 CAggregSpec */
1547 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "AggregSpecs[%u]", i
);
1550 proto_item_set_end(item
, tvb
, offset
);
1554 /* 2.2.1.27 CAggregSortKey */
1555 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
1556 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1557 const char *fmt
, ...)
1566 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1567 tree
= proto_item_add_subtree(item
, ett_CAggregSortKey
);
1570 order
= tvb_get_letohl(tvb
, offset
);
1571 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", order
);
1574 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "ColumnSpec");
1576 proto_item_set_end(item
, tvb
, offset
);
1581 /* 2.2.1.26 CSortAggregSet */
1582 static int parse_CSortAggregSet(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_CSortAggregSet
);
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.27 CAggregSortKey */
1603 offset
= parse_CAggregSortKey(tvb
, offset
, tree
, pad_tree
, "SortKeys[%u]", i
);
1606 proto_item_set_end(item
, tvb
, offset
);
1610 enum CInGroupSortAggregSet_type
{
1611 GroupIdDefault
= 0x00, /* The default for all ranges. */
1612 GroupIdMinValue
= 0x01, /*The first range in the parent's group.*/
1613 GroupIdNull
= 0x02, /*The last range in the parent's group.*/
1614 GroupIdValue
= 0x03,
1617 /* 2.2.1.29 CInGroupSortAggregSet */
1618 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
1619 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1620 const char *fmt
, ...)
1625 enum CInGroupSortAggregSet_type type
;
1628 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1629 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSet
);
1632 type
= tvb_get_guint8(tvb
, offset
);
1633 proto_tree_add_text(tree
, tvb
, offset
, 1, "Type: 0x%02x", (unsigned)type
);
1636 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "CInGroupSortAggregSet");
1638 if (type
== GroupIdValue
) {
1639 struct CBaseStorageVariant id
;
1640 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &id
, "inGroupId");
1643 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1645 proto_item_set_end(item
, tvb
, offset
);
1650 /* 2.2.1.28 CInGroupSortAggregSets */
1651 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
1652 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1653 const char *fmt
, ...)
1662 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1663 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSets
);
1666 cCount
= tvb_get_letohl(tvb
, offset
);
1667 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1670 for (i
=0; i
<cCount
; i
++) {
1671 /* 2.2.1.29 CInGroupSortAggregSet */
1672 offset
= parse_CInGroupSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortSets[%u]", i
);
1675 proto_item_set_end(item
, tvb
, offset
);
1679 /* 2.2.1.20 CCategorizationSpec */
1680 int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
1681 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1682 const char *fmt
, ...)
1684 guint32 cMaxResults
;
1691 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1692 tree
= proto_item_add_subtree(item
, ett_CCategorizationSpec
);
1695 /* 2.2.1.18 CColumnSet */
1696 offset
= parse_CColumnSet(tvb
, offset
, tree
, "csColumns");
1698 /* 2.2.1.21 CCategSpec */
1699 offset
= parse_CCategSpec(tvb
, offset
, tree
, pad_tree
, "Spec");
1701 /* 2.2.1.24 CAggregSet */
1702 offset
= parse_CAggregSet(tvb
, offset
, tree
, pad_tree
, "AggregSet");
1704 /* 2.2.1.26 CSortAggregSet */
1705 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1707 /* 2.2.1.28 CInGroupSortAggregSets */
1708 offset
= parse_CInGroupSortAggregSets(tvb
, offset
, tree
, pad_tree
, "InGroupSortAggregSets");
1710 cMaxResults
= tvb_get_letohl(tvb
, offset
);
1711 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", cMaxResults
);
1714 proto_item_set_end(item
, tvb
, offset
);
1718 int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
1719 proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1720 const char *fmt
, ...)
1729 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1730 tree
= proto_item_add_subtree(item
, ett_CRowsetProperties
);
1733 proto_tree_add_text(tree
, tvb
, offset
, 4, "uBooleanOptions");
1736 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMaxOpenRows (ignored)");
1739 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMemoryUsage (ignored)");
1742 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults");
1745 proto_tree_add_text(tree
, tvb
, offset
, 4, "cCmdTimeout");
1748 proto_item_set_end(item
, tvb
, offset
);
1752 int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
1753 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1754 const char *fmt
, ...)
1762 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1763 tree
= proto_item_add_subtree(item
, ett_CPidMapper
);
1766 count
= tvb_get_letohl(tvb
, offset
);
1767 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
1770 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "CPidMapper_PropSpec");
1772 for (i
=0; i
<count
; i
++) {
1773 struct CFullPropSpec v
;
1775 offset
= parse_padding(tvb
, offset
, 4, pad_tree
,
1776 "CPidMapper_PropSpec[%u]", i
); //at begin or end of loop???
1777 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
, "PropSpec[%u]", i
);
1780 proto_item_set_end(item
, tvb
, offset
);
1784 /* Code to actually dissect the packets */
1786 static int dissect_CPMConnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
1794 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
1795 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
1796 proto_item_set_text(ti
, "CPMConnect%s", in
? "In" : "Out");
1797 col_append_str(pinfo
->cinfo
, COL_INFO
, "Connect");
1799 version
= tvb_get_letohl(tvb
, offset
);
1800 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_Connect_Version
, tvb
,
1801 offset
, 4, ENC_LITTLE_ENDIAN
);
1802 if (version
& 0xffff0000) {
1803 proto_item_append_text(ti
, " 64 bit");
1805 switch (version
& 0xffff) {
1807 proto_item_append_text(ti
, " w2k8 or vista");
1810 proto_item_append_text(ti
, " XP or w2k3, with Windows Search 4.0");
1813 proto_item_append_text(ti
, " win7 or w2k8r2");
1819 guint32 blob_size1_off
, blob_size2_off
;
1820 proto_tree
*pad_tree
;
1822 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
1823 pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
1825 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_ClientIsRemote
, tvb
,
1826 offset
, 4, ENC_LITTLE_ENDIAN
);
1830 blob_size1_off
= offset
;
1833 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcbBlob2");
1836 blob_size2_off
= offset
;
1839 offset
= parse_padding(tvb
, offset
, 16, pad_tree
, "_padding");
1841 len
= tvb_unicode_strsize(tvb
, offset
);
1842 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_MachineName
, tvb
,
1843 offset
, len
, ENC_UTF_16
);
1844 /*This shouldnt be necessary, is this a bug or is there some GUI setting I've missed?*/
1845 proto_item_set_text(ti
, "Remote machine: %s",
1846 tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
1849 len
= tvb_unicode_strsize(tvb
, offset
);
1850 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_UserName
, tvb
,
1851 offset
, len
, ENC_UTF_16
);
1852 proto_item_set_text(ti
, "User: %s", tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
1855 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcPropSets");
1857 offset
= parse_PropertySetArray(tvb
, offset
, blob_size1_off
, tree
, pad_tree
, "PropSets");
1859 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingExtPropset");
1861 offset
= parse_PropertySetArray(tvb
, offset
, blob_size2_off
, tree
, pad_tree
, "ExtPropset");
1863 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "???");
1865 DISSECTOR_ASSERT(offset
== (int)tvb_length(tvb
));
1867 /* make "Padding" the last item */
1868 proto_tree_move_item(tree
, ti
, proto_tree_get_parent(pad_tree
));
1872 return tvb_length(tvb
);
1875 static int dissect_CPMDisconnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1877 col_append_str(pinfo
->cinfo
, COL_INFO
, "Disconnect");
1878 return tvb_length(tvb
);
1881 static int dissect_CPMCreateQuery(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
1887 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
1888 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
1890 proto_item_set_text(ti
, "CPMCreateQuery%s", in
? "In" : "Out");
1891 col_append_str(pinfo
->cinfo
, COL_INFO
, "CreateQuery");
1894 proto_item
*ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
1895 proto_tree
*pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
1896 guint8 CColumnSetPresent
, CRestrictionPresent
, CSortSetPresent
, CCategorizationSetPresent
;
1897 guint32 size
= tvb_get_letohl(tvb
, offset
);
1898 proto_tree_add_text(tree
, tvb
, offset
, 4, "size");
1899 proto_tree_add_text(tree
, tvb
, offset
, size
, "ALL");
1902 CColumnSetPresent
= tvb_get_guint8(tvb
, offset
);
1903 proto_tree_add_text(tree
, tvb
, offset
, 1, "CColumnSetPresent: %s", CColumnSetPresent
? "True" : "False");
1906 if (CColumnSetPresent
) {
1907 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCColumnSetPresent");
1908 offset
= parse_CColumnSet(tvb
, offset
, tree
, "CColumnSet");
1911 CRestrictionPresent
= tvb_get_guint8(tvb
, offset
);
1912 proto_tree_add_text(tree
, tvb
, offset
, 1, "CRestrictionPresent: %s", CColumnSetPresent
? "True" : "False");
1914 if (CRestrictionPresent
) {
1915 guint8 count
, present
;
1917 count
= tvb_get_guint8(tvb
, offset
);
1918 present
= tvb_get_guint8(tvb
, offset
);
1919 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "CRestrictionSet: count %d", count
);
1922 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCRestrictionPresent");
1924 for (i
=0; i
<count
; i
++) {
1925 struct CRestriction r
;
1926 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "CRestrictionArray[%d]", i
);
1929 proto_item_set_end(ti
, tvb
, offset
);
1932 CSortSetPresent
= tvb_get_guint8(tvb
, offset
);
1933 proto_tree_add_text(tree
, tvb
, offset
, 1, "CSortSetPresent: %s", CSortSetPresent
? "True" : "False");
1935 if (CSortSetPresent
) {
1936 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCSortSetPresent");
1937 offset
= parse_CSortSet(tvb
, offset
, tree
, pad_tree
, "SortSet");
1940 CCategorizationSetPresent
= tvb_get_guint8(tvb
, offset
);
1941 proto_tree_add_text(tree
, tvb
, offset
, 1, "CCategorizationSetPresent: %s", CCategorizationSetPresent
? "True" : "False");
1944 if (CCategorizationSetPresent
) {
1946 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCCategorizationSetPresent");
1947 /* 2.2.1.19 CCategorizationSet */
1948 count
= tvb_get_letohl(tvb
, offset
);
1949 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
1951 for (i
=0; i
<count
; i
++) {
1952 offset
= parse_CCategorizationSpec(tvb
, offset
, tree
, pad_tree
, "categories[%u]", i
);
1956 offset
= parse_CRowsetProperties(tvb
, offset
, tree
, pad_tree
, "RowSetProperties");
1958 offset
= parse_CPidMapper(tvb
, offset
, tree
, pad_tree
, "PidMapper");
1961 return tvb_length(tvb
);
1964 static int dissect_CPMFreeCursor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1966 col_append_str(pinfo
->cinfo
, COL_INFO
, "FreeCursor");
1967 return tvb_length(tvb
);
1970 static int dissect_CPMGetRows(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1972 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRows");
1973 return tvb_length(tvb
);
1976 static int dissect_CPMRatioFinished(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1978 col_append_str(pinfo
->cinfo
, COL_INFO
, "RatioFinished");
1979 return tvb_length(tvb
);
1982 static int dissect_CPMCompareBmk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1984 col_append_str(pinfo
->cinfo
, COL_INFO
, "CompareBmk");
1985 return tvb_length(tvb
);
1988 static int dissect_CPMGetApproximatePosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1990 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetApproximatePosition");
1991 return tvb_length(tvb
);
1994 static int dissect_CPMSetBindings(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
1996 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetBindings");
1997 return tvb_length(tvb
);
2000 static int dissect_CPMGetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2002 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetNotify");
2003 return tvb_length(tvb
);
2006 static int dissect_CPMSendNotifyOut(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2008 col_append_str(pinfo
->cinfo
, COL_INFO
, "SendNotify");
2009 return tvb_length(tvb
);
2012 static int dissect_CPMGetQueryStatus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2014 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatus");
2015 return tvb_length(tvb
);
2018 static int dissect_CPMCiState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2020 col_append_str(pinfo
->cinfo
, COL_INFO
, "CiState");
2021 return tvb_length(tvb
);
2024 static int dissect_CPMFetchValue(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2026 col_append_str(pinfo
->cinfo
, COL_INFO
, "FetchValue");
2027 return tvb_length(tvb
);
2030 static int dissect_CPMGetQueryStatusEx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2032 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatusEx");
2033 return tvb_length(tvb
);
2036 static int dissect_CPMRestartPosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2038 col_append_str(pinfo
->cinfo
, COL_INFO
, "RestartPosition");
2039 return tvb_length(tvb
);
2042 static int dissect_CPMSetCatState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2044 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetCatState");
2045 return tvb_length(tvb
);
2048 static int dissect_CPMGetRowsetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2050 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRowsetNotify");
2051 return tvb_length(tvb
);
2054 static int dissect_CPMFindIndices(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2056 col_append_str(pinfo
->cinfo
, COL_INFO
, "FindIndices");
2057 return tvb_length(tvb
);
2060 static int dissect_CPMSetScopePrioritization(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2062 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetScopePrioritization");
2063 return tvb_length(tvb
);
2066 static int dissect_CPMGetScopeStatistics(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2068 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetScopeStatistics");
2069 return tvb_length(tvb
);
2074 dissect_mswsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gboolean in
)
2076 static const char *dbg_wait
= NULL
;
2077 static int wait_frame
= -1;
2079 proto_tree
*mswsp_tree
= NULL
;
2086 int (*fn
)(tvbuff_t
*, packet_info
*, proto_tree
*, gboolean
);
2088 if (tvb_length(tvb
) < 16) {
2092 if (dbg_wait
== NULL
) {
2093 dbg_wait
= getenv("DBG_FRAME");
2094 if (dbg_wait
== NULL
) {
2097 wait_frame
= atoi(dbg_wait
);
2101 if ((int)pinfo
->fd
->num
== wait_frame
) {
2102 static volatile gboolean wait
= 1;
2108 hdr
.msg
= tvb_get_letohl(tvb
, 0);
2112 fn
= dissect_CPMConnect
;
2115 fn
= dissect_CPMDisconnect
;
2118 fn
= dissect_CPMCreateQuery
;
2121 fn
= dissect_CPMFreeCursor
;
2124 fn
= dissect_CPMGetRows
;
2127 fn
= dissect_CPMRatioFinished
;
2130 fn
= dissect_CPMCompareBmk
;
2133 fn
= dissect_CPMGetApproximatePosition
;
2136 fn
= dissect_CPMSetBindings
;
2139 fn
= dissect_CPMGetNotify
;
2142 fn
= dissect_CPMSendNotifyOut
;
2145 fn
= dissect_CPMGetQueryStatus
;
2148 fn
= dissect_CPMCiState
;
2151 fn
= dissect_CPMFetchValue
;
2154 fn
= dissect_CPMGetQueryStatusEx
;
2157 fn
= dissect_CPMRestartPosition
;
2160 fn
= dissect_CPMSetCatState
;
2163 fn
= dissect_CPMGetRowsetNotify
;
2166 fn
= dissect_CPMFindIndices
;
2169 fn
= dissect_CPMSetScopePrioritization
;
2172 fn
= dissect_CPMGetScopeStatistics
;
2178 hdr
.status
= tvb_get_letohl(tvb
, 4);
2179 hdr
.checksum
= tvb_get_letohl(tvb
, 8);
2181 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MS-WSP");
2182 /* col_clear(pinfo->cinfo, COL_INFO); */
2184 col_set_str(pinfo
->cinfo
, COL_INFO
, "WSP ");
2185 col_append_str(pinfo
->cinfo
, COL_INFO
, in
? "Request: " : "Response: ");
2188 proto_tree
*hdr_tree
;
2189 proto_item
*ti
, *hti
;
2191 ti
= proto_tree_add_item(tree
, proto_mswsp
, tvb
, 0, -1, ENC_NA
);
2192 mswsp_tree
= proto_item_add_subtree(ti
, ett_mswsp
);
2194 hti
= proto_tree_add_item(mswsp_tree
, hf_mswsp_hdr
, tvb
, 0, 16, ENC_NA
);
2195 hdr_tree
= proto_item_add_subtree(hti
, ett_mswsp_hdr
);
2197 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_msg
, tvb
,
2198 0, 4, ENC_LITTLE_ENDIAN
);
2199 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_status
,
2200 tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
2201 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_checksum
,
2202 tvb
, 8, 4, ENC_LITTLE_ENDIAN
);
2203 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_reserved
, tvb
,
2204 12, 4, ENC_LITTLE_ENDIAN
);
2207 fn(tvb
, pinfo
, mswsp_tree
, in
);
2209 /* Return the amount of data this dissector was able to dissect */
2210 return tvb_length(tvb
);
2214 /* Register the protocol with Wireshark */
2216 /* this format is require because a script is used to build the C function
2217 that calls all the protocol registration.
2221 proto_register_mswsp(void)
2223 module_t
*mswsp_module
;
2225 /* Setup list of header fields See Section 1.6.1 for details*/
2226 static const value_string msg_ids
[] = {
2227 {0x000000C8, "CPMConnect"}, /* In/Out */
2228 {0x000000C9, "CPMDisconnect"},
2229 {0x000000CA, "CPMCreateQuery"}, /* In/Out */
2230 {0x000000CB, "CPMFreeCursor"}, /* In/Out */
2231 {0x000000CC, "CPMGetRows"}, /* In/Out */
2232 {0x000000CD, "CPMRatioFinished"}, /* In/Out */
2233 {0x000000CE, "CPMCompareBmk"}, /* In/Out */
2234 {0x000000CF, "CPMGetApproximatePosition"}, /* In/Out */
2235 {0x000000D0, "CPMSetBindingsIn"},
2236 {0x000000D1, "CPMGetNotify"},
2237 {0x000000D2, "CPMSendNotifyOut"},
2238 {0x000000D7, "CPMGetQueryStatusIn"}, /* In/Out */
2239 {0x000000D9, "CPMCiStateInOut"},
2240 {0x000000E4, "CPMFetchValue"}, /* In/Out */
2241 {0x000000E7, "CPMGetQueryStatusEx"}, /* In/Out */
2242 {0x000000E8, "CPMRestartPositionIn"},
2243 {0x000000EC, "CPMSetCatStateIn"}, /* (not supported) */
2244 {0x000000F1, "CPMGetRowsetNotify"}, /* In/Out */
2245 {0x000000F2, "CPMFindIndices"}, /* In/Out */
2246 {0x000000F3, "CPMSetScopePrioritization"}, /* In/Out */
2247 {0x000000F4, "CPMGetScopeStatistics"}, /* In/Out */
2249 static hf_register_info hf
[] = {
2251 { "Header", "mswsp.hdr",
2252 FT_NONE
, BASE_NONE
, NULL
, 0,
2253 "Message header", HFILL
}
2255 { &hf_mswsp_hdr_msg
,
2256 { "Msg id", "mswsp.hdr.id",
2257 FT_UINT32
, BASE_HEX
, VALS(msg_ids
), 0,
2258 "Message id", HFILL
}
2260 { &hf_mswsp_hdr_status
,
2261 { "Status", "mswsp.hdr.status",
2262 FT_UINT32
, BASE_HEX
, NULL
, 0,
2265 { &hf_mswsp_hdr_checksum
,
2266 { "checksum", "mswsp.hdr.checksum",
2267 FT_UINT32
, BASE_HEX
, NULL
, 0,
2270 { &hf_mswsp_hdr_reserved
,
2271 { "Reserved", "mswsp.hdr.reserved",
2272 FT_UINT32
, BASE_HEX
, NULL
, 0,
2276 { "msg", "mswsp.msg",
2277 FT_NONE
, BASE_NONE
, NULL
, 0,
2280 { &hf_mswsp_msg_Connect_Version
,
2281 { "Version", "mswsp.Connect.version",
2282 FT_UINT32
, BASE_HEX
, NULL
, 0,
2285 { &hf_mswsp_msg_ConnectIn_ClientIsRemote
,
2286 { "Remote", "mswsp.ConnectIn.isRemote",
2287 FT_BOOLEAN
, BASE_HEX
, NULL
, 0,
2288 "Client is remote",HFILL
}
2290 { &hf_mswsp_msg_ConnectIn_Blob1
,
2291 { "Size", "mswsp.ConnectIn.propset.size",
2292 FT_UINT32
, BASE_DEC
, NULL
, 0,
2293 "Size of PropSet fields",HFILL
}
2295 { &hf_mswsp_msg_ConnectIn_Blob2
,
2296 { "Size", "mswsp.ConnectIn.extpropset.size",
2297 FT_UINT32
, BASE_DEC
, NULL
, 0,
2298 "Size of ExtPropSet fields",HFILL
}
2300 { &hf_mswsp_msg_ConnectIn_MachineName
,
2301 { "Remote machine", "mswsp.ConnectIn.machine",
2302 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2303 "Name of remote machine",HFILL
}
2305 { &hf_mswsp_msg_ConnectIn_UserName
,
2306 { "User", "mswsp.ConnectIn.user",
2307 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2308 "Name of remote user",HFILL
}
2310 { &hf_mswsp_msg_ConnectIn_PropSets_num
,
2311 { "Num", "mswsp.ConnectIn.propset.num",
2312 FT_UINT32
, BASE_DEC
, NULL
, 0,
2313 "Number of Property Sets", HFILL
}
2315 { &hf_mswsp_msg_ConnectIn_ExtPropSets_num
,
2316 { "Num", "mswsp.ConnectIn.extpropset.num",
2317 FT_UINT32
, BASE_DEC
, NULL
, 0,
2318 "Number of extended Property Sets", HFILL
}
2323 /* Setup protocol subtree array */
2324 static gint
*ett
[] = {
2329 &ett_mswsp_property_restriction
,
2330 &ett_CRestrictionArray
,
2331 &ett_CBaseStorageVariant
,
2332 &ett_CBaseStorageVariant_Vector
,
2333 &ett_CBaseStorageVariant_Array
,
2338 &ett_CDbPropSet_Array
,
2340 &ett_CNodeRestriction
,
2341 &ett_CPropertyRestriction
,
2342 &ett_CCoercionRestriction
,
2343 &ett_CContentRestriction
,
2345 &ett_CRangeCategSpec
,
2349 &ett_CCategorizationSpec
,
2350 &ett_CAggregSortKey
,
2351 &ett_CSortAggregSet
,
2352 &ett_CInGroupSortAggregSet
,
2353 &ett_CInGroupSortAggregSets
,
2354 &ett_CRowsetProperties
,
2363 /* Register the protocol name and description */
2364 proto_mswsp
= proto_register_protocol("Windows Search Protocol",
2367 /* Required function calls to register the header fields and subtrees used */
2368 proto_register_field_array(proto_mswsp
, hf
, array_length(hf
));
2369 proto_register_subtree_array(ett
, array_length(ett
));
2371 for (i
=0; i
<(int)array_length(GuidPropertySet
); i
++) {
2372 guids_add_guid(&GuidPropertySet
[i
].guid
, GuidPropertySet
[i
].def
);
2376 /* Register preferences module (See Section 2.6 for more on preferences) */
2377 /* (Registration of a prefs callback is not required if there are no */
2378 /* prefs-dependent registration functions (eg: a port pref). */
2379 /* See proto_reg_handoff below. */
2380 /* If a prefs callback is not needed, use NULL instead of */
2381 /* proto_reg_handoff_mswsp in the following). */
2382 mswsp_module
= prefs_register_protocol(proto_mswsp
,
2383 proto_reg_handoff_mswsp
);
2385 /* Register preferences module under preferences subtree.
2386 Use this function instead of prefs_register_protocol if you want to group
2387 preferences of several protocols under one preferences subtree.
2388 Argument subtree identifies grouping tree node name, several subnodes can be
2389 specified using slash '/' (e.g. "OSI/X.500" - protocol preferences will be
2390 accessible under Protocols->OSI->X.500-><PROTOSHORTNAME> preferences node.
2392 /* mswsp_module = prefs_register_protocol_subtree(subtree, */
2393 /* proto_mswsp, proto_reg_handoff_mswsp); */
2395 /* Register a sample preference */
2396 prefs_register_bool_preference(mswsp_module
, "show_hex",
2397 "Display numbers in Hex",
2398 "Enable to display numerical values in hexadecimal.",
2401 /* Register a sample port preference */
2402 prefs_register_uint_preference(mswsp_module
, "tcp.port", "mswsp TCP Port",
2403 " mswsp TCP port if other than the default",
2407 static int dissect_mswsp_smb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2408 smb_info_t
*si
= pinfo
->private_data
;
2409 gboolean in
= si
->request
;
2411 fprintf(stderr
, "dissect_mswsp_smb %d <> %d : op %02x %s %s type: %d\n",
2412 pinfo
->fd
->num
, si
->tid
,
2414 pinfo
->dcerpc_procedure_name
? pinfo
->dcerpc_procedure_name
: "<NULL>",
2415 in
? "Request" : "Response", si
->tid
);
2418 if (strcmp(pinfo
->dcerpc_procedure_name
, "File: MsFteWds") != 0) {
2422 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2426 static int dissect_mswsp_smb2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2427 smb2_info_t
*si
= pinfo
->private_data
;
2428 gboolean in
= !(si
->flags
& SMB2_FLAGS_RESPONSE
);
2430 //si->tree->share_type == SMB2_SHARE_TYPE_PIPE
2431 //si->tree->connect_frame
2433 fprintf(stderr
, "dissect_mswsp %d <> %d : op %02x %s %s type: %d extra_file: %s\n",
2434 pinfo
->fd
->num
, si
->tree
? (int)si
->tree
->connect_frame
: -1,
2436 pinfo
->dcerpc_procedure_name
? pinfo
->dcerpc_procedure_name
: "<NULL>",
2437 in
? "Request" : "Response", si
->tree
? si
->tree
->share_type
: -1,
2438 si
->saved
? (si
->saved
->extra_info_type
== SMB2_EI_FILENAME
? (char*)si
->saved
->extra_info
: "<OTHER>") : "<NONE>"
2442 if (strcmp(pinfo
->dcerpc_procedure_name
, "File: MsFteWds") != 0) {
2446 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2451 /* If this dissector uses sub-dissector registration add a registration routine.
2452 This exact format is required because a script is used to find these
2453 routines and create the code that calls these routines.
2455 If this function is registered as a prefs callback (see prefs_register_protocol
2456 above) this function is also called by preferences whenever "Apply" is pressed;
2457 In that case, it should accommodate being called more than once.
2459 Simple form of proto_reg_handoff_mswsp which can be used if there are
2460 no prefs-dependent registration function calls.
2464 proto_reg_handoff_mswsp(void)
2466 heur_dissector_add("smb_transact", dissect_mswsp_smb
, proto_mswsp
);
2467 heur_dissector_add("smb2_heur_subdissectors", dissect_mswsp_smb2
, proto_mswsp
);
2472 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2477 * indent-tabs-mode: nil
2480 * vi: set shiftwidth=4 tabstop=8 expandtab:
2481 * :indentSize=4:tabSize=8:noTabs=true: