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 */
36 #include <sys/types.h>
42 #include <epan/packet.h>
43 #include <epan/prefs.h>
45 #include "packet-smb.h"
46 #include "packet-smb2.h"
48 /* IF PROTO exposes code to other dissectors, then it must be exported
49 in a header file. If not, a header file is not needed at all. */
51 * #include "packet-mswsp.h"
55 #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
57 /* Forward declaration we need below (if using proto_reg_handoff...
58 as a prefs callback) */
59 void proto_reg_handoff_mswsp(void);
61 /* Initialize the protocol and registered fields */
62 static int proto_mswsp
= -1;
63 static int hf_mswsp_msg
= -1;
64 static int hf_mswsp_hdr
= -1;
65 static int hf_mswsp_hdr_msg
= -1;
66 static int hf_mswsp_hdr_status
= -1;
67 static int hf_mswsp_hdr_checksum
= -1;
68 static int hf_mswsp_hdr_reserved
= -1;
69 static int hf_mswsp_msg_Connect_Version
= -1;
70 static int hf_mswsp_msg_ConnectIn_ClientIsRemote
= -1;
71 static int hf_mswsp_msg_ConnectIn_Blob1
= -1;
72 static int hf_mswsp_msg_ConnectIn_Blob2
= -1;
73 static int hf_mswsp_msg_ConnectIn_MachineName
= -1;
74 static int hf_mswsp_msg_ConnectIn_UserName
= -1;
75 static int hf_mswsp_msg_ConnectIn_PropSets_num
= -1;
76 static int hf_mswsp_msg_ConnectIn_ExtPropSets_num
= -1;
79 /* Global sample preference ("controls" display of numbers) */
80 static gboolean gPREF_HEX
= FALSE
;
81 /* Global sample port pref */
82 static guint gPORT_PREF
= 1234;
84 /* Initialize the subtree pointers */
85 static gint ett_mswsp
= -1;
86 static gint ett_mswsp_hdr
= -1;
87 static gint ett_mswsp_msg
= -1;
88 static gint ett_mswsp_pad
= -1;
90 static gint ett_mswsp_property_restriction
= -1;
91 static gint ett_CRestrictionArray
= -1;
92 static gint ett_CBaseStorageVariant
= -1;
93 static gint ett_CBaseStorageVariant_Vector
= -1;
94 static gint ett_CBaseStorageVariant_Array
= -1;
95 static gint ett_CDbColId
= -1;
96 static gint ett_GUID
= -1;
97 static gint ett_CDbProp
= -1;
98 static gint ett_CDbPropSet
= -1;
99 static gint ett_CDbPropSet_Array
= -1;
100 static gint ett_CRestriction
= -1;
101 static gint ett_CNodeRestriction
= -1;
102 static gint ett_CPropertyRestriction
= -1;
103 static gint ett_CCoercionRestriction
= -1;
104 static gint ett_CContentRestriction
= -1;
105 static gint ett_RANGEBOUNDARY
= -1;
106 static gint ett_CRangeCategSpec
= -1;
107 static gint ett_CCategSpec
= -1;
108 static gint ett_CAggregSpec
= -1;
109 static gint ett_CAggregSet
= -1;
110 static gint ett_CCategorizationSpec
= -1;
111 static gint ett_CAggregSortKey
= -1;
112 static gint ett_CSortAggregSet
= -1;
113 static gint ett_CInGroupSortAggregSet
= -1;
114 static gint ett_CInGroupSortAggregSets
= -1;
115 static gint ett_CRowsetProperties
= -1;
116 static gint ett_CFullPropSpec
= -1;
117 static gint ett_CPidMapper
= -1;
118 static gint ett_CSort
= -1;
119 static gint ett_CSortSet
= -1;
120 static gint ett_CNatLanguageRestriction
= -1;
122 /******************************************************************************/
123 struct GuidPropertySet
{
127 const value_string
*id_map
;
131 static const value_string DBPROPSET_FSCIFRMWRK_EXT_IDS
[] = {
132 {0x02, "DBPROP_CI_CATALOG_NAME"},
133 {0x03, "DBPROP_CI_INCLUDE_SCOPES"},
134 {0x04, "DBPROP_CI_SCOPE_FLAGS"},
135 {0x07, "DBPROP_CI_QUERY_TYPE"},
139 static const value_string DBPROPSET_QUERYEXT_IDS
[] = {
140 {0x02, "DBPROP_USECONTENTINDEX"},
141 {0x03, "DBPROP_DEFERNONINDEXEDTRIMMING"},
142 {0x04, "DBPROP_USEEXTENDEDDBTYPES"},
143 {0x05, "DBPROP_IGNORENOISEONLYCLAUSES"},
144 {0x06, "DBPROP_GENERICOPTIONS_STRING"},
145 {0x07, "DBPROP_FIRSTROWS"},
146 {0x08, "DBPROP_DEFERCATALOGVERIFICATION"},
147 {0x0a, "DBPROP_GENERATEPARSETREE"},
148 {0x0c, "DBPROP_FREETEXTANYTERM"},
149 {0x0d, "DBPROP_FREETEXTUSESTEMMING"},
150 {0x0e, "DBPROP_IGNORESBRI"},
151 {0x10, "DBPROP_ENABLEROWSETEVENTS"},
155 static const value_string DBPROPSET_CIFRMWRKCORE_EXT_IDS
[] = {
156 {0x02, "DBPROP_MACHINE"},
157 {0x03, "DBPROP_CLIENT_CLSID"},
161 static const value_string DBPROPSET_MSIDXS_ROWSETEXT_IDS
[] = {
162 {0x02, "MSIDXSPROP_ROWSETQUERYSTATUS"},
163 {0x03, "MSIDXSPROP_COMMAND_LOCALE_STRING"},
164 {0x04, "MSIDXSPROP_QUERY_RESTRICTION"},
165 {0x05, "MSIDXSPROP_PARSE_TREE"},
166 {0x06, "MSIDXSPROP_MAX_RANK"},
167 {0x07, "MSIDXSPROP_RESULTS_FOUND"},
172 static const value_string QueryGuid_IDS
[] = {
173 {0x02, "RankVector"},
174 {0x03, "System.Search.Rank"},
175 {0x04, "System.Search.HitCount"},
176 {0x05, "System.Search.EntryID"},
178 {0x09, "System.ItemURL"},
183 static const value_string StorageGuid_IDS
[] = {
184 {0x02, "System.ItemFolderNameDisplay"},
186 {0x04, "System.ItemTypeText"},
189 {0x0a, "System.ItemNameDisplay"},
191 {0x0c, "System.Size"},
192 {0x0d, "System.FileAttributes"},
193 {0x0e, "System.DateModified"},
194 {0x0f, "System.DateCreated"},
195 {0x10, "System.DateAccessed"},
197 {0x13, "System.Search.Contents"},
198 {0x14, "ShortFilename"},
204 static const value_string DocPropSetGuid_IDS
[] = {
205 {0x02, "System.Title"},
206 {0x03, "System.Subject"},
207 {0x04, "System.Author"},
208 {0x05, "System.Keywords"},
209 {0x06, "System.Comment"},
210 {0x07, "DocTemplate"},
211 {0x08, "System.Document.LastAuthor"},
212 {0x09, "System.Document.RevisionNumber"},
213 {0x0a, "System.Document.EditTime???"},
214 {0x0b, "System.Document.DatePrinted"},
215 {0x0c, "System.Document.DateCreated"},
216 {0x0d, "System.Document.DateSaved"},
217 {0x0e, "System.Document.PageCount"},
218 {0x0f, "System.Document.WordCount"},
219 {0x10, "System.Document.CharacterCount"},
220 {0x11, "DocThumbnail"},
221 {0x12, "System.ApplicationName"},
225 static const value_string ShellDetails_IDS
[] = {
226 { 5, "System.ComputerName"},
227 { 8, "System.ItemPathDisplayNarrow"},
228 { 9, "PercivedType"},
229 {11, "System.ItemType"},
231 {14, "TotalFileSize"},
232 {24, "System.ParsingName"},
233 {25, "System.SFGAOFlags"},
237 static const value_string PropSet1_IDS
[] = {
238 {100, "System.ThumbnailCacheId"},
242 static const value_string PropSet2_IDS
[] = {
247 static const value_string MusicGuid_IDS
[] = {
251 static const value_string PropSet3_IDS
[] = {
252 { 2, "System.Message.BccAddress"},
253 { 3, "System.Message.BccName"},
254 { 4, "System.Message.CcAddress"},
255 { 5, "System.Message.CcName"},
256 { 6, "System.ItemFolderPathDisplay"},
257 { 7, "System.ItemPathDisplay"},
258 { 9, "System.Communication.AccountName"},
259 {10, "System.IsRead"},
260 {11, "System.Importance"},
261 {12, "System.FlagStatus"},
262 {13, "System.Message.FromAddress"},
263 {14, "System.Message.FromName"},
264 {15, "System.Message.Store"},
265 {16, "System.Message.ToAddress"},
266 {17, "System.Message.ToName"},
267 {18, "System.Contact.WebPage"},
268 {19, "System.Message.DateSent"},
269 {20, "System.Message.DateReceived"},
270 {21, "System.Message.AttachmentNames"},
274 static const value_string PropSet4_IDS
[] = {
275 {100, "System.ItemFolderPathDisplayNarrow"},
279 static const value_string PropSet5_IDS
[] = {
280 {100, "System.Contact.FullName"},
284 static const value_string PropSet6_IDS
[] = {
285 {100, "System.ItemAuthors"},
289 static const value_string PropSet7_IDS
[] = {
290 {2, "System.Shell.OmitFromView"},
294 static const value_string PropSet8_IDS
[] = {
295 {2, "System.Shell.SFGAOFlagsStrings"},
296 {3, "System.Link.TargetSFGAOFlagsStrings"},
300 static struct GuidPropertySet GuidPropertySet
[] = {
301 {{0xa9bd1526, 0x6a80, 0x11d0, {0x8c, 0x9d, 0x00, 0x20, 0xaf, 0x1d, 0x74, 0x0e}},
302 "DBPROPSET_FSCIFRMWRK_EXT", "File system content index framework",
303 DBPROPSET_FSCIFRMWRK_EXT_IDS
},
304 {{0xa7ac77ed, 0xf8d7, 0x11ce, {0xa7, 0x98, 0x00, 0x20, 0xf8, 0x00, 0x80, 0x25}},
305 "DBPROPSET_QUERYEXT", "Query extension",
306 DBPROPSET_QUERYEXT_IDS
},
307 {{0xafafaca5, 0xb5d1, 0x11d0, {0x8c, 0x62, 0x00, 0xc0, 0x4f, 0xc2, 0xdb, 0x8d}},
308 "DBPROPSET_CIFRMWRKCORE_EXT", "Content index framework core",
309 DBPROPSET_CIFRMWRKCORE_EXT_IDS
},
310 {{0xAA6EE6B0, 0xE828, 0x11D0, {0xB2, 0x3E, 0x00, 0xAA, 0x00, 0x47, 0xFC, 0x01}},
311 "DBPROPSET_MSIDXS_ROWSETEXT", "???",
312 DBPROPSET_MSIDXS_ROWSETEXT_IDS
},
313 {{0xB725F130, 0x47ef, 0x101a, {0xA5, 0xF1, 0x02, 0x60, 0x8C, 0x9E, 0xEB, 0xAC}},
314 "Storage", "Storage Property Set",
316 {{0xF29F85E0, 0x4FF9, 0x1068, {0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9}},
317 "Document", "Document Property Set",
319 {{0x49691C90, 0x7E17, 0x101A, {0xA9, 0x1C, 0x08, 0x00, 0x2B, 0x2E, 0xCD, 0xA9}},
320 "Query", "Query Property Set",
322 {{0x28636AA6, 0x953D, 0x11D2, {0xB5, 0xD6, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0}},
323 "ShellDetails", "Shell Details Property Set",
325 {{0x446D16B1, 0x8DAD, 0x4870, {0xA7, 0x48, 0x40, 0x2E, 0xA4, 0x3D, 0x78, 0x8C}},
326 "???", "Unspecified Property Set",
328 {{0x1E3EE840, 0xBC2B, 0x476C, {0x82, 0x37, 0x2A, 0xCD, 0x1A, 0x83, 0x9B, 0x22}},
329 "???", "Unspecified Property Set",
331 {{0x56A3372E, 0xCE9C, 0x11d2, {0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6}},
332 "Music", "Music Property Set",
334 {{0xE3E0584C, 0xB788, 0x4A5A, {0xBB, 0x20, 0x7F, 0x5A, 0x44, 0xC9, 0xAC, 0xDD}},
335 "???", "Unspecified Property Set",
337 {{0xDABD30ED, 0x0043, 0x4789, {0xA7, 0xF8, 0xD0, 0x13, 0xA4, 0x73, 0x66, 0x22}},
338 "???", "Unspecified Property Set",
340 {{0x635E9051, 0x50A5, 0x4BA2, {0xB9, 0xDB, 0x4E, 0xD0, 0x56, 0xC7, 0x72, 0x96}},
341 "???", "Unspecified Property Set",
343 {{0xD0A04F0A, 0x462A, 0x48A4, {0xBB, 0x2F, 0x37, 0x06, 0xE8, 0x8D, 0xBD, 0x7D}},
344 "???", "Unspecified Property Set",
346 {{0xDE35258C, 0xC695, 0x4CBC, {0xB9, 0x82, 0x38, 0xB0, 0xAD, 0x24, 0xCE, 0xD0}},
347 "???", "Unspecified Property Set",
349 {{0xD6942081, 0xD53B, 0x443D, {0xAD, 0x47, 0x5E, 0x05, 0x9D, 0x9C, 0xD2, 0x7A}},
350 "???", "Unspecified Property Set",
354 static struct GuidPropertySet
*GuidPropertySet_find_guid(const e_guid_t
*guid
)
357 for (i
=0; i
<array_length(GuidPropertySet
); i
++) {
358 if (guid_cmp(&GuidPropertySet
[i
].guid
, guid
) == 0) {
359 return &GuidPropertySet
[i
];
365 /******************************************************************************/
367 static int parse_padding(tvbuff_t
*tvb
, int offset
, int alignment
, proto_tree
*pad_tree
, const char *fmt
, ...)
369 if (offset
% alignment
) {
370 const int padding
= alignment
- (offset
% alignment
);
374 ti
= proto_tree_add_text_valist(pad_tree
, tvb
, offset
, padding
, fmt
, ap
);
377 proto_item_append_text(ti
, " (%d)", padding
);
380 DISSECTOR_ASSERT((offset
% alignment
) == 0);
384 static int parse_guid(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, e_guid_t
*guid
, const char *text
)
386 const char *guid_str
, *name
, *bytes
;
390 tvb_get_letohguid(tvb
, offset
, guid
);
391 guid_str
= guid_to_str(guid
);
392 name
= guids_get_guid_name(guid
);
394 ti
= proto_tree_add_text(tree
, tvb
, offset
, 16, "%s: %s {%s}", text
, name
? name
: "", guid_str
);
395 tr
= proto_item_add_subtree(ti
, ett_GUID
);
397 proto_tree_add_text(tr
, tvb
, offset
, 4, "time-low: 0x%08x", guid
->data1
);
399 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-mid: 0x%04x", guid
->data2
);
401 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-high-and-version: 0x%04x", guid
->data3
);
403 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_hi_and_reserved: 0x%02x", guid
->data4
[0]);
405 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_low: 0x%02x", guid
->data4
[1]);
407 bytes
= bytestring_to_str(&guid
->data4
[2], 6, ':');
408 proto_tree_add_text(tr
, tvb
, offset
, 6, "node: %s", bytes
);
414 /*****************************************************************************************/
415 /* 2.2.1.1 CBaseStorageVariant */
416 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
417 struct CBaseStorageVariant
*value
, const char *text
);
419 /* 2.2.1.2 CFullPropSpec */
420 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
421 struct CFullPropSpec
*v
, const char *fmt
, ...);
423 /* 2.2.1.3 CContentRestriction */
424 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
425 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
426 const char *fmt
, ...);
428 /* 2.2.1.5 CNatLanguageRestriction */
429 static int parse_CNatLanguageRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
430 proto_tree
*pad_tree
, struct CNatLanguageRestriction
*v
,
431 const char *fmt
, ...);
433 /* 2.2.1.6 CNodeRestriction */
434 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
435 struct CNodeRestriction
*v
, const char* fmt
, ...);
437 /* 2.2.1.7 CPropertyRestriction */
438 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
439 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
440 const char *fmt
, ...);
442 /* 2.2.1.8 CReuseWhere */
443 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
444 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
445 const char *fmt
, ...);
448 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
449 proto_tree
*pad_tree _U_
,
450 const char *fmt
, ...);
452 /* 2.2.1.12 CCoercionRestriction */
453 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
454 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
455 const char *fmt
, ...);
456 /* 2.2.1.16 CRestrictionArray */
457 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
458 const char *fmt
, ...);
460 /* 2.2.1.17 CRestriction */
461 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
462 struct CRestriction
*v
, const char *fmt
, ...);
464 /* 2.2.1.18 CColumnSet */
465 static int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...);
467 /* 2.2.1.20 CCategorizationSpec */
468 static int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
469 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
470 const char *fmt
, ...);
472 /* 2.2.1.21 CCategSpec */
473 static int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
474 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
475 const char *fmt
, ...);
477 /* 2.2.1.22 CRangeCategSpec */
478 static int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
479 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
480 const char *fmt
, ...);
482 /* 2.2.1.23 RANGEBOUNDARY */
483 static int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
484 proto_tree
*pad_tree
, const char *fmt
, ...);
486 /* 2.2.1.24 CAggregSet */
487 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
488 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
489 const char *fmt
, ...);
491 /* 2.2.1.25 CAggregSpec */
492 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
493 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
494 const char *fmt
, ...);
496 /* 2.2.1.26 CSortAggregSet */
497 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
498 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
499 const char *fmt
, ...);
501 /* 2.2.1.27 CAggregSortKey */
502 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
503 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
504 const char *fmt
, ...);
506 /* 2.2.1.28 CInGroupSortAggregSets */
507 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
508 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
509 const char *fmt
, ...);
511 /* 2.2.1.29 CInGroupSortAggregSet */
512 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
513 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
514 const char *fmt
, ...);
515 /* 2.2.1.30 CDbColId */
516 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
,
517 proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
);
519 /* 2.2.1.31 CDbProp */
520 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
521 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
522 const char *fmt
, ...);
524 /* 2.2.1.32 CDbPropSet */
525 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
526 proto_tree
*pad_tree
, const char *fmt
, ...);
527 /* 2.2.1.33 CPidMapper */
528 static int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
529 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
530 const char *fmt
, ...);
532 /* 2.2.1.41 CRowsetProperties */
533 static int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
534 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
535 const char *fmt
, ...);
537 /* 2.2.1.43 CSortSet */
538 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
,
539 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
540 const char *fmt
, ...);
543 2.2.1.4 CInternalPropertyRestriction
544 2.2.1.9 CScopeRestriction
545 2.2.1.11 CVectorRestriction
546 2.2.1.13 CRelDocRestriction
547 2.2.1.14 CProbRestriction
548 2.2.1.15 CFeedbackRestriction
549 2.2.1.19 CCategorizationSet
550 2.2.1.34 CColumnGroupArray
551 2.2.1.35 CColumnGroup
554 2.2.1.38 CRowSeekAtRatio
555 2.2.1.39 CRowSeekByBookmark
556 2.2.1.40 CRowSeekNext
558 2.2.1.44 CTableColumn
559 2.2.1.45 SERIALIZEDPROPERTYVALUE
560 2.2.1.46 CCompletionCategSp
563 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
564 proto_tree
*pad_tree _U_
,
565 const char *fmt
, ...)
567 guint32 col
, ord
, ind
, lcid
;
575 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
577 tree
= proto_item_add_subtree(item
, ett_CSort
);
579 col
= tvb_get_letohl(tvb
, offset
);
580 proto_tree_add_text(tree
, tvb
, offset
, 4, "column: %u", col
);
583 ord
= tvb_get_letohl(tvb
, offset
);
584 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", ord
);
587 ind
= tvb_get_letohl(tvb
, offset
);
588 proto_tree_add_text(tree
, tvb
, offset
, 4, "individual: %u", ind
);
591 lcid
= tvb_get_letohl(tvb
, offset
);
592 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", lcid
);
595 proto_item_set_end(item
, tvb
, offset
);
599 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
600 proto_tree
*pad_tree
,
601 const char *fmt
, ...)
611 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
613 tree
= proto_item_add_subtree(item
, ett_CSortSet
);
615 count
= tvb_get_letohl(tvb
, offset
);
616 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
619 for (i
=0; i
<count
; i
++) {
620 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_sortArray[%u]", i
);
621 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "sortArray[%u]", i
);
624 proto_item_set_end(item
, tvb
, offset
);
629 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
,
630 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
631 struct CFullPropSpec
*v
, const char *fmt
, ...)
633 static const value_string KIND
[] = {
634 {0, "PRSPEC_LPWSTR"},
635 {1, "PRSPEC_PROPID"},
639 struct GuidPropertySet
*pset
;
640 const char *id_str
, *guid_str
;
647 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
649 tree
= proto_item_add_subtree(item
, ett_CFullPropSpec
);
651 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingPropSet");
653 offset
= parse_guid(tvb
, offset
, tree
, &v
->guid
, "GUID");
654 pset
= GuidPropertySet_find_guid(&v
->guid
);
656 v
->kind
= tvb_get_letohl(tvb
, offset
);
657 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulKind: %s ", val_to_str(v
->kind
, KIND
, "(Unknown: 0x%x)"));
660 v
->u
.propid
= tvb_get_letohl(tvb
, offset
);
661 proto_tree_add_text(tree
, tvb
, offset
, 4, "propid: %u ", v
->u
.propid
);
664 if (v
->kind
== PRSPEC_LPWSTR
) {
665 int len
= 2*v
->u
.propid
;
666 v
->u
.name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
667 proto_tree_add_text(tree
, tvb
, offset
, len
, "name: \"%s\"", v
->u
.name
);
671 id_str
= pset
? match_strval(v
->u
.propid
, pset
->id_map
) : NULL
;
674 proto_item_append_text(item
, ": %s", id_str
);
676 guid_str
= guids_get_guid_name(&v
->guid
);
678 proto_item_append_text(item
, ": \"%s\"", guid_str
);
680 guid_str
= guid_to_str(&v
->guid
);
681 proto_item_append_text(item
, ": {%s}", guid_str
);
684 if (v
->kind
== PRSPEC_LPWSTR
) {
685 proto_item_append_text(item
, " \"%s\"", v
->u
.name
);
686 } else if (v
->kind
== PRSPEC_PROPID
) {
687 proto_item_append_text(item
, " 0x%08x", v
->u
.propid
);
689 proto_item_append_text(item
, " <INVALID>");
693 proto_item_set_end(item
, tvb
, offset
);
699 static const value_string PR_VALS
[] = {
707 {PRAllBits
, "PRAllBits"},
708 {PRSomeBits
, "PRSomeBits"},
714 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
715 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
716 const char *fmt
, ...)
724 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
727 tree
= proto_item_add_subtree(item
, ett_CPropertyRestriction
);
729 v
->relop
= tvb_get_letohl(tvb
, offset
);
730 str
= val_to_str(v
->relop
, PR_VALS
, "0x%04x");
731 proto_tree_add_text(tree
, tvb
, offset
, 4, "relop: %s (0x%04x)",
732 str
[0]=='\0' ? "" : str
, v
->relop
);
733 proto_item_append_text(item
, " Op: %s", str
);
736 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
738 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &v
->prval
, "prval");
740 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
742 v
->lcid
= tvb_get_letohl(tvb
, offset
);
743 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
746 proto_item_set_end(item
, tvb
, offset
);
751 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
752 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
753 const char *fmt
, ...)
760 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
763 tree
= proto_item_add_subtree(item
, ett_CCoercionRestriction
);
765 v
->value
= tvb_get_letohl(tvb
, offset
);
766 proto_tree_add_text(tree
, tvb
, offset
, 4, "value: %g", (double)v
->value
);
769 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &v
->child
, "child");
771 proto_item_set_end(item
, tvb
, offset
);
775 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
776 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
777 const char *fmt
, ...)
787 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
790 tree
= proto_item_add_subtree(item
, ett_CContentRestriction
);
792 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
794 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding1");
796 cc
= tvb_get_letohl(tvb
, offset
);
797 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
800 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
801 str
= tvb_get_unicode_string(tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
802 v
->phrase
= se_strdup(str
);
803 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
806 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding2");
808 v
->lcid
= tvb_get_letohl(tvb
, offset
);
809 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
812 v
->method
= tvb_get_letohl(tvb
, offset
);
813 proto_tree_add_text(tree
, tvb
, offset
, 4, "method: 0x%08x", v
->method
);
816 proto_item_set_end(item
, tvb
, offset
);
820 int parse_CNatLanguageRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
821 proto_tree
*pad_tree
, struct CNatLanguageRestriction
*v
,
822 const char *fmt
, ...)
832 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
835 tree
= proto_item_add_subtree(item
, ett_CNatLanguageRestriction
);
837 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
839 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_cc");
841 cc
= tvb_get_letohl(tvb
, offset
);
842 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
845 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
846 str
= tvb_get_unicode_string(tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
847 v
->phrase
= se_strdup(str
);
848 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
851 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
853 v
->lcid
= tvb_get_letohl(tvb
, offset
);
854 proto_tree_add_text(tree
, tvb
, offset
, 4, "lcid: 0x%08x", v
->lcid
);
857 proto_item_set_end(item
, tvb
, offset
);
862 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
863 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
864 const char *fmt
, ...)
871 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
874 v
->whereId
= tvb_get_letohl(tvb
, offset
);
877 proto_item_append_text(item
, " Id: %u", v
->whereId
);
879 proto_item_set_end(item
, tvb
, offset
);
883 static value_string RT_VALS
[] = {
888 {RTContent
, "RTContent"},
889 {RTProperty
, "RTProperty"},
890 {RTProximity
, "RTProximity"},
892 {RTNatLanguage
, "RTNatLanguage"},
893 {RTScope
, "RTScope"},
894 {RTCoerce_Add
, "RTCoerce_Add"},
895 {RTCoerce_Multiply
, "RTCoerce_Multiply"},
896 {RTCoerce_Absolute
, "RTCoerce_Absolute"},
898 {RTFeedback
, "RTFeedback"},
899 {RTReldoc
, "RTReldoc"},
900 {RTReuseWhere
, "RTReuseWhere"},
901 {RTInternalProp
, "RTInternalProp"},
902 {RTPhrase
, "RTInternalProp"},
905 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
906 struct CRestriction
*v
, const char *fmt
, ...)
914 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
917 tree
= proto_item_add_subtree(item
, ett_CRestriction
);
920 v
->ulType
= tvb_get_letohl(tvb
, offset
);
921 str
= val_to_str(v
->ulType
, RT_VALS
, "0x%.8x");
922 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType: %s (0x%.8x)",
923 str
[0] == '0' ? "" : str
, v
->ulType
);
924 proto_item_append_text(item
, " Type: %s", str
);
927 v
->Weight
= tvb_get_letohl(tvb
, offset
);
928 proto_tree_add_text(tree
, tvb
, offset
, 4, "Weight: %u", v
->ulType
);
939 v
->u
.RTAnd
= ep_alloc(sizeof(struct CNodeRestriction
)); //XXX
940 offset
= parse_CNodeRestriction(tvb
, offset
, tree
, pad_tree
, v
->u
.RTAnd
, "CNodeRestriction");
945 v
->u
.RTNot
= ep_alloc(sizeof(struct CRestriction
)); //XXX
946 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
,
947 v
->u
.RTNot
, "CRestriction");
952 v
->u
.RTProperty
= ep_alloc(sizeof(struct CPropertyRestriction
)); //XXX
953 offset
= parse_CPropertyRestriction(tvb
, offset
, tree
, pad_tree
,
954 v
->u
.RTProperty
, "CPropertyRestriction");
958 case RTCoerce_Multiply
:
959 case RTCoerce_Absolute
:
961 v
->u
.RTCoerce_Add
= ep_alloc(sizeof(struct CCoercionRestriction
)); //XXX
962 offset
= parse_CCoercionRestriction(tvb
, offset
, tree
, pad_tree
,
963 v
->u
.RTCoerce_Add
, "CCoercionRestriction");
967 v
->u
.RTContent
= ep_alloc(sizeof(struct CContentRestriction
)); //XXX
968 offset
= parse_CContentRestriction(tvb
, offset
, tree
, pad_tree
,
969 v
->u
.RTContent
, "CContentRestriction");
973 v
->u
.RTReuseWhere
= ep_alloc(sizeof(struct CReuseWhere
)); //XXX
974 offset
= parse_CReuseWhere(tvb
, offset
, tree
, pad_tree
,
975 v
->u
.RTReuseWhere
, "CReuseWhere");
978 case RTNatLanguage
: {
979 v
->u
.RTNatLanguage
= ep_alloc(sizeof(struct CNatLanguageRestriction
)); //XXX
980 offset
= parse_CNatLanguageRestriction(tvb
, offset
, tree
, pad_tree
,
981 v
->u
.RTNatLanguage
, "CNatLanguageRestriction");
985 fprintf(stderr
, "CRestriciont 0x%08x not Supported\n", v
->ulType
);
986 proto_item_append_text(item
, " Not supported!");
989 proto_item_set_end(item
, tvb
, offset
);
993 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
994 const char *fmt
, ...)
996 guint8 present
, count
;
1003 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1005 tree
= proto_item_add_subtree(item
, ett_CRestrictionArray
);
1007 pad_tree
= tree
; //XXX
1009 count
= tvb_get_guint8(tvb
, offset
);
1010 proto_tree_add_text(tree
, tvb
, offset
, 1, "count: %u", count
);
1013 present
= tvb_get_guint8(tvb
, offset
);
1014 proto_tree_add_text(tree
, tvb
, offset
, 1, "present: %u", present
);
1019 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCRestrictionPresent");
1021 for (i
=0; i
<count
; i
++) {
1022 struct CRestriction r
;
1023 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "Restriction[%d]", i
);
1026 proto_item_set_end(item
, tvb
, offset
);
1030 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1031 proto_tree
*pad_tree
, struct CNodeRestriction
*v
,
1032 const char *fmt
, ...)
1040 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1042 tree
= proto_item_add_subtree(item
, ett_CNodeRestriction
);
1044 v
->cNode
= tvb_get_letohl(tvb
, offset
);
1045 proto_tree_add_text(tree
, tvb
, offset
, 4, "cNode: %u", v
->cNode
);
1048 for (i
=0; i
<v
->cNode
; i
++) {
1049 struct CRestriction r
;
1051 // offset = parse_padding(tvb, offset, 4, tree, "padding_paNode[%u]", i); /*at begin or end of loop ????*/
1052 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "paNode[%u]", i
);
1053 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_paNode[%u]", i
); /*at begin or end of loop ????*/
1055 // offset = parse_padding(tvb, offset, 4, pad_tree, "paNode[%u]", i); /*at begin or end of loop ????*/
1058 proto_item_set_end(item
, tvb
, offset
);
1063 /*****************************************************************************************/
1065 static int vvalue_tvb_get0(tvbuff_t
*tvb _U_
, int offset _U_
, void *val _U_
)
1070 static int vvalue_tvb_get1(tvbuff_t
*tvb
, int offset
, void *val
)
1072 guint8
*ui1
= (guint8
*)val
;
1073 *ui1
= tvb_get_guint8(tvb
, offset
);
1077 static int vvalue_tvb_get2(tvbuff_t
*tvb
, int offset
, void *val
)
1079 guint16
*ui2
= (guint16
*)val
;
1080 *ui2
= tvb_get_letohs(tvb
, offset
);
1084 static int vvalue_tvb_get4(tvbuff_t
*tvb
, int offset
, void *val
)
1086 guint32
*ui4
= (guint32
*)val
;
1087 *ui4
= tvb_get_letohl(tvb
, offset
);
1091 static int vvalue_tvb_get8(tvbuff_t
*tvb
, int offset
, void *val
)
1093 guint64
*ui8
= (guint64
*)val
;
1094 *ui8
= tvb_get_letoh64(tvb
, offset
);
1098 static int vvalue_tvb_blob(tvbuff_t
*tvb
, int offset
, void *val
)
1100 struct data_blob
*blob
= (struct data_blob
*)val
;
1101 guint32 len
= tvb_get_letohl(tvb
, offset
);
1102 const guint8
*data
= tvb_get_ptr(tvb
, offset
+ 4, len
);
1105 blob
->data
= se_memdup(data
, len
);
1110 static int vvalue_tvb_bstr(tvbuff_t
*tvb
, int offset
, void *val
)
1112 struct data_str
*str
= (struct data_str
*)val
;
1113 guint32 len
= tvb_get_letohl(tvb
, offset
);
1114 const void *ptr
= tvb_get_ptr(tvb
, offset
+ 4, len
);
1116 //XXX this might be UTF-16
1118 str
->str
= se_strndup(ptr
, len
);
1122 static int vvalue_tvb_lpstr(tvbuff_t
*tvb
, int offset
, void *val
)
1124 struct data_str
*str
= (struct data_str
*)val
;
1127 str
->len
= tvb_get_letohl(tvb
, offset
);
1128 str
->str
= tvb_get_seasonal_stringz(tvb
, offset
+ 4, &len
);
1129 /* XXX test str->len == len */
1133 static int vvalue_tvb_lpwstr(tvbuff_t
*tvb
, int offset
, void *val
)
1135 struct data_str
*str
= (struct data_str
*)val
;
1139 str
->len
= tvb_get_letohl(tvb
, offset
);
1141 ptr
= tvb_get_ephemeral_unicode_stringz(tvb
, offset
+ 4, &len
, ENC_LITTLE_ENDIAN
);
1142 str
->str
= se_strdup (ptr
);
1147 static int vvalue_tvb_vector_internal(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
, int num
)
1149 const int offset_in
= offset
;
1150 const gboolean varsize
= (type
->size
== -1);
1151 const int elsize
= varsize
? (int)sizeof(struct data_blob
) : type
->size
;
1152 guint8
*data
= se_alloc(elsize
* num
);
1156 val
->u
.vt_ui1
= data
;
1157 DISSECTOR_ASSERT((void*)&val
->u
== ((void*)&val
->u
.vt_ui1
));
1159 for (i
=0; i
<num
; i
++) {
1160 len
= type
->tvb_get(tvb
, offset
, data
);
1163 if (varsize
&& (offset
% 4) ) { /* at begin or end of loop ??? */
1164 int padding
= 4 - (offset
% 4);
1168 return offset
- offset_in
;
1171 static int vvalue_tvb_vector(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
)
1173 const int num
= tvb_get_letohl(tvb
, offset
);
1174 return 4 + vvalue_tvb_vector_internal(tvb
, offset
+4, val
, type
, num
);
1177 static void vvalue_strbuf_append_null(emem_strbuf_t
*strbuf _U_
, void *ptr _U_
)
1180 static void vvalue_strbuf_append_i1(emem_strbuf_t
*strbuf
, void *ptr
)
1182 gint8 i1
= *(gint8
*)ptr
;
1183 ep_strbuf_append_printf(strbuf
, "%d", (int)i1
);
1186 static void vvalue_strbuf_append_i2(emem_strbuf_t
*strbuf
, void *ptr
)
1188 gint16 i2
= *(gint16
*)ptr
;
1189 ep_strbuf_append_printf(strbuf
, "%d", (int)i2
);
1192 static void vvalue_strbuf_append_i4(emem_strbuf_t
*strbuf
, void *ptr
)
1194 gint32 i4
= *(gint32
*)ptr
;
1195 ep_strbuf_append_printf(strbuf
, "%d", i4
);
1198 static void vvalue_strbuf_append_i8(emem_strbuf_t
*strbuf
, void *ptr
)
1200 gint64 i8
= *(gint64
*)ptr
;
1201 ep_strbuf_append_printf(strbuf
, "%ld", i8
);
1204 static void vvalue_strbuf_append_ui1(emem_strbuf_t
*strbuf
, void *ptr
)
1206 guint8 ui1
= *(guint8
*)ptr
;
1207 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui1
);
1210 static void vvalue_strbuf_append_ui2(emem_strbuf_t
*strbuf
, void *ptr
)
1212 guint16 ui2
= *(guint16
*)ptr
;
1213 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui2
);
1216 static void vvalue_strbuf_append_ui4(emem_strbuf_t
*strbuf
, void *ptr
)
1218 guint32 ui4
= *(guint32
*)ptr
;
1219 ep_strbuf_append_printf(strbuf
, "%d", ui4
);
1222 static void vvalue_strbuf_append_ui8(emem_strbuf_t
*strbuf
, void *ptr
)
1224 guint64 ui8
= *(guint64
*)ptr
;
1225 ep_strbuf_append_printf(strbuf
, "%lu", ui8
);
1228 static void vvalue_strbuf_append_r4(emem_strbuf_t
*strbuf
, void *ptr
)
1230 float r4
= *(float*)ptr
;
1231 ep_strbuf_append_printf(strbuf
, "%g", (double)r4
);
1234 static void vvalue_strbuf_append_r8(emem_strbuf_t
*strbuf
, void *ptr
)
1236 double r8
= *(double*)ptr
;
1237 ep_strbuf_append_printf(strbuf
, "%g", r8
);
1240 static void vvalue_strbuf_append_str(emem_strbuf_t
*strbuf
, void *ptr
)
1242 struct data_str
*str
= (struct data_str
*)ptr
;
1243 ep_strbuf_append_printf(strbuf
, "\"%s\"", str
->str
);
1246 static void vvalue_strbuf_append_blob(emem_strbuf_t
*strbuf
, void *ptr
)
1248 struct data_blob
*blob
= (struct data_blob
*)ptr
;
1249 ep_strbuf_append_printf(strbuf
, "size: %d", (int)blob
->size
);
1252 static void vvalue_strbuf_append_bool(emem_strbuf_t
*strbuf
, void *ptr
)
1254 guint16 val
= *(guint
*)ptr
;
1257 ep_strbuf_append(strbuf
, "False");
1260 ep_strbuf_append(strbuf
, "True");
1263 ep_strbuf_append_printf(strbuf
, "Invalid (0x%4x)", val
);
1267 static void vvalue_strbuf_append_vector(emem_strbuf_t
*strbuf
, struct vt_vector val
, struct vtype
*type
)
1269 const int elsize
= (type
->size
== -1) ? (int)sizeof(struct data_blob
) : type
->size
;
1271 guint8
*data
= val
.u
.vt_ui1
;
1272 ep_strbuf_append_c(strbuf
, '[');
1273 for (i
=0; i
<val
.len
; i
++) {
1275 ep_strbuf_append_c(strbuf
, ',');
1277 type
->strbuf_append(strbuf
, data
);
1280 ep_strbuf_append_c(strbuf
, ']');
1284 static struct vtype VT_TYPE
[] = {
1285 {VT_EMPTY
, "VT_EMPTY", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
1286 {VT_NULL
, "VT_NULL", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
1287 {VT_I2
, "VT_I2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_i2
},
1288 {VT_I4
, "VT_I4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
1289 {VT_R4
, "VT_R4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_r4
},
1290 {VT_R8
, "VT_R8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
1291 {VT_CY
, "VT_CY", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1292 {VT_DATE
, "VT_DATE", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
1293 // {VT_BSTR, "VT_BSTR", -1, vvalue_tvb_bstr, vvalue_strbuf_append_str},
1294 {VT_BSTR
, "VT_BSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
1295 {VT_ERROR
, "VT_ERROR", 8, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1296 {VT_BOOL
, "VT_BOOL", 2, vvalue_tvb_get2
, vvalue_strbuf_append_bool
},
1297 {VT_VARIANT
, "VT_VARIANT", -1, NULL
, NULL
},
1298 {VT_DECIMAL
, "VT_DECIMAL", 16, NULL
, NULL
},
1299 {VT_I1
, "VT_I1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_i1
},
1300 {VT_UI1
, "VT_UI1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_ui1
},
1301 {VT_UI2
, "VT_UI2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_ui2
},
1302 {VT_UI4
, "VT_UI4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1303 {VT_I8
, "VT_I8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1304 {VT_UI8
, "VT_UI8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_ui8
},
1305 {VT_INT
, "VT_INT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
1306 {VT_UINT
, "VT_UINT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1307 {VT_LPSTR
, "VT_LPSTR", -1, vvalue_tvb_lpstr
, vvalue_strbuf_append_str
},
1308 {VT_LPWSTR
, "VT_LPWSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
1309 {VT_COMPRESSED_LPWSTR
, "VT_COMPRESSED_LPWSTR", -1, NULL
, vvalue_strbuf_append_str
},
1310 {VT_FILETIME
, "VT_FILETIME", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1311 {VT_BLOB
, "VT_BLOB", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
1312 {VT_BLOB_OBJECT
, "VT_BLOB_OBJECT", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
1313 {VT_CLSID
, "VT_CLSID", 16, NULL
, NULL
},
1316 static struct vtype
*vType_get_type(enum vType t
) {
1319 for (i
=0; i
<array_length(VT_TYPE
); i
++) {
1320 if (t
== VT_TYPE
[i
].tag
) {
1327 static char *str_CBaseStorageVariant(struct CBaseStorageVariant
*value
, gboolean print_type
)
1330 emem_strbuf_t
*strbuf
= ep_strbuf_new(NULL
);
1331 if (value
== NULL
) {
1335 if (value
->type
== NULL
) {
1340 ep_strbuf_append(strbuf
, value
->type
->str
);
1342 if (value
->vType
& 0xFF00) {
1343 ep_strbuf_append_printf(strbuf
, "[%d]", value
->vValue
.vt_vector
.len
);
1345 ep_strbuf_append(strbuf
, ": ");
1348 switch (value
->vType
& 0xFF00) {
1350 value
->type
->strbuf_append(strbuf
, &value
->vValue
);
1353 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_array
.vData
, value
->type
);
1356 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_vector
, value
->type
);
1359 ep_strbuf_append(strbuf
, "Invalid");
1365 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1366 struct CBaseStorageVariant
*value
, const char *text
)
1369 proto_item
*ti
, *ti_type
, *ti_val
;
1370 proto_tree
*tree
, *tr
;
1371 enum vType baseType
, highType
;
1373 ZERO_STRUCT(*value
);
1375 ti
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1376 tree
= proto_item_add_subtree(ti
, ett_CBaseStorageVariant
);
1378 value
->vType
= tvb_get_letohs(tvb
, offset
);
1379 value
->type
= vType_get_type(value
->vType
);
1381 ti_type
= proto_tree_add_text(tree
, tvb
, offset
, 2, "vType: %s", value
->type
->str
);
1384 value
->vData1
= tvb_get_guint8(tvb
, offset
);
1385 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData1: %d", value
->vData1
);
1388 value
->vData2
= tvb_get_guint8(tvb
, offset
);
1389 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData2: %d", value
->vData2
);
1392 baseType
= value
->vType
& 0x00FF;
1393 highType
= value
->vType
& 0xFF00;
1395 if (value
->type
== NULL
) {
1399 ti_val
= proto_tree_add_text(tree
, tvb
, offset
, 0, "vValue");
1403 len
= value
->type
->tvb_get(tvb
, offset
, &value
->vValue
.vt_single
);
1407 proto_item_append_text(ti_type
, "|VT_VECTOR");
1408 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Vector
);
1410 len
= vvalue_tvb_vector(tvb
, offset
, &value
->vValue
.vt_vector
, value
->type
);
1411 proto_tree_add_text(tr
, tvb
, offset
, 4, "num: %d", value
->vValue
.vt_vector
.len
);
1415 guint16 cDims
, fFeatures
;
1416 guint32 cbElements
, cElements
, lLbound
;
1419 proto_item_append_text(ti_type
, "|VT_ARRAY");
1420 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Array
);
1422 cDims
= tvb_get_letohs(tvb
, offset
);
1423 proto_tree_add_text(tr
, tvb
, offset
, 2, "cDims: %d", cDims
);
1426 fFeatures
= tvb_get_letohs(tvb
, offset
);
1427 proto_tree_add_text(tr
, tvb
, offset
, 2, "fFeaturess: %d", fFeatures
);
1430 cbElements
= tvb_get_letohl(tvb
, offset
);
1431 proto_tree_add_text(tr
, tvb
, offset
, 4, "cbElements: %d", cbElements
);
1433 for (i
=0; i
<cDims
; i
++) {
1434 cElements
= tvb_get_letohl(tvb
, offset
);
1435 lLbound
= tvb_get_letohl(tvb
, offset
+ 4);
1436 proto_tree_add_text(tr
, tvb
, offset
, 8, "Rgsabound[%d]: (%d:%d)", i
, cElements
, lLbound
);
1441 len
= vvalue_tvb_vector_internal(tvb
, offset
, &value
->vValue
.vt_array
.vData
, value
->type
, num
);
1446 proto_item_append_text(ti_type
, "|0x%x", highType
);
1448 proto_item_set_end(ti
, tvb
, offset
);
1449 proto_item_set_end(ti_val
, tvb
, offset
);
1451 proto_item_append_text(ti_val
, " %s", str_CBaseStorageVariant(value
, false));
1452 proto_item_append_text(ti
, " %s", str_CBaseStorageVariant(value
, true));
1457 proto_item_append_text(ti
, ": sorry, vType %02x not handled yet!", (unsigned)value
->vType
);
1463 DBKIND_GUID_NAME
= 0,
1464 DBKIND_GUID_PROPID
= 1
1467 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
)
1469 guint32 eKind
, ulId
;
1471 static const char *KIND
[] = {"DBKIND_GUID_NAME", "DBKIND_GUID_PROPID"};
1473 proto_item
*tree_item
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1474 proto_tree
*tree
= proto_item_add_subtree(tree_item
, ett_CDbColId
);
1476 eKind
= tvb_get_letohl(tvb
, offset
);
1477 proto_tree_add_text(tree
, tvb
, offset
, 4, "eKind: %s (%u)", eKind
< 2 ? KIND
[eKind
] : "???", eKind
);
1480 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingGuidAlign");
1482 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "GUID");
1484 ulId
= tvb_get_letohl(tvb
, offset
);
1485 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulId: %d", ulId
);
1488 if (eKind
== DBKIND_GUID_NAME
) {
1490 int len
= ulId
; //*2 ???
1491 name
= tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
1492 proto_tree_add_text(tree
, tvb
, offset
, len
, "vString: \"%s\"", name
);
1493 proto_item_append_text(tree_item
, " \"%s\"", name
);
1495 } else if (eKind
== DBKIND_GUID_PROPID
) {
1496 proto_item_append_text(tree_item
, " %08x", ulId
);
1498 proto_item_append_text(tree_item
, "<INVALID>");
1501 proto_item_set_end(tree_item
, tvb
, offset
);
1506 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1507 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
1508 const char *fmt
, ...)
1510 static const value_string EMPTY_VS
[] = {{0, NULL
}};
1511 const value_string
*vs
= (propset
&& propset
->id_map
) ? propset
->id_map
: EMPTY_VS
;
1512 guint32 id
, opt
, status
;
1513 struct CBaseStorageVariant value
;
1520 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1523 tree
= proto_item_add_subtree(item
, ett_CDbProp
);
1525 id
= tvb_get_letohl(tvb
, offset
);
1526 str
= val_to_str(id
, vs
, "0x%08x");
1527 proto_tree_add_text(tree
, tvb
, offset
, 4, "Id: %s (0x%08x)", str
[0] == '0' ? "" : str
, id
);
1529 proto_item_append_text(item
, " Id: %s", str
);
1531 opt
= tvb_get_letohl(tvb
, offset
);
1532 proto_tree_add_text(tree
, tvb
, offset
, 4, "Options: %08x", opt
);
1535 status
= tvb_get_letohl(tvb
, offset
);
1536 proto_tree_add_text(tree
, tvb
, offset
, 4, "Status: %08x", status
);
1539 offset
= parse_CDbColId(tvb
, offset
, tree
, pad_tree
, "colid");
1541 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &value
, "vValue");
1543 str
= str_CBaseStorageVariant(&value
, true);
1544 proto_item_append_text(item
, " %s", str
);
1545 proto_item_set_end(item
, tvb
, offset
);
1550 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1551 proto_tree
*pad_tree
, const char *fmt
, ...)
1555 struct GuidPropertySet
*pset
;
1561 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1564 tree
= proto_item_add_subtree(item
, ett_CDbPropSet
);
1566 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "guidPropertySet");
1568 pset
= GuidPropertySet_find_guid(&guid
);
1571 proto_item_append_text(item
, " \"%s\" (%s)", pset
->desc
, pset
->def
);
1573 const char *guid_str
= guid_to_str(&guid
);
1574 proto_item_append_text(item
, " {%s}", guid_str
);
1577 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "guidPropertySet");
1579 num
= tvb_get_letohl(tvb
, offset
);
1580 proto_tree_add_text(tree
, tvb
, offset
, 4, "cProperties: %d", num
);
1582 proto_item_append_text(item
, " Num: %d", num
);
1584 for (i
= 0; i
<num
; i
++) {
1585 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "aProp[%d]", i
);
1586 offset
= parse_CDbProp(tvb
, offset
, tree
, pad_tree
, pset
, "aProp[%d]", i
);
1589 proto_item_set_end(item
, tvb
, offset
);
1593 static int parse_PropertySetArray(tvbuff_t
*tvb
, int offset
, int size_offset
,
1594 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1595 const char *fmt
, ...)
1597 const int offset_in
= offset
;
1605 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1608 tree
= proto_item_add_subtree(item
, ett_CDbPropSet_Array
);
1610 size
= tvb_get_letohl(tvb
, size_offset
);
1611 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_Blob1
, tvb
,
1612 size_offset
, 4, ENC_LITTLE_ENDIAN
);
1614 num
= tvb_get_letohl(tvb
, offset
);
1615 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_PropSets_num
, tvb
,
1616 offset
, 4, ENC_LITTLE_ENDIAN
);
1619 for (i
= 0; i
< (int)num
; i
++) {
1620 offset
= parse_CDbPropSet(tvb
, offset
, tree
, pad_tree
, "PropertySet[%d]", i
);
1623 proto_item_set_end(item
, tvb
, offset
);
1624 DISSECTOR_ASSERT(offset
- offset_in
== (int)size
);
1628 int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...)
1630 guint32 count
, v
, i
;
1636 item
= proto_tree_add_text_valist(tree
, tvb
, offset
, 0, fmt
, ap
);
1639 count
= tvb_get_letohl(tvb
, offset
);
1642 proto_item_append_text(item
, " Count %u [", count
);
1643 for (i
=0; i
<count
; i
++) {
1644 v
= tvb_get_letohl(tvb
, offset
);
1647 proto_item_append_text(item
, ",%u", v
);
1649 proto_item_append_text(item
, "%u", v
);
1652 proto_item_append_text(item
, "]");
1656 /* 2.2.1.23 RANGEBOUNDARY */
1657 int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1658 proto_tree
*pad_tree
, const char *fmt
, ...)
1661 guint8 labelPresent
;
1664 struct CBaseStorageVariant prval
;
1668 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1669 tree
= proto_item_add_subtree(item
, ett_RANGEBOUNDARY
);
1672 ulType
= tvb_get_letohl(tvb
, offset
);
1673 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType 0x%08x", ulType
);
1674 proto_item_append_text(item
, ": Type 0x%08x", ulType
);
1678 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &prval
, "prVal");
1680 labelPresent
= tvb_get_guint8(tvb
, offset
);
1681 proto_tree_add_text(tree
, tvb
, offset
, 1, "labelPresent: %s", labelPresent
? "True" : "False");
1687 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingLabelPresent");
1689 ccLabel
= tvb_get_letohl(tvb
, offset
);
1690 proto_tree_add_text(tree
, tvb
, offset
, 4, "ccLabel: %u", ccLabel
);
1693 label
= tvb_get_unicode_string(tvb
, offset
, 2*ccLabel
, ENC_LITTLE_ENDIAN
);
1694 proto_tree_add_text(tree
, tvb
, offset
, 2*ccLabel
, "Label: \"%s\"", label
);
1695 proto_item_append_text(item
, " Label: \"%s\"", label
);
1696 offset
+= 2*ccLabel
;
1699 proto_item_append_text(item
, " Val: %s", str_CBaseStorageVariant(&prval
, true));
1701 proto_item_set_end(item
, tvb
, offset
);
1706 /* 2.2.1.22 CRangeCategSpec */
1707 int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
1708 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1709 const char *fmt
, ...)
1715 guint32 lcid
, cRange
;
1718 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1719 tree
= proto_item_add_subtree(item
, ett_CRangeCategSpec
);
1722 lcid
= tvb_get_letohl(tvb
, offset
);
1723 proto_tree_add_text(tree
, tvb
, offset
, 4, "Lcid 0x%08x", lcid
);
1726 cRange
= tvb_get_letohl(tvb
, offset
);
1727 proto_tree_add_text(tree
, tvb
, offset
, 4, "cRange 0x%08x", cRange
);
1730 for (i
=0; i
<cRange
; i
++) {
1731 offset
= parse_RANGEBOUNDARY(tvb
, offset
, tree
, pad_tree
, "aRangeBegin[%u]", i
);
1735 proto_item_set_end(item
, tvb
, offset
);
1739 /* 2.2.1.21 CCategSpec */
1740 int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
1741 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1742 const char *fmt
, ...)
1751 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1752 tree
= proto_item_add_subtree(item
, ett_CCategSpec
);
1755 type
= tvb_get_letohl(tvb
, offset
);
1756 proto_tree_add_text(tree
, tvb
, offset
, 4, "Type 0x%08x", type
);
1757 proto_item_append_text(item
, " Type %u", type
);
1760 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "CSort");
1762 offset
= parse_CRangeCategSpec(tvb
, offset
, tree
, pad_tree
, "CRangeCategSpec");
1764 proto_item_set_end(item
, tvb
, offset
);
1768 /* 2.2.1.25 CAggregSpec */
1769 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
1770 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1771 const char *fmt
, ...)
1777 guint32 ccAlias
, idColumn
, ulMaxNumToReturn
, idRepresentative
;
1781 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1782 tree
= proto_item_add_subtree(item
, ett_CAggregSpec
);
1785 type
= tvb_get_guint8(tvb
, offset
);
1786 proto_tree_add_text(tree
, tvb
, offset
, 1, "type: %u", type
);
1787 proto_item_append_text(item
, "type: %u", type
);
1790 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding");
1792 ccAlias
= tvb_get_letohl(tvb
, offset
);
1793 proto_tree_add_text(tree
, tvb
, offset
, 1, "ccAlias: %u", ccAlias
);
1796 alias
= tvb_get_unicode_string(tvb
, offset
, 2*ccAlias
, ENC_LITTLE_ENDIAN
);
1797 proto_tree_add_text(tree
, tvb
, offset
, 2*ccAlias
, "Alias: %s", alias
);
1798 offset
+= 2*ccAlias
;
1800 idColumn
= tvb_get_letohl(tvb
, offset
);
1801 proto_tree_add_text(tree
, tvb
, offset
, 1, "idColumn: %u", idColumn
);
1804 ulMaxNumToReturn, idRepresentative;
1806 fprintf(stderr
, "WARNING, dont know if optional members are present!\n ");
1808 proto_item_set_end(item
, tvb
, offset
);
1812 /* 2.2.1.24 CAggregSet */
1813 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
1814 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1815 const char *fmt
, ...)
1824 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1825 tree
= proto_item_add_subtree(item
, ett_CAggregSet
);
1828 cCount
= tvb_get_letohl(tvb
, offset
);
1829 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1832 for (i
=0; i
<cCount
; i
++) {
1833 /* 2.2.1.25 CAggregSpec */
1834 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "AggregSpecs[%u]", i
);
1837 proto_item_set_end(item
, tvb
, offset
);
1841 /* 2.2.1.27 CAggregSortKey */
1842 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
1843 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1844 const char *fmt
, ...)
1853 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1854 tree
= proto_item_add_subtree(item
, ett_CAggregSortKey
);
1857 order
= tvb_get_letohl(tvb
, offset
);
1858 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", order
);
1861 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "ColumnSpec");
1863 proto_item_set_end(item
, tvb
, offset
);
1868 /* 2.2.1.26 CSortAggregSet */
1869 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
1870 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1871 const char *fmt
, ...)
1880 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1881 tree
= proto_item_add_subtree(item
, ett_CSortAggregSet
);
1884 cCount
= tvb_get_letohl(tvb
, offset
);
1885 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1888 for (i
=0; i
<cCount
; i
++) {
1889 /* 2.2.1.27 CAggregSortKey */
1890 offset
= parse_CAggregSortKey(tvb
, offset
, tree
, pad_tree
, "SortKeys[%u]", i
);
1893 proto_item_set_end(item
, tvb
, offset
);
1897 enum CInGroupSortAggregSet_type
{
1898 GroupIdDefault
= 0x00, /* The default for all ranges. */
1899 GroupIdMinValue
= 0x01, /*The first range in the parent's group.*/
1900 GroupIdNull
= 0x02, /*The last range in the parent's group.*/
1901 GroupIdValue
= 0x03,
1904 /* 2.2.1.29 CInGroupSortAggregSet */
1905 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
1906 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1907 const char *fmt
, ...)
1912 enum CInGroupSortAggregSet_type type
;
1915 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1916 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSet
);
1919 type
= tvb_get_guint8(tvb
, offset
);
1920 proto_tree_add_text(tree
, tvb
, offset
, 1, "Type: 0x%02x", (unsigned)type
);
1923 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "CInGroupSortAggregSet");
1925 if (type
== GroupIdValue
) {
1926 struct CBaseStorageVariant id
;
1927 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &id
, "inGroupId");
1930 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1932 proto_item_set_end(item
, tvb
, offset
);
1937 /* 2.2.1.28 CInGroupSortAggregSets */
1938 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
1939 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1940 const char *fmt
, ...)
1949 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1950 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSets
);
1953 cCount
= tvb_get_letohl(tvb
, offset
);
1954 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
1957 for (i
=0; i
<cCount
; i
++) {
1958 /* 2.2.1.29 CInGroupSortAggregSet */
1959 offset
= parse_CInGroupSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortSets[%u]", i
);
1962 proto_item_set_end(item
, tvb
, offset
);
1966 /* 2.2.1.20 CCategorizationSpec */
1967 int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
1968 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1969 const char *fmt
, ...)
1971 guint32 cMaxResults
;
1978 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1979 tree
= proto_item_add_subtree(item
, ett_CCategorizationSpec
);
1982 /* 2.2.1.18 CColumnSet */
1983 offset
= parse_CColumnSet(tvb
, offset
, tree
, "csColumns");
1985 /* 2.2.1.21 CCategSpec */
1986 offset
= parse_CCategSpec(tvb
, offset
, tree
, pad_tree
, "Spec");
1988 /* 2.2.1.24 CAggregSet */
1989 offset
= parse_CAggregSet(tvb
, offset
, tree
, pad_tree
, "AggregSet");
1991 /* 2.2.1.26 CSortAggregSet */
1992 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
1994 /* 2.2.1.28 CInGroupSortAggregSets */
1995 offset
= parse_CInGroupSortAggregSets(tvb
, offset
, tree
, pad_tree
, "InGroupSortAggregSets");
1997 cMaxResults
= tvb_get_letohl(tvb
, offset
);
1998 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", cMaxResults
);
2001 proto_item_set_end(item
, tvb
, offset
);
2005 int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
2006 proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
2007 const char *fmt
, ...)
2009 guint32 opt
, maxres
, timeout
;
2016 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2017 tree
= proto_item_add_subtree(item
, ett_CRowsetProperties
);
2020 opt
= tvb_get_letohl(tvb
, offset
);
2021 proto_tree_add_text(tree
, tvb
, offset
, 4, "uBooleanOptions: 0x%08x", opt
);
2024 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMaxOpenRows (ignored)");
2027 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMemoryUsage (ignored)");
2030 maxres
= tvb_get_letohl(tvb
, offset
);
2031 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", maxres
);
2034 timeout
= tvb_get_letohl(tvb
, offset
);
2035 proto_tree_add_text(tree
, tvb
, offset
, 4, "cCmdTimeout: %u", timeout
);
2038 proto_item_set_end(item
, tvb
, offset
);
2042 int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
2043 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2044 const char *fmt
, ...)
2052 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2053 tree
= proto_item_add_subtree(item
, ett_CPidMapper
);
2056 count
= tvb_get_letohl(tvb
, offset
);
2057 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2060 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "CPidMapper_PropSpec");
2062 for (i
=0; i
<count
; i
++) {
2063 struct CFullPropSpec v
;
2065 offset
= parse_padding(tvb
, offset
, 4, pad_tree
,
2066 "CPidMapper_PropSpec[%u]", i
); //at begin or end of loop???
2067 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
, "PropSpec[%u]", i
);
2070 proto_item_set_end(item
, tvb
, offset
);
2074 /* Code to actually dissect the packets */
2076 static int dissect_CPMConnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
2084 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
2085 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
2086 proto_item_set_text(ti
, "CPMConnect%s", in
? "In" : "Out");
2087 col_append_str(pinfo
->cinfo
, COL_INFO
, "Connect");
2089 version
= tvb_get_letohl(tvb
, offset
);
2090 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_Connect_Version
, tvb
,
2091 offset
, 4, ENC_LITTLE_ENDIAN
);
2092 if (version
& 0xffff0000) {
2093 proto_item_append_text(ti
, " 64 bit");
2095 switch (version
& 0xffff) {
2097 proto_item_append_text(ti
, " w2k8 or vista");
2100 proto_item_append_text(ti
, " XP or w2k3, with Windows Search 4.0");
2103 proto_item_append_text(ti
, " win7 or w2k8r2");
2109 guint32 blob_size1_off
, blob_size2_off
;
2110 proto_tree
*pad_tree
;
2112 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
2113 pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
2115 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_ClientIsRemote
, tvb
,
2116 offset
, 4, ENC_LITTLE_ENDIAN
);
2120 blob_size1_off
= offset
;
2123 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcbBlob2");
2126 blob_size2_off
= offset
;
2129 offset
= parse_padding(tvb
, offset
, 16, pad_tree
, "_padding");
2131 len
= tvb_unicode_strsize(tvb
, offset
);
2132 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_MachineName
, tvb
,
2133 offset
, len
, ENC_UTF_16
);
2134 /*This shouldnt be necessary, is this a bug or is there some GUI setting I've missed?*/
2135 proto_item_set_text(ti
, "Remote machine: %s",
2136 tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
2139 len
= tvb_unicode_strsize(tvb
, offset
);
2140 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_UserName
, tvb
,
2141 offset
, len
, ENC_UTF_16
);
2142 proto_item_set_text(ti
, "User: %s", tvb_get_unicode_string(tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
2145 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcPropSets");
2147 offset
= parse_PropertySetArray(tvb
, offset
, blob_size1_off
, tree
, pad_tree
, "PropSets");
2149 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingExtPropset");
2151 offset
= parse_PropertySetArray(tvb
, offset
, blob_size2_off
, tree
, pad_tree
, "ExtPropset");
2153 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "???");
2155 DISSECTOR_ASSERT(offset
== (int)tvb_length(tvb
));
2157 /* make "Padding" the last item */
2158 proto_tree_move_item(tree
, ti
, proto_tree_get_parent(pad_tree
));
2162 return tvb_length(tvb
);
2165 static int dissect_CPMDisconnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2167 col_append_str(pinfo
->cinfo
, COL_INFO
, "Disconnect");
2168 return tvb_length(tvb
);
2171 static int dissect_CPMCreateQuery(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
2177 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
2178 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
2180 proto_item_set_text(ti
, "CPMCreateQuery%s", in
? "In" : "Out");
2181 col_append_str(pinfo
->cinfo
, COL_INFO
, "CreateQuery");
2184 proto_item
*ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
2185 proto_tree
*pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
2186 guint8 CColumnSetPresent
, CRestrictionPresent
, CSortSetPresent
, CCategorizationSetPresent
;
2187 guint32 size
= tvb_get_letohl(tvb
, offset
);
2188 proto_tree_add_text(tree
, tvb
, offset
, 4, "size");
2189 proto_tree_add_text(tree
, tvb
, offset
, size
, "ALL");
2192 CColumnSetPresent
= tvb_get_guint8(tvb
, offset
);
2193 proto_tree_add_text(tree
, tvb
, offset
, 1, "CColumnSetPresent: %s", CColumnSetPresent
? "True" : "False");
2196 if (CColumnSetPresent
) {
2197 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCColumnSetPresent");
2198 offset
= parse_CColumnSet(tvb
, offset
, tree
, "CColumnSet");
2201 CRestrictionPresent
= tvb_get_guint8(tvb
, offset
);
2202 proto_tree_add_text(tree
, tvb
, offset
, 1, "CRestrictionPresent: %s", CColumnSetPresent
? "True" : "False");
2204 if (CRestrictionPresent
) {
2205 offset
= parse_CRestrictionArray(tvb
, offset
, tree
, pad_tree
, "RestrictionArray");
2208 CSortSetPresent
= tvb_get_guint8(tvb
, offset
);
2209 proto_tree_add_text(tree
, tvb
, offset
, 1, "CSortSetPresent: %s", CSortSetPresent
? "True" : "False");
2211 if (CSortSetPresent
) {
2212 offset
= parse_padding(tvb
, offset
, 4, tree
, "paddingCSortSetPresent");
2214 proto_tree_add_text(tree
, tvb
, offset
, 8, "XXX");
2217 offset
= parse_CSortSet(tvb
, offset
, tree
, pad_tree
, "SortSet");
2220 CCategorizationSetPresent
= tvb_get_guint8(tvb
, offset
);
2221 proto_tree_add_text(tree
, tvb
, offset
, 1, "CCategorizationSetPresent: %s", CCategorizationSetPresent
? "True" : "False");
2224 if (CCategorizationSetPresent
) {
2226 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCCategorizationSetPresent");
2227 /* 2.2.1.19 CCategorizationSet */
2228 count
= tvb_get_letohl(tvb
, offset
);
2229 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2231 for (i
=0; i
<count
; i
++) {
2232 offset
= parse_CCategorizationSpec(tvb
, offset
, tree
, pad_tree
, "categories[%u]", i
);
2236 offset
= parse_padding(tvb
, offset
, 4, tree
, "XXXX"); //XXX
2238 offset
= parse_CRowsetProperties(tvb
, offset
, tree
, pad_tree
, "RowSetProperties");
2240 offset
= parse_CPidMapper(tvb
, offset
, tree
, pad_tree
, "PidMapper");
2243 return tvb_length(tvb
);
2246 static int dissect_CPMFreeCursor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2248 col_append_str(pinfo
->cinfo
, COL_INFO
, "FreeCursor");
2249 return tvb_length(tvb
);
2252 static int dissect_CPMGetRows(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2254 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRows");
2255 return tvb_length(tvb
);
2258 static int dissect_CPMRatioFinished(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2260 col_append_str(pinfo
->cinfo
, COL_INFO
, "RatioFinished");
2261 return tvb_length(tvb
);
2264 static int dissect_CPMCompareBmk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2266 col_append_str(pinfo
->cinfo
, COL_INFO
, "CompareBmk");
2267 return tvb_length(tvb
);
2270 static int dissect_CPMGetApproximatePosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2272 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetApproximatePosition");
2273 return tvb_length(tvb
);
2276 static int dissect_CPMSetBindings(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2278 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetBindings");
2279 return tvb_length(tvb
);
2282 static int dissect_CPMGetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2284 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetNotify");
2285 return tvb_length(tvb
);
2288 static int dissect_CPMSendNotifyOut(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2290 col_append_str(pinfo
->cinfo
, COL_INFO
, "SendNotify");
2291 return tvb_length(tvb
);
2294 static int dissect_CPMGetQueryStatus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2296 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatus");
2297 return tvb_length(tvb
);
2300 static int dissect_CPMCiState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2302 col_append_str(pinfo
->cinfo
, COL_INFO
, "CiState");
2303 return tvb_length(tvb
);
2306 static int dissect_CPMFetchValue(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2308 col_append_str(pinfo
->cinfo
, COL_INFO
, "FetchValue");
2309 return tvb_length(tvb
);
2312 static int dissect_CPMGetQueryStatusEx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2314 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatusEx");
2315 return tvb_length(tvb
);
2318 static int dissect_CPMRestartPosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2320 col_append_str(pinfo
->cinfo
, COL_INFO
, "RestartPosition");
2321 return tvb_length(tvb
);
2324 static int dissect_CPMSetCatState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2326 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetCatState");
2327 return tvb_length(tvb
);
2330 static int dissect_CPMGetRowsetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2332 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRowsetNotify");
2333 return tvb_length(tvb
);
2336 static int dissect_CPMFindIndices(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2338 col_append_str(pinfo
->cinfo
, COL_INFO
, "FindIndices");
2339 return tvb_length(tvb
);
2342 static int dissect_CPMSetScopePrioritization(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2344 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetScopePrioritization");
2345 return tvb_length(tvb
);
2348 static int dissect_CPMGetScopeStatistics(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2350 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetScopeStatistics");
2351 return tvb_length(tvb
);
2354 static void debug_frame(int frame
)
2356 static const char *dbg_wait
= NULL
;
2357 static int wait_frame
= -1;
2359 if (dbg_wait
== NULL
) {
2360 dbg_wait
= getenv("DBG_FRAME");
2361 if (dbg_wait
== NULL
) {
2364 wait_frame
= atoi(dbg_wait
);
2368 if (frame
== wait_frame
) {
2369 static volatile gboolean wait
= 1;
2370 fprintf(stderr
, "waiting for debugger with pid: %u\n", getpid());
2379 dissect_mswsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gboolean in
)
2381 proto_tree
*mswsp_tree
= NULL
;
2388 int (*fn
)(tvbuff_t
*, packet_info
*, proto_tree
*, gboolean
);
2390 if (tvb_length(tvb
) < 16) {
2394 hdr
.msg
= tvb_get_letohl(tvb
, 0);
2398 fn
= dissect_CPMConnect
;
2401 fn
= dissect_CPMDisconnect
;
2404 fn
= dissect_CPMCreateQuery
;
2407 fn
= dissect_CPMFreeCursor
;
2410 fn
= dissect_CPMGetRows
;
2413 fn
= dissect_CPMRatioFinished
;
2416 fn
= dissect_CPMCompareBmk
;
2419 fn
= dissect_CPMGetApproximatePosition
;
2422 fn
= dissect_CPMSetBindings
;
2425 fn
= dissect_CPMGetNotify
;
2428 fn
= dissect_CPMSendNotifyOut
;
2431 fn
= dissect_CPMGetQueryStatus
;
2434 fn
= dissect_CPMCiState
;
2437 fn
= dissect_CPMFetchValue
;
2440 fn
= dissect_CPMGetQueryStatusEx
;
2443 fn
= dissect_CPMRestartPosition
;
2446 fn
= dissect_CPMSetCatState
;
2449 fn
= dissect_CPMGetRowsetNotify
;
2452 fn
= dissect_CPMFindIndices
;
2455 fn
= dissect_CPMSetScopePrioritization
;
2458 fn
= dissect_CPMGetScopeStatistics
;
2464 hdr
.status
= tvb_get_letohl(tvb
, 4);
2465 hdr
.checksum
= tvb_get_letohl(tvb
, 8);
2467 /* col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS-WSP"); */
2468 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, " WSP");
2469 /* col_clear(pinfo->cinfo, COL_INFO); */
2471 col_set_str(pinfo
->cinfo
, COL_INFO
, "WSP ");
2472 col_append_str(pinfo
->cinfo
, COL_INFO
, in
? "Request: " : "Response: ");
2475 proto_tree
*hdr_tree
;
2476 proto_item
*ti
, *hti
;
2478 ti
= proto_tree_add_item(tree
, proto_mswsp
, tvb
, 0, -1, ENC_NA
);
2479 mswsp_tree
= proto_item_add_subtree(ti
, ett_mswsp
);
2481 hti
= proto_tree_add_item(mswsp_tree
, hf_mswsp_hdr
, tvb
, 0, 16, ENC_NA
);
2482 hdr_tree
= proto_item_add_subtree(hti
, ett_mswsp_hdr
);
2484 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_msg
, tvb
,
2485 0, 4, ENC_LITTLE_ENDIAN
);
2486 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_status
,
2487 tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
2488 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_checksum
,
2489 tvb
, 8, 4, ENC_LITTLE_ENDIAN
);
2490 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_reserved
, tvb
,
2491 12, 4, ENC_LITTLE_ENDIAN
);
2494 fn(tvb
, pinfo
, mswsp_tree
, in
);
2496 /* Return the amount of data this dissector was able to dissect */
2497 return tvb_length(tvb
);
2501 /* Register the protocol with Wireshark */
2503 /* this format is require because a script is used to build the C function
2504 that calls all the protocol registration.
2508 proto_register_mswsp(void)
2510 module_t
*mswsp_module
;
2512 /* Setup list of header fields See Section 1.6.1 for details*/
2513 static const value_string msg_ids
[] = {
2514 {0x000000C8, "CPMConnect"}, /* In/Out */
2515 {0x000000C9, "CPMDisconnect"},
2516 {0x000000CA, "CPMCreateQuery"}, /* In/Out */
2517 {0x000000CB, "CPMFreeCursor"}, /* In/Out */
2518 {0x000000CC, "CPMGetRows"}, /* In/Out */
2519 {0x000000CD, "CPMRatioFinished"}, /* In/Out */
2520 {0x000000CE, "CPMCompareBmk"}, /* In/Out */
2521 {0x000000CF, "CPMGetApproximatePosition"}, /* In/Out */
2522 {0x000000D0, "CPMSetBindingsIn"},
2523 {0x000000D1, "CPMGetNotify"},
2524 {0x000000D2, "CPMSendNotifyOut"},
2525 {0x000000D7, "CPMGetQueryStatusIn"}, /* In/Out */
2526 {0x000000D9, "CPMCiStateInOut"},
2527 {0x000000E4, "CPMFetchValue"}, /* In/Out */
2528 {0x000000E7, "CPMGetQueryStatusEx"}, /* In/Out */
2529 {0x000000E8, "CPMRestartPositionIn"},
2530 {0x000000EC, "CPMSetCatStateIn"}, /* (not supported) */
2531 {0x000000F1, "CPMGetRowsetNotify"}, /* In/Out */
2532 {0x000000F2, "CPMFindIndices"}, /* In/Out */
2533 {0x000000F3, "CPMSetScopePrioritization"}, /* In/Out */
2534 {0x000000F4, "CPMGetScopeStatistics"}, /* In/Out */
2536 static hf_register_info hf
[] = {
2538 { "Header", "mswsp.hdr",
2539 FT_NONE
, BASE_NONE
, NULL
, 0,
2540 "Message header", HFILL
}
2542 { &hf_mswsp_hdr_msg
,
2543 { "Msg id", "mswsp.hdr.id",
2544 FT_UINT32
, BASE_HEX
, VALS(msg_ids
), 0,
2545 "Message id", HFILL
}
2547 { &hf_mswsp_hdr_status
,
2548 { "Status", "mswsp.hdr.status",
2549 FT_UINT32
, BASE_HEX
, NULL
, 0,
2552 { &hf_mswsp_hdr_checksum
,
2553 { "checksum", "mswsp.hdr.checksum",
2554 FT_UINT32
, BASE_HEX
, NULL
, 0,
2557 { &hf_mswsp_hdr_reserved
,
2558 { "Reserved", "mswsp.hdr.reserved",
2559 FT_UINT32
, BASE_HEX
, NULL
, 0,
2563 { "msg", "mswsp.msg",
2564 FT_NONE
, BASE_NONE
, NULL
, 0,
2567 { &hf_mswsp_msg_Connect_Version
,
2568 { "Version", "mswsp.Connect.version",
2569 FT_UINT32
, BASE_HEX
, NULL
, 0,
2572 { &hf_mswsp_msg_ConnectIn_ClientIsRemote
,
2573 { "Remote", "mswsp.ConnectIn.isRemote",
2574 FT_BOOLEAN
, BASE_HEX
, NULL
, 0,
2575 "Client is remote",HFILL
}
2577 { &hf_mswsp_msg_ConnectIn_Blob1
,
2578 { "Size", "mswsp.ConnectIn.propset.size",
2579 FT_UINT32
, BASE_DEC
, NULL
, 0,
2580 "Size of PropSet fields",HFILL
}
2582 { &hf_mswsp_msg_ConnectIn_Blob2
,
2583 { "Size", "mswsp.ConnectIn.extpropset.size",
2584 FT_UINT32
, BASE_DEC
, NULL
, 0,
2585 "Size of ExtPropSet fields",HFILL
}
2587 { &hf_mswsp_msg_ConnectIn_MachineName
,
2588 { "Remote machine", "mswsp.ConnectIn.machine",
2589 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2590 "Name of remote machine",HFILL
}
2592 { &hf_mswsp_msg_ConnectIn_UserName
,
2593 { "User", "mswsp.ConnectIn.user",
2594 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2595 "Name of remote user",HFILL
}
2597 { &hf_mswsp_msg_ConnectIn_PropSets_num
,
2598 { "Num", "mswsp.ConnectIn.propset.num",
2599 FT_UINT32
, BASE_DEC
, NULL
, 0,
2600 "Number of Property Sets", HFILL
}
2602 { &hf_mswsp_msg_ConnectIn_ExtPropSets_num
,
2603 { "Num", "mswsp.ConnectIn.extpropset.num",
2604 FT_UINT32
, BASE_DEC
, NULL
, 0,
2605 "Number of extended Property Sets", HFILL
}
2610 /* Setup protocol subtree array */
2611 static gint
*ett
[] = {
2616 &ett_mswsp_property_restriction
,
2617 &ett_CRestrictionArray
,
2618 &ett_CBaseStorageVariant
,
2619 &ett_CBaseStorageVariant_Vector
,
2620 &ett_CBaseStorageVariant_Array
,
2625 &ett_CDbPropSet_Array
,
2627 &ett_CNodeRestriction
,
2628 &ett_CPropertyRestriction
,
2629 &ett_CCoercionRestriction
,
2630 &ett_CContentRestriction
,
2632 &ett_CRangeCategSpec
,
2636 &ett_CCategorizationSpec
,
2637 &ett_CAggregSortKey
,
2638 &ett_CSortAggregSet
,
2639 &ett_CInGroupSortAggregSet
,
2640 &ett_CInGroupSortAggregSets
,
2641 &ett_CRowsetProperties
,
2646 &ett_CNatLanguageRestriction
,
2651 /* Register the protocol name and description */
2652 proto_mswsp
= proto_register_protocol("Windows Search Protocol",
2655 /* Required function calls to register the header fields and subtrees used */
2656 proto_register_field_array(proto_mswsp
, hf
, array_length(hf
));
2657 proto_register_subtree_array(ett
, array_length(ett
));
2659 for (i
=0; i
<(int)array_length(GuidPropertySet
); i
++) {
2660 guids_add_guid(&GuidPropertySet
[i
].guid
, GuidPropertySet
[i
].def
);
2664 /* Register preferences module (See Section 2.6 for more on preferences) */
2665 /* (Registration of a prefs callback is not required if there are no */
2666 /* prefs-dependent registration functions (eg: a port pref). */
2667 /* See proto_reg_handoff below. */
2668 /* If a prefs callback is not needed, use NULL instead of */
2669 /* proto_reg_handoff_mswsp in the following). */
2670 mswsp_module
= prefs_register_protocol(proto_mswsp
,
2671 proto_reg_handoff_mswsp
);
2673 /* Register preferences module under preferences subtree.
2674 Use this function instead of prefs_register_protocol if you want to group
2675 preferences of several protocols under one preferences subtree.
2676 Argument subtree identifies grouping tree node name, several subnodes can be
2677 specified using slash '/' (e.g. "OSI/X.500" - protocol preferences will be
2678 accessible under Protocols->OSI->X.500-><PROTOSHORTNAME> preferences node.
2680 /* mswsp_module = prefs_register_protocol_subtree(subtree, */
2681 /* proto_mswsp, proto_reg_handoff_mswsp); */
2683 /* Register a sample preference */
2684 prefs_register_bool_preference(mswsp_module
, "show_hex",
2685 "Display numbers in Hex",
2686 "Enable to display numerical values in hexadecimal.",
2689 /* Register a sample port preference */
2690 prefs_register_uint_preference(mswsp_module
, "tcp.port", "mswsp TCP Port",
2691 " mswsp TCP port if other than the default",
2695 static int dissect_mswsp_smb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2696 smb_info_t
*si
= pinfo
->private_data
;
2697 gboolean in
= si
->request
;
2699 smb_transact_info_t
*tri
= (si
->sip
->extra_info_type
== SMB_EI_TRI
) ? si
->sip
->extra_info
: NULL
;
2700 smb_fid_info_t
*fid_info
= NULL
;
2703 debug_frame((int)pinfo
->fd
->num
);
2705 fprintf(stderr
, "dissect_mswsp_smb %s frame: %d tid: %d op: %02x ",
2706 in
? "Request" : "Response",
2707 pinfo
->fd
->num
, si
->tid
, si
->cmd
);
2710 fprintf(stderr
, " extra_info_type: %d\n", si
->sip
->extra_info_type
);
2714 for (iter
= si
->ct
->GSL_fid_info
; iter
; iter
= g_slist_next(iter
)) {
2715 smb_fid_info_t
*info
= iter
->data
;
2716 if ((info
->tid
== si
->tid
) && (info
->fid
== tri
->fid
)) {
2722 if (!fid_info
|| !fid_info
->fsi
|| !fid_info
->fsi
->filename
) {
2723 fprintf(stderr
, " no %s\n", fid_info
? (fid_info
->fsi
? "filename" : "fsi") : "fid_info");
2727 fprintf(stderr
, " file: %s\n", fid_info
->fsi
->filename
);
2729 if (strcasecmp(fid_info
->fsi
->filename
, "\\MsFteWds") != 0) {
2733 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2737 static int dissect_mswsp_smb2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
2738 smb2_info_t
*si
= pinfo
->private_data
;
2739 gboolean in
= !(si
->flags
& SMB2_FLAGS_RESPONSE
);
2741 //si->tree->share_type == SMB2_SHARE_TYPE_PIPE
2742 //si->tree->connect_frame
2744 debug_frame((int)pinfo
->fd
->num
);
2746 fprintf(stderr
, "dissect_mswsp %d <> %d : op %02x %s %s type: %d extra_file: %s\n",
2747 pinfo
->fd
->num
, si
->tree
? (int)si
->tree
->connect_frame
: -1,
2749 pinfo
->dcerpc_procedure_name
? pinfo
->dcerpc_procedure_name
: "<NULL>",
2750 in
? "Request" : "Response", si
->tree
? si
->tree
->share_type
: -1,
2751 si
->saved
? (si
->saved
->extra_info_type
== SMB2_EI_FILENAME
? (char*)si
->saved
->extra_info
: "<OTHER>") : "<NONE>"
2755 if (strcmp(pinfo
->dcerpc_procedure_name
, "File: MsFteWds") != 0) {
2759 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
2764 /* If this dissector uses sub-dissector registration add a registration routine.
2765 This exact format is required because a script is used to find these
2766 routines and create the code that calls these routines.
2768 If this function is registered as a prefs callback (see prefs_register_protocol
2769 above) this function is also called by preferences whenever "Apply" is pressed;
2770 In that case, it should accommodate being called more than once.
2772 Simple form of proto_reg_handoff_mswsp which can be used if there are
2773 no prefs-dependent registration function calls.
2777 proto_reg_handoff_mswsp(void)
2779 heur_dissector_add("smb_transact", dissect_mswsp_smb
, proto_mswsp
);
2780 heur_dissector_add("smb2_heur_subdissectors", dissect_mswsp_smb2
, proto_mswsp
);
2785 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2790 * indent-tabs-mode: nil
2793 * vi: set shiftwidth=4 tabstop=8 expandtab:
2794 * :indentSize=4:tabSize=8:noTabs=true: