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;
121 static gint ett_CColumnGroup
= -1;
122 static gint ett_CColumnGroupArray
= -1;
123 static gint ett_LCID
= -1;
124 static gint ett_CTableColumn
= -1;
126 /******************************************************************************/
127 struct GuidPropertySet
{
131 const value_string
*id_map
;
135 static const value_string DBPROPSET_FSCIFRMWRK_EXT_IDS
[] = {
136 {0x02, "DBPROP_CI_CATALOG_NAME"},
137 {0x03, "DBPROP_CI_INCLUDE_SCOPES"},
138 {0x04, "DBPROP_CI_SCOPE_FLAGS"},
139 {0x07, "DBPROP_CI_QUERY_TYPE"},
143 static const value_string DBPROPSET_QUERYEXT_IDS
[] = {
144 {0x02, "DBPROP_USECONTENTINDEX"},
145 {0x03, "DBPROP_DEFERNONINDEXEDTRIMMING"},
146 {0x04, "DBPROP_USEEXTENDEDDBTYPES"},
147 {0x05, "DBPROP_IGNORENOISEONLYCLAUSES"},
148 {0x06, "DBPROP_GENERICOPTIONS_STRING"},
149 {0x07, "DBPROP_FIRSTROWS"},
150 {0x08, "DBPROP_DEFERCATALOGVERIFICATION"},
151 {0x0a, "DBPROP_GENERATEPARSETREE"},
152 {0x0c, "DBPROP_FREETEXTANYTERM"},
153 {0x0d, "DBPROP_FREETEXTUSESTEMMING"},
154 {0x0e, "DBPROP_IGNORESBRI"},
155 {0x10, "DBPROP_ENABLEROWSETEVENTS"},
159 static const value_string DBPROPSET_CIFRMWRKCORE_EXT_IDS
[] = {
160 {0x02, "DBPROP_MACHINE"},
161 {0x03, "DBPROP_CLIENT_CLSID"},
165 static const value_string DBPROPSET_MSIDXS_ROWSETEXT_IDS
[] = {
166 {0x02, "MSIDXSPROP_ROWSETQUERYSTATUS"},
167 {0x03, "MSIDXSPROP_COMMAND_LOCALE_STRING"},
168 {0x04, "MSIDXSPROP_QUERY_RESTRICTION"},
169 {0x05, "MSIDXSPROP_PARSE_TREE"},
170 {0x06, "MSIDXSPROP_MAX_RANK"},
171 {0x07, "MSIDXSPROP_RESULTS_FOUND"},
176 static const value_string QueryGuid_IDS
[] = {
177 {0x02, "RankVector"},
178 {0x03, "System.Search.Rank"},
179 {0x04, "System.Search.HitCount"},
180 {0x05, "System.Search.EntryID"},
182 {0x09, "System.ItemURL"},
187 static const value_string StorageGuid_IDS
[] = {
188 {0x02, "System.ItemFolderNameDisplay"},
190 {0x04, "System.ItemTypeText"},
193 {0x0a, "System.ItemNameDisplay"},
195 {0x0c, "System.Size"},
196 {0x0d, "System.FileAttributes"},
197 {0x0e, "System.DateModified"},
198 {0x0f, "System.DateCreated"},
199 {0x10, "System.DateAccessed"},
201 {0x13, "System.Search.Contents"},
202 {0x14, "ShortFilename"},
208 static const value_string DocPropSetGuid_IDS
[] = {
209 {0x02, "System.Title"},
210 {0x03, "System.Subject"},
211 {0x04, "System.Author"},
212 {0x05, "System.Keywords"},
213 {0x06, "System.Comment"},
214 {0x07, "DocTemplate"},
215 {0x08, "System.Document.LastAuthor"},
216 {0x09, "System.Document.RevisionNumber"},
217 {0x0a, "System.Document.EditTime???"},
218 {0x0b, "System.Document.DatePrinted"},
219 {0x0c, "System.Document.DateCreated"},
220 {0x0d, "System.Document.DateSaved"},
221 {0x0e, "System.Document.PageCount"},
222 {0x0f, "System.Document.WordCount"},
223 {0x10, "System.Document.CharacterCount"},
224 {0x11, "DocThumbnail"},
225 {0x12, "System.ApplicationName"},
229 static const value_string ShellDetails_IDS
[] = {
230 { 5, "System.ComputerName"},
231 { 8, "System.ItemPathDisplayNarrow"},
232 { 9, "PercivedType"},
233 {11, "System.ItemType"},
235 {14, "TotalFileSize"},
236 {24, "System.ParsingName"},
237 {25, "System.SFGAOFlags"},
241 static const value_string PropSet1_IDS
[] = {
242 {100, "System.ThumbnailCacheId"},
246 static const value_string PropSet2_IDS
[] = {
251 static const value_string MusicGuid_IDS
[] = {
255 static const value_string PropSet3_IDS
[] = {
256 { 2, "System.Message.BccAddress"},
257 { 3, "System.Message.BccName"},
258 { 4, "System.Message.CcAddress"},
259 { 5, "System.Message.CcName"},
260 { 6, "System.ItemFolderPathDisplay"},
261 { 7, "System.ItemPathDisplay"},
262 { 9, "System.Communication.AccountName"},
263 {10, "System.IsRead"},
264 {11, "System.Importance"},
265 {12, "System.FlagStatus"},
266 {13, "System.Message.FromAddress"},
267 {14, "System.Message.FromName"},
268 {15, "System.Message.Store"},
269 {16, "System.Message.ToAddress"},
270 {17, "System.Message.ToName"},
271 {18, "System.Contact.WebPage"},
272 {19, "System.Message.DateSent"},
273 {20, "System.Message.DateReceived"},
274 {21, "System.Message.AttachmentNames"},
278 static const value_string PropSet4_IDS
[] = {
279 {100, "System.ItemFolderPathDisplayNarrow"},
283 static const value_string PropSet5_IDS
[] = {
284 {100, "System.Contact.FullName"},
288 static const value_string PropSet6_IDS
[] = {
289 {100, "System.ItemAuthors"},
293 static const value_string PropSet7_IDS
[] = {
294 {2, "System.Shell.OmitFromView"},
298 static const value_string PropSet8_IDS
[] = {
299 {2, "System.Shell.SFGAOFlagsStrings"},
300 {3, "System.Link.TargetSFGAOFlagsStrings"},
304 static const value_string PropSet9_IDS
[] = {
305 {100, "System.ItemDate"},
309 static const value_string PropSet10_IDS
[] = {
310 { 5, "System.MIMEType"},
311 { 8, "System.Search.GatherTime"},
312 { 9, "System.Search.AccessCount"},
313 {11, "System.Search.LastIndexedTotalTime"},
317 static const value_string PropSet11_IDS
[] = {
318 {5, "System.Priority"},
319 {8, "System.Messagee.HasAttachments"},
323 static const value_string DocCharacter_IDS
[] = {
324 {2, "System.Search.Autosummary"},
328 static const value_string PropSet12_IDS
[] = {
329 {100, "System.IsDeleted"},
333 static const value_string PropSet13_IDS
[] = {
334 {100, "System.IsAttachment"},
338 static const value_string PropSet14_IDS
[] = {
339 {100, "System.Message.ConversationID"},
340 {101, "System.Message.ConversationIndex"},
344 static const value_string DocPropSetGuid2_IDS
[] = {
345 {0x02, "System.Category"},
346 {0x03, "System.Document.PresentationFormat"},
347 {0x04, "System.Document.ByteCount"},
348 {0x05, "System.Document.LineCount"},
349 {0x06, "System.Document.ParagraphCount"},
350 {0x07, "System.Document.SlideCount"},
351 {0x08, "DocNoteCount"},
352 {0x09, "System.Document.HiddenSlideCount"},
353 {0x0D, "DocPartTitles"},
354 {0x0E, "System.Document.Manager"},
355 {0x0F, "System.Company"},
359 static const value_string SystemContact_IDS
[] = {
360 { 6, "System.Contact.JobTitle"},
361 { 7, "System.Contact.OfficeLocation"},
362 {20, "System.Contact.HomeTelephone"},
363 {25, "System.Contact.PrimaryTelephone"},
364 {35, "System.Contact.MobileTelephone"},
365 {47, "System.Contact.Birthday"},
366 {48, "System.Contact.PrimaryEmailAddress"},
367 {65, "System.Contact.HomeAddressCity"},
368 {69, "System.Contact.PersonalTitle"},
369 {71, "System.Contact.MiddleName"},
370 {73, "System.Contact.Suffix"},
371 {74, "System.Contact.NickName"},
375 static struct GuidPropertySet GuidPropertySet
[] = {
376 {{0xa9bd1526, 0x6a80, 0x11d0, {0x8c, 0x9d, 0x00, 0x20, 0xaf, 0x1d, 0x74, 0x0e}},
377 "DBPROPSET_FSCIFRMWRK_EXT", "File system content index framework",
378 DBPROPSET_FSCIFRMWRK_EXT_IDS
},
379 {{0xa7ac77ed, 0xf8d7, 0x11ce, {0xa7, 0x98, 0x00, 0x20, 0xf8, 0x00, 0x80, 0x25}},
380 "DBPROPSET_QUERYEXT", "Query extension",
381 DBPROPSET_QUERYEXT_IDS
},
382 {{0xafafaca5, 0xb5d1, 0x11d0, {0x8c, 0x62, 0x00, 0xc0, 0x4f, 0xc2, 0xdb, 0x8d}},
383 "DBPROPSET_CIFRMWRKCORE_EXT", "Content index framework core",
384 DBPROPSET_CIFRMWRKCORE_EXT_IDS
},
385 {{0xAA6EE6B0, 0xE828, 0x11D0, {0xB2, 0x3E, 0x00, 0xAA, 0x00, 0x47, 0xFC, 0x01}},
386 "DBPROPSET_MSIDXS_ROWSETEXT", "???",
387 DBPROPSET_MSIDXS_ROWSETEXT_IDS
},
388 {{0xB725F130, 0x47ef, 0x101a, {0xA5, 0xF1, 0x02, 0x60, 0x8C, 0x9E, 0xEB, 0xAC}},
389 "Storage", "Storage Property Set",
391 {{0xF29F85E0, 0x4FF9, 0x1068, {0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9}},
392 "Document", "Document Property Set",
394 {{0x49691C90, 0x7E17, 0x101A, {0xA9, 0x1C, 0x08, 0x00, 0x2B, 0x2E, 0xCD, 0xA9}},
395 "Query", "Query Property Set",
397 {{0x28636AA6, 0x953D, 0x11D2, {0xB5, 0xD6, 0x00, 0xC0, 0x4F, 0xD9, 0x18, 0xD0}},
398 "ShellDetails", "Shell Details Property Set",
400 {{0x446D16B1, 0x8DAD, 0x4870, {0xA7, 0x48, 0x40, 0x2E, 0xA4, 0x3D, 0x78, 0x8C}},
401 "???", "Unspecified Property Set",
403 {{0x1E3EE840, 0xBC2B, 0x476C, {0x82, 0x37, 0x2A, 0xCD, 0x1A, 0x83, 0x9B, 0x22}},
404 "???", "Unspecified Property Set",
406 {{0x56A3372E, 0xCE9C, 0x11d2, {0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6}},
407 "Music", "Music Property Set",
409 {{0xE3E0584C, 0xB788, 0x4A5A, {0xBB, 0x20, 0x7F, 0x5A, 0x44, 0xC9, 0xAC, 0xDD}},
410 "???", "Unspecified Property Set",
412 {{0xDABD30ED, 0x0043, 0x4789, {0xA7, 0xF8, 0xD0, 0x13, 0xA4, 0x73, 0x66, 0x22}},
413 "???", "Unspecified Property Set",
415 {{0x635E9051, 0x50A5, 0x4BA2, {0xB9, 0xDB, 0x4E, 0xD0, 0x56, 0xC7, 0x72, 0x96}},
416 "???", "Unspecified Property Set",
418 {{0xD0A04F0A, 0x462A, 0x48A4, {0xBB, 0x2F, 0x37, 0x06, 0xE8, 0x8D, 0xBD, 0x7D}},
419 "???", "Unspecified Property Set",
421 {{0xDE35258C, 0xC695, 0x4CBC, {0xB9, 0x82, 0x38, 0xB0, 0xAD, 0x24, 0xCE, 0xD0}},
422 "???", "Unspecified Property Set",
424 {{0xD6942081, 0xD53B, 0x443D, {0xAD, 0x47, 0x5E, 0x05, 0x9D, 0x9C, 0xD2, 0x7A}},
425 "???", "Unspecified Property Set",
427 {{0xF7DB74B4, 0x4287, 0x4103, {0xAF, 0xBA, 0xF1, 0xB1, 0x3D, 0xCD, 0x75, 0xCF}},
428 "???", "Unspecified Property Set",
430 {{0x0B63E350, 0x9CCC, 0x11d0, {0xBC, 0xDB, 0x00, 0x80, 0x5F, 0xCC, 0xCE, 0x04}},
431 "???", "Unspecified Property Set",
433 {{0x9C1FCF74, 0x2D97, 0x41BA, {0xB4, 0xAE, 0xCB, 0x2E, 0x36, 0x61, 0xA6, 0xE4}},
434 "???", "Unspecified Property Set",
436 {{0x560C36C0, 0x503A, 0x11CF, {0xBA, 0xA1, 0x00, 0x00, 0x4C, 0x75, 0x2A, 0x9A}},
437 "DocCharacter", "Document characterization Property Set",
439 {{0x5CDA5FC8, 0x33EE, 0x4FF3, {0x90, 0x94, 0xAE, 0x7B, 0xD8, 0x86, 0x8C, 0x4D}},
440 "???", "Unspecified Property Set",
442 {{0xF23F425C, 0x71A1, 0x4FA8, {0x92, 0x2F, 0x67, 0x8E, 0xA4, 0xA6, 0x04, 0x08}},
443 "???", "Unspecified Property Set",
445 {{0xDC8F80BD, 0xAF1E, 0x4289, {0x85, 0xB6, 0x3D, 0xFC, 0x1B, 0x49, 0x39, 0x92}},
446 "???", "Unspecified Property Set",
448 {{0xD5CDD502, 0x2E9C, 0x101B, {0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE}},
449 "DocPropSet2", "Document Property Set 2",
450 DocPropSetGuid2_IDS
},
451 {{0x176DC63C, 0x2688, 0x4E89, {0x81, 0x43, 0xA3, 0x47, 0x80, 0x0F, 0x25, 0xE9}},
452 "System.Contact", "System Contact Property Set",
456 static struct GuidPropertySet
*GuidPropertySet_find_guid(const e_guid_t
*guid
)
459 for (i
=0; i
<array_length(GuidPropertySet
); i
++) {
460 if (guid_cmp(&GuidPropertySet
[i
].guid
, guid
) == 0) {
461 return &GuidPropertySet
[i
];
467 /******************************************************************************/
469 static int parse_padding(tvbuff_t
*tvb
, int offset
, int alignment
, proto_tree
*pad_tree
, const char *fmt
, ...)
471 if (offset
% alignment
) {
472 const int padding
= alignment
- (offset
% alignment
);
476 ti
= proto_tree_add_text_valist(pad_tree
, tvb
, offset
, padding
, fmt
, ap
);
479 proto_item_append_text(ti
, " (%d)", padding
);
482 DISSECTOR_ASSERT((offset
% alignment
) == 0);
486 static int parse_guid(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, e_guid_t
*guid
, const char *text
)
488 const char *guid_str
, *name
, *bytes
;
492 tvb_get_letohguid(tvb
, offset
, guid
);
493 guid_str
= guid_to_str(guid
);
494 name
= guids_get_guid_name(guid
);
496 ti
= proto_tree_add_text(tree
, tvb
, offset
, 16, "%s: %s {%s}", text
, name
? name
: "", guid_str
);
497 tr
= proto_item_add_subtree(ti
, ett_GUID
);
499 proto_tree_add_text(tr
, tvb
, offset
, 4, "time-low: 0x%08x", guid
->data1
);
501 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-mid: 0x%04x", guid
->data2
);
503 proto_tree_add_text(tr
, tvb
, offset
, 2, "time-high-and-version: 0x%04x", guid
->data3
);
505 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_hi_and_reserved: 0x%02x", guid
->data4
[0]);
507 proto_tree_add_text(tr
, tvb
, offset
, 1, "clock_seq_low: 0x%02x", guid
->data4
[1]);
509 bytes
= bytestring_to_str(&guid
->data4
[2], 6, ':');
510 proto_tree_add_text(tr
, tvb
, offset
, 6, "node: %s", bytes
);
516 static const value_string LCID_LID
[] = {
523 /*Language Code ID: http://msdn.microsoft.com/en-us/library/cc233968(v=prot.20).aspx */
524 static int parse_lcid(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, const char *text
)
531 item
= proto_tree_add_text(parent_tree
, tvb
, offset
, 4, "%s", text
);
532 tree
= proto_item_add_subtree(item
, ett_LCID
);
534 lcid
= tvb_get_letohl(tvb
, offset
);
535 langid
= val_to_str(lcid
& 0xFFFF, LCID_LID
, "0x%04x");
536 proto_tree_add_text(tree
, tvb
, offset
+2, 2, "Language ID: %s", langid
);
537 proto_item_append_text(item
, ": %s", langid
);
538 proto_tree_add_text(tree
, tvb
, offset
+1,1, "Sort ID: %u", (lcid
>> 16) & 0xf);
543 /*****************************************************************************************/
544 /* 2.2.1.1 CBaseStorageVariant */
545 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
546 struct CBaseStorageVariant
*value
, const char *text
);
548 /* 2.2.1.2 CFullPropSpec */
549 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
550 struct CFullPropSpec
*v
, const char *fmt
, ...);
552 /* 2.2.1.3 CContentRestriction */
553 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
554 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
555 const char *fmt
, ...);
557 /* 2.2.1.5 CNatLanguageRestriction */
558 static int parse_CNatLanguageRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
559 proto_tree
*pad_tree
, struct CNatLanguageRestriction
*v
,
560 const char *fmt
, ...);
562 /* 2.2.1.6 CNodeRestriction */
563 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_tree
*pad_tree
,
564 struct CNodeRestriction
*v
, const char* fmt
, ...);
566 /* 2.2.1.7 CPropertyRestriction */
567 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
568 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
569 const char *fmt
, ...);
571 /* 2.2.1.8 CReuseWhere */
572 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
573 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
574 const char *fmt
, ...);
577 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
578 proto_tree
*pad_tree _U_
,
579 const char *fmt
, ...);
581 /* 2.2.1.12 CCoercionRestriction */
582 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
583 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
584 const char *fmt
, ...);
585 /* 2.2.1.16 CRestrictionArray */
586 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
587 const char *fmt
, ...);
589 /* 2.2.1.17 CRestriction */
590 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
591 struct CRestriction
*v
, const char *fmt
, ...);
593 /* 2.2.1.18 CColumnSet */
594 static int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...);
596 /* 2.2.1.20 CCategorizationSpec */
597 static int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
598 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
599 const char *fmt
, ...);
601 /* 2.2.1.21 CCategSpec */
602 static int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
603 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
604 const char *fmt
, ...);
606 /* 2.2.1.22 CRangeCategSpec */
607 static int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
608 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
609 const char *fmt
, ...);
611 /* 2.2.1.23 RANGEBOUNDARY */
612 static int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
613 proto_tree
*pad_tree
, const char *fmt
, ...);
615 /* 2.2.1.24 CAggregSet */
616 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
617 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
618 const char *fmt
, ...);
620 /* 2.2.1.25 CAggregSpec */
621 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
622 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
623 const char *fmt
, ...);
625 /* 2.2.1.26 CSortAggregSet */
626 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
627 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
628 const char *fmt
, ...);
630 /* 2.2.1.27 CAggregSortKey */
631 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
632 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
633 const char *fmt
, ...);
635 /* 2.2.1.28 CInGroupSortAggregSets */
636 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
637 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
638 const char *fmt
, ...);
640 /* 2.2.1.29 CInGroupSortAggregSet */
641 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
642 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
643 const char *fmt
, ...);
644 /* 2.2.1.30 CDbColId */
645 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
,
646 proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
);
648 /* 2.2.1.31 CDbProp */
649 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
650 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
651 const char *fmt
, ...);
653 /* 2.2.1.32 CDbPropSet */
654 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
655 proto_tree
*pad_tree
, const char *fmt
, ...);
656 /* 2.2.1.33 CPidMapper */
657 static int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
658 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
659 const char *fmt
, ...);
661 /* 2.2.1.34 CColumnGroupArray */
662 static int parse_CColumnGroupArray(tvbuff_t
*tvb
, int offset
,
663 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
664 const char *fmt
, ...);
666 /* 2.2.1.35 CColumnGroup */
667 static int parse_CColumnGroup(tvbuff_t
*tvb
, int offset
,
668 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
669 const char *fmt
, ...);
671 /* 2.2.1.41 CRowsetProperties */
672 static int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
673 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
674 const char *fmt
, ...);
676 /* 2.2.1.43 CSortSet */
677 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
,
678 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
679 const char *fmt
, ...);
681 /* 2.2.1.44 CTableColumn */
682 static int parse_CTableColumn(tvbuff_t
*tvb
, int offset
,
683 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
684 const char *fmt
, ...);
688 2.2.1.4 CInternalPropertyRestriction
689 2.2.1.9 CScopeRestriction
690 2.2.1.11 CVectorRestriction
691 2.2.1.13 CRelDocRestriction
692 2.2.1.14 CProbRestriction
693 2.2.1.15 CFeedbackRestriction
694 2.2.1.19 CCategorizationSet
696 2.2.1.38 CRowSeekAtRatio
697 2.2.1.39 CRowSeekByBookmark
698 2.2.1.40 CRowSeekNext
700 2.2.1.45 SERIALIZEDPROPERTYVALUE
701 2.2.1.46 CCompletionCategSp
704 static int parse_CSort(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
705 proto_tree
*pad_tree _U_
,
706 const char *fmt
, ...)
708 guint32 col
, ord
, ind
;
716 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
718 tree
= proto_item_add_subtree(item
, ett_CSort
);
720 col
= tvb_get_letohl(tvb
, offset
);
721 proto_tree_add_text(tree
, tvb
, offset
, 4, "column: %u", col
);
724 ord
= tvb_get_letohl(tvb
, offset
);
725 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", ord
);
728 ind
= tvb_get_letohl(tvb
, offset
);
729 proto_tree_add_text(tree
, tvb
, offset
, 4, "individual: %u", ind
);
732 offset
= parse_lcid(tvb
, offset
, tree
, "lcid");
734 proto_item_set_end(item
, tvb
, offset
);
738 static int parse_CSortSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
739 proto_tree
*pad_tree
,
740 const char *fmt
, ...)
750 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
752 tree
= proto_item_add_subtree(item
, ett_CSortSet
);
754 count
= tvb_get_letohl(tvb
, offset
);
755 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
758 for (i
=0; i
<count
; i
++) {
759 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_sortArray[%u]", i
);
760 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "sortArray[%u]", i
);
763 proto_item_set_end(item
, tvb
, offset
);
767 static int parse_CTableColumn(tvbuff_t
*tvb
, int offset
,
768 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
769 const char *fmt
, ...)
775 struct CFullPropSpec v
;
779 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
781 tree
= proto_item_add_subtree(item
, ett_CTableColumn
);
783 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
, "PropSpec");
785 proto_tree_add_text(tree
, tvb
, offset
, 4, "vType");
788 proto_tree_add_text(tree
, tvb
, offset
, 1, "AggreagateUsed");
791 proto_tree_add_text(tree
, tvb
, offset
, 1, "AggreagateType");
794 used
= tvb_get_guint8(tvb
, offset
);
795 proto_tree_add_text(tree
, tvb
, offset
, 1, "ValueUsed");
799 offset
= parse_padding(tvb
, offset
, 2, pad_tree
, "padding_Value");
801 proto_tree_add_text(tree
, tvb
, offset
, 2, "ValueOffset");
804 proto_tree_add_text(tree
, tvb
, offset
, 2, "ValueSize");
808 used
= tvb_get_guint8(tvb
, offset
);
809 proto_tree_add_text(tree
, tvb
, offset
, 1, "StatusUsed");
813 offset
= parse_padding(tvb
, offset
, 2, pad_tree
, "padding_Status");
815 proto_tree_add_text(tree
, tvb
, offset
, 2, "StatusOffset");
819 used
= tvb_get_guint8(tvb
, offset
);
820 proto_tree_add_text(tree
, tvb
, offset
, 1, "LengthUsed");
824 offset
= parse_padding(tvb
, offset
, 2, pad_tree
, "padding_Lenght");
826 proto_tree_add_text(tree
, tvb
, offset
, 2, "LenghtOffset");
830 proto_item_set_end(item
, tvb
, offset
);
835 static int parse_CFullPropSpec(tvbuff_t
*tvb
, int offset
,
836 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
837 struct CFullPropSpec
*v
, const char *fmt
, ...)
839 static const value_string KIND
[] = {
840 {0, "PRSPEC_LPWSTR"},
841 {1, "PRSPEC_PROPID"},
845 struct GuidPropertySet
*pset
;
846 const char *id_str
, *guid_str
;
853 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
855 tree
= proto_item_add_subtree(item
, ett_CFullPropSpec
);
857 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingPropSet");
859 offset
= parse_guid(tvb
, offset
, tree
, &v
->guid
, "GUID");
860 pset
= GuidPropertySet_find_guid(&v
->guid
);
862 v
->kind
= tvb_get_letohl(tvb
, offset
);
863 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulKind: %s ", val_to_str(v
->kind
, KIND
, "(Unknown: 0x%x)"));
866 v
->u
.propid
= tvb_get_letohl(tvb
, offset
);
867 proto_tree_add_text(tree
, tvb
, offset
, 4, "propid: %u ", v
->u
.propid
);
870 if (v
->kind
== PRSPEC_LPWSTR
) {
871 int len
= 2*v
->u
.propid
;
872 v
->u
.name
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
873 proto_tree_add_text(tree
, tvb
, offset
, len
, "name: \"%s\"", v
->u
.name
);
877 id_str
= pset
? match_strval(v
->u
.propid
, pset
->id_map
) : NULL
;
880 proto_item_append_text(item
, ": %s", id_str
);
882 guid_str
= guids_get_guid_name(&v
->guid
);
884 proto_item_append_text(item
, ": \"%s\"", guid_str
);
886 guid_str
= guid_to_str(&v
->guid
);
887 proto_item_append_text(item
, ": {%s}", guid_str
);
890 if (v
->kind
== PRSPEC_LPWSTR
) {
891 proto_item_append_text(item
, " \"%s\"", v
->u
.name
);
892 } else if (v
->kind
== PRSPEC_PROPID
) {
893 proto_item_append_text(item
, " 0x%08x", v
->u
.propid
);
895 proto_item_append_text(item
, " <INVALID>");
899 proto_item_set_end(item
, tvb
, offset
);
905 static const value_string PR_VALS
[] = {
913 {PRAllBits
, "PRAllBits"},
914 {PRSomeBits
, "PRSomeBits"},
920 static int parse_CPropertyRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
921 proto_tree
*pad_tree
, struct CPropertyRestriction
*v
,
922 const char *fmt
, ...)
930 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
933 tree
= proto_item_add_subtree(item
, ett_CPropertyRestriction
);
935 v
->relop
= tvb_get_letohl(tvb
, offset
);
936 str
= val_to_str(v
->relop
, PR_VALS
, "0x%04x");
937 proto_tree_add_text(tree
, tvb
, offset
, 4, "relop: %s (0x%04x)",
938 str
[0]=='\0' ? "" : str
, v
->relop
);
939 proto_item_append_text(item
, " Op: %s", str
);
942 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
944 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &v
->prval
, "prval");
946 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
948 v
->lcid
= tvb_get_letohl(tvb
, offset
);
949 offset
= parse_lcid(tvb
, offset
, tree
, "lcid");
951 proto_item_set_end(item
, tvb
, offset
);
956 static int parse_CCoercionRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
957 proto_tree
*pad_tree
, struct CCoercionRestriction
*v
,
958 const char *fmt
, ...)
965 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
968 tree
= proto_item_add_subtree(item
, ett_CCoercionRestriction
);
970 v
->value
= tvb_get_letohl(tvb
, offset
);
971 proto_tree_add_text(tree
, tvb
, offset
, 4, "value: %g", (double)v
->value
);
974 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &v
->child
, "child");
976 proto_item_set_end(item
, tvb
, offset
);
980 static int parse_CContentRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
981 proto_tree
*pad_tree
, struct CContentRestriction
*v
,
982 const char *fmt
, ...)
992 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
995 tree
= proto_item_add_subtree(item
, ett_CContentRestriction
);
997 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
999 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding1");
1001 cc
= tvb_get_letohl(tvb
, offset
);
1002 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
1005 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
1006 str
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
1007 v
->phrase
= se_strdup(str
);
1008 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
1011 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "Padding2");
1013 v
->lcid
= tvb_get_letohl(tvb
, offset
);
1014 offset
= parse_lcid(tvb
, offset
, tree
, "lcid");
1016 v
->method
= tvb_get_letohl(tvb
, offset
);
1017 proto_tree_add_text(tree
, tvb
, offset
, 4, "method: 0x%08x", v
->method
);
1020 proto_item_set_end(item
, tvb
, offset
);
1024 int parse_CNatLanguageRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1025 proto_tree
*pad_tree
, struct CNatLanguageRestriction
*v
,
1026 const char *fmt
, ...)
1036 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1039 tree
= proto_item_add_subtree(item
, ett_CNatLanguageRestriction
);
1041 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
->property
, "Property");
1043 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_cc");
1045 cc
= tvb_get_letohl(tvb
, offset
);
1046 proto_tree_add_text(tree
, tvb
, offset
, 4, "cc: %u", cc
);
1049 // str = tvb_get_ephemeral_string_enc(tvb, offset, 2*cc, ENC_UTF_16);
1050 str
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, 2*cc
, ENC_LITTLE_ENDIAN
);
1051 v
->phrase
= se_strdup(str
);
1052 proto_tree_add_text(tree
, tvb
, offset
, 2*cc
, "phrase: %s", str
);
1055 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_lcid");
1057 v
->lcid
= tvb_get_letohl(tvb
, offset
);
1058 offset
= parse_lcid(tvb
, offset
, tree
, "lcid");
1060 proto_item_set_end(item
, tvb
, offset
);
1065 static int parse_CReuseWhere(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1066 proto_tree
*pad_tree _U_
, struct CReuseWhere
*v
,
1067 const char *fmt
, ...)
1074 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1077 v
->whereId
= tvb_get_letohl(tvb
, offset
);
1080 proto_item_append_text(item
, " Id: %u", v
->whereId
);
1082 proto_item_set_end(item
, tvb
, offset
);
1086 static value_string RT_VALS
[] = {
1091 {RTContent
, "RTContent"},
1092 {RTProperty
, "RTProperty"},
1093 {RTProximity
, "RTProximity"},
1095 {RTNatLanguage
, "RTNatLanguage"},
1096 {RTScope
, "RTScope"},
1097 {RTCoerce_Add
, "RTCoerce_Add"},
1098 {RTCoerce_Multiply
, "RTCoerce_Multiply"},
1099 {RTCoerce_Absolute
, "RTCoerce_Absolute"},
1101 {RTFeedback
, "RTFeedback"},
1102 {RTReldoc
, "RTReldoc"},
1103 {RTReuseWhere
, "RTReuseWhere"},
1104 {RTInternalProp
, "RTInternalProp"},
1105 {RTPhrase
, "RTInternalProp"},
1108 static int parse_CRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1109 struct CRestriction
*v
, const char *fmt
, ...)
1117 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1120 tree
= proto_item_add_subtree(item
, ett_CRestriction
);
1123 v
->ulType
= tvb_get_letohl(tvb
, offset
);
1124 str
= val_to_str(v
->ulType
, RT_VALS
, "0x%.8x");
1125 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType: %s (0x%.8x)",
1126 str
[0] == '0' ? "" : str
, v
->ulType
);
1127 proto_item_append_text(item
, " Type: %s", str
);
1130 v
->Weight
= tvb_get_letohl(tvb
, offset
);
1131 proto_tree_add_text(tree
, tvb
, offset
, 4, "Weight: %u", v
->ulType
);
1142 v
->u
.RTAnd
= ep_alloc(sizeof(struct CNodeRestriction
)); //XXX
1143 offset
= parse_CNodeRestriction(tvb
, offset
, tree
, pad_tree
, v
->u
.RTAnd
, "CNodeRestriction");
1148 v
->u
.RTNot
= ep_alloc(sizeof(struct CRestriction
)); //XXX
1149 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
,
1150 v
->u
.RTNot
, "CRestriction");
1155 v
->u
.RTProperty
= ep_alloc(sizeof(struct CPropertyRestriction
)); //XXX
1156 offset
= parse_CPropertyRestriction(tvb
, offset
, tree
, pad_tree
,
1157 v
->u
.RTProperty
, "CPropertyRestriction");
1161 case RTCoerce_Multiply
:
1162 case RTCoerce_Absolute
:
1164 v
->u
.RTCoerce_Add
= ep_alloc(sizeof(struct CCoercionRestriction
)); //XXX
1165 offset
= parse_CCoercionRestriction(tvb
, offset
, tree
, pad_tree
,
1166 v
->u
.RTCoerce_Add
, "CCoercionRestriction");
1170 v
->u
.RTContent
= ep_alloc(sizeof(struct CContentRestriction
)); //XXX
1171 offset
= parse_CContentRestriction(tvb
, offset
, tree
, pad_tree
,
1172 v
->u
.RTContent
, "CContentRestriction");
1175 case RTReuseWhere
: {
1176 v
->u
.RTReuseWhere
= ep_alloc(sizeof(struct CReuseWhere
)); //XXX
1177 offset
= parse_CReuseWhere(tvb
, offset
, tree
, pad_tree
,
1178 v
->u
.RTReuseWhere
, "CReuseWhere");
1181 case RTNatLanguage
: {
1182 v
->u
.RTNatLanguage
= ep_alloc(sizeof(struct CNatLanguageRestriction
)); //XXX
1183 offset
= parse_CNatLanguageRestriction(tvb
, offset
, tree
, pad_tree
,
1184 v
->u
.RTNatLanguage
, "CNatLanguageRestriction");
1188 fprintf(stderr
, "CRestriciont 0x%08x not Supported\n", v
->ulType
);
1189 proto_item_append_text(item
, " Not supported!");
1192 proto_item_set_end(item
, tvb
, offset
);
1196 static int parse_CRestrictionArray(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1197 const char *fmt
, ...)
1199 guint8 present
, count
;
1206 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1208 tree
= proto_item_add_subtree(item
, ett_CRestrictionArray
);
1210 pad_tree
= tree
; //XXX
1212 count
= tvb_get_guint8(tvb
, offset
);
1213 proto_tree_add_text(tree
, tvb
, offset
, 1, "count: %u", count
);
1216 present
= tvb_get_guint8(tvb
, offset
);
1217 proto_tree_add_text(tree
, tvb
, offset
, 1, "present: %u", present
);
1222 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCRestrictionPresent");
1224 for (i
=0; i
<count
; i
++) {
1225 struct CRestriction r
;
1226 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "Restriction[%d]", i
);
1229 proto_item_set_end(item
, tvb
, offset
);
1233 static int parse_CNodeRestriction(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1234 proto_tree
*pad_tree
, struct CNodeRestriction
*v
,
1235 const char *fmt
, ...)
1243 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1245 tree
= proto_item_add_subtree(item
, ett_CNodeRestriction
);
1247 v
->cNode
= tvb_get_letohl(tvb
, offset
);
1248 proto_tree_add_text(tree
, tvb
, offset
, 4, "cNode: %u", v
->cNode
);
1251 for (i
=0; i
<v
->cNode
; i
++) {
1252 struct CRestriction r
;
1254 // offset = parse_padding(tvb, offset, 4, tree, "padding_paNode[%u]", i); /*at begin or end of loop ????*/
1255 offset
= parse_CRestriction(tvb
, offset
, tree
, pad_tree
, &r
, "paNode[%u]", i
);
1256 offset
= parse_padding(tvb
, offset
, 4, tree
, "padding_paNode[%u]", i
); /*at begin or end of loop ????*/
1258 // offset = parse_padding(tvb, offset, 4, pad_tree, "paNode[%u]", i); /*at begin or end of loop ????*/
1261 proto_item_set_end(item
, tvb
, offset
);
1266 /*****************************************************************************************/
1268 static int vvalue_tvb_get0(tvbuff_t
*tvb _U_
, int offset _U_
, void *val _U_
)
1273 static int vvalue_tvb_get1(tvbuff_t
*tvb
, int offset
, void *val
)
1275 guint8
*ui1
= (guint8
*)val
;
1276 *ui1
= tvb_get_guint8(tvb
, offset
);
1280 static int vvalue_tvb_get2(tvbuff_t
*tvb
, int offset
, void *val
)
1282 guint16
*ui2
= (guint16
*)val
;
1283 *ui2
= tvb_get_letohs(tvb
, offset
);
1287 static int vvalue_tvb_get4(tvbuff_t
*tvb
, int offset
, void *val
)
1289 guint32
*ui4
= (guint32
*)val
;
1290 *ui4
= tvb_get_letohl(tvb
, offset
);
1294 static int vvalue_tvb_get8(tvbuff_t
*tvb
, int offset
, void *val
)
1296 guint64
*ui8
= (guint64
*)val
;
1297 *ui8
= tvb_get_letoh64(tvb
, offset
);
1301 static int vvalue_tvb_blob(tvbuff_t
*tvb
, int offset
, void *val
)
1303 struct data_blob
*blob
= (struct data_blob
*)val
;
1304 guint32 len
= tvb_get_letohl(tvb
, offset
);
1305 const guint8
*data
= tvb_get_ptr(tvb
, offset
+ 4, len
);
1308 blob
->data
= se_memdup(data
, len
);
1313 static int vvalue_tvb_bstr(tvbuff_t
*tvb
, int offset
, void *val
)
1315 struct data_str
*str
= (struct data_str
*)val
;
1316 guint32 len
= tvb_get_letohl(tvb
, offset
);
1317 const void *ptr
= tvb_get_ptr(tvb
, offset
+ 4, len
);
1319 //XXX this might be UTF-16
1321 str
->str
= se_strndup(ptr
, len
);
1325 static int vvalue_tvb_lpstr(tvbuff_t
*tvb
, int offset
, void *val
)
1327 struct data_str
*str
= (struct data_str
*)val
;
1330 str
->len
= tvb_get_letohl(tvb
, offset
);
1331 str
->str
= tvb_get_stringz(wmem_packet_scope(), tvb
, offset
+ 4, &len
);
1332 /* XXX test str->len == len */
1336 static int vvalue_tvb_lpwstr(tvbuff_t
*tvb
, int offset
, void *val
)
1338 struct data_str
*str
= (struct data_str
*)val
;
1342 str
->len
= tvb_get_letohl(tvb
, offset
);
1344 ptr
= tvb_get_unicode_stringz(wmem_packet_scope(), tvb
, offset
+ 4, &len
, ENC_LITTLE_ENDIAN
);
1345 str
->str
= se_strdup (ptr
);
1350 static int vvalue_tvb_vector_internal(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
, int num
)
1352 const int offset_in
= offset
;
1353 const gboolean varsize
= (type
->size
== -1);
1354 const int elsize
= varsize
? (int)sizeof(struct data_blob
) : type
->size
;
1355 guint8
*data
= se_alloc(elsize
* num
);
1359 val
->u
.vt_ui1
= data
;
1360 DISSECTOR_ASSERT((void*)&val
->u
== ((void*)&val
->u
.vt_ui1
));
1362 for (i
=0; i
<num
; i
++) {
1363 len
= type
->tvb_get(tvb
, offset
, data
);
1366 if (varsize
&& (offset
% 4) ) { /* at begin or end of loop ??? */
1367 int padding
= 4 - (offset
% 4);
1371 return offset
- offset_in
;
1374 static int vvalue_tvb_vector(tvbuff_t
*tvb
, int offset
, struct vt_vector
*val
, struct vtype
*type
)
1376 const int num
= tvb_get_letohl(tvb
, offset
);
1377 return 4 + vvalue_tvb_vector_internal(tvb
, offset
+4, val
, type
, num
);
1380 static void vvalue_strbuf_append_null(emem_strbuf_t
*strbuf _U_
, void *ptr _U_
)
1383 static void vvalue_strbuf_append_i1(emem_strbuf_t
*strbuf
, void *ptr
)
1385 gint8 i1
= *(gint8
*)ptr
;
1386 ep_strbuf_append_printf(strbuf
, "%d", (int)i1
);
1389 static void vvalue_strbuf_append_i2(emem_strbuf_t
*strbuf
, void *ptr
)
1391 gint16 i2
= *(gint16
*)ptr
;
1392 ep_strbuf_append_printf(strbuf
, "%d", (int)i2
);
1395 static void vvalue_strbuf_append_i4(emem_strbuf_t
*strbuf
, void *ptr
)
1397 gint32 i4
= *(gint32
*)ptr
;
1398 ep_strbuf_append_printf(strbuf
, "%d", i4
);
1401 static void vvalue_strbuf_append_i8(emem_strbuf_t
*strbuf
, void *ptr
)
1403 gint64 i8
= *(gint64
*)ptr
;
1404 ep_strbuf_append_printf(strbuf
, "%ld", i8
);
1407 static void vvalue_strbuf_append_ui1(emem_strbuf_t
*strbuf
, void *ptr
)
1409 guint8 ui1
= *(guint8
*)ptr
;
1410 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui1
);
1413 static void vvalue_strbuf_append_ui2(emem_strbuf_t
*strbuf
, void *ptr
)
1415 guint16 ui2
= *(guint16
*)ptr
;
1416 ep_strbuf_append_printf(strbuf
, "%u", (unsigned)ui2
);
1419 static void vvalue_strbuf_append_ui4(emem_strbuf_t
*strbuf
, void *ptr
)
1421 guint32 ui4
= *(guint32
*)ptr
;
1422 ep_strbuf_append_printf(strbuf
, "%d", ui4
);
1425 static void vvalue_strbuf_append_ui8(emem_strbuf_t
*strbuf
, void *ptr
)
1427 guint64 ui8
= *(guint64
*)ptr
;
1428 ep_strbuf_append_printf(strbuf
, "%lu", ui8
);
1431 static void vvalue_strbuf_append_r4(emem_strbuf_t
*strbuf
, void *ptr
)
1433 float r4
= *(float*)ptr
;
1434 ep_strbuf_append_printf(strbuf
, "%g", (double)r4
);
1437 static void vvalue_strbuf_append_r8(emem_strbuf_t
*strbuf
, void *ptr
)
1439 double r8
= *(double*)ptr
;
1440 ep_strbuf_append_printf(strbuf
, "%g", r8
);
1443 static void vvalue_strbuf_append_str(emem_strbuf_t
*strbuf
, void *ptr
)
1445 struct data_str
*str
= (struct data_str
*)ptr
;
1446 ep_strbuf_append_printf(strbuf
, "\"%s\"", str
->str
);
1449 static void vvalue_strbuf_append_blob(emem_strbuf_t
*strbuf
, void *ptr
)
1451 struct data_blob
*blob
= (struct data_blob
*)ptr
;
1452 ep_strbuf_append_printf(strbuf
, "size: %d", (int)blob
->size
);
1455 static void vvalue_strbuf_append_bool(emem_strbuf_t
*strbuf
, void *ptr
)
1457 guint16 val
= *(guint
*)ptr
;
1460 ep_strbuf_append(strbuf
, "False");
1463 ep_strbuf_append(strbuf
, "True");
1466 ep_strbuf_append_printf(strbuf
, "Invalid (0x%4x)", val
);
1470 static void vvalue_strbuf_append_vector(emem_strbuf_t
*strbuf
, struct vt_vector val
, struct vtype
*type
)
1472 const int elsize
= (type
->size
== -1) ? (int)sizeof(struct data_blob
) : type
->size
;
1474 guint8
*data
= val
.u
.vt_ui1
;
1475 ep_strbuf_append_c(strbuf
, '[');
1476 for (i
=0; i
<val
.len
; i
++) {
1478 ep_strbuf_append_c(strbuf
, ',');
1480 type
->strbuf_append(strbuf
, data
);
1483 ep_strbuf_append_c(strbuf
, ']');
1487 static struct vtype VT_TYPE
[] = {
1488 {VT_EMPTY
, "VT_EMPTY", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
1489 {VT_NULL
, "VT_NULL", 0, vvalue_tvb_get0
, vvalue_strbuf_append_null
},
1490 {VT_I2
, "VT_I2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_i2
},
1491 {VT_I4
, "VT_I4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
1492 {VT_R4
, "VT_R4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_r4
},
1493 {VT_R8
, "VT_R8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
1494 {VT_CY
, "VT_CY", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1495 {VT_DATE
, "VT_DATE", 8, vvalue_tvb_get8
, vvalue_strbuf_append_r8
},
1496 // {VT_BSTR, "VT_BSTR", -1, vvalue_tvb_bstr, vvalue_strbuf_append_str},
1497 {VT_BSTR
, "VT_BSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
1498 {VT_ERROR
, "VT_ERROR", 8, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1499 {VT_BOOL
, "VT_BOOL", 2, vvalue_tvb_get2
, vvalue_strbuf_append_bool
},
1500 {VT_VARIANT
, "VT_VARIANT", -1, NULL
, NULL
},
1501 {VT_DECIMAL
, "VT_DECIMAL", 16, NULL
, NULL
},
1502 {VT_I1
, "VT_I1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_i1
},
1503 {VT_UI1
, "VT_UI1", 1, vvalue_tvb_get1
, vvalue_strbuf_append_ui1
},
1504 {VT_UI2
, "VT_UI2", 2, vvalue_tvb_get2
, vvalue_strbuf_append_ui2
},
1505 {VT_UI4
, "VT_UI4", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1506 {VT_I8
, "VT_I8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1507 {VT_UI8
, "VT_UI8", 8, vvalue_tvb_get8
, vvalue_strbuf_append_ui8
},
1508 {VT_INT
, "VT_INT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_i4
},
1509 {VT_UINT
, "VT_UINT", 4, vvalue_tvb_get4
, vvalue_strbuf_append_ui4
},
1510 {VT_LPSTR
, "VT_LPSTR", -1, vvalue_tvb_lpstr
, vvalue_strbuf_append_str
},
1511 {VT_LPWSTR
, "VT_LPWSTR", -1, vvalue_tvb_lpwstr
, vvalue_strbuf_append_str
},
1512 {VT_COMPRESSED_LPWSTR
, "VT_COMPRESSED_LPWSTR", -1, NULL
, vvalue_strbuf_append_str
},
1513 {VT_FILETIME
, "VT_FILETIME", 8, vvalue_tvb_get8
, vvalue_strbuf_append_i8
},
1514 {VT_BLOB
, "VT_BLOB", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
1515 {VT_BLOB_OBJECT
, "VT_BLOB_OBJECT", -1, vvalue_tvb_blob
, vvalue_strbuf_append_blob
},
1516 {VT_CLSID
, "VT_CLSID", 16, NULL
, NULL
},
1519 static struct vtype
*vType_get_type(enum vType t
) {
1522 for (i
=0; i
<array_length(VT_TYPE
); i
++) {
1523 if (t
== VT_TYPE
[i
].tag
) {
1530 static char *str_CBaseStorageVariant(struct CBaseStorageVariant
*value
, gboolean print_type
)
1533 emem_strbuf_t
*strbuf
= ep_strbuf_new(NULL
);
1534 if (value
== NULL
) {
1538 if (value
->type
== NULL
) {
1543 ep_strbuf_append(strbuf
, value
->type
->str
);
1545 if (value
->vType
& 0xFF00) {
1546 ep_strbuf_append_printf(strbuf
, "[%d]", value
->vValue
.vt_vector
.len
);
1548 ep_strbuf_append(strbuf
, ": ");
1551 switch (value
->vType
& 0xFF00) {
1553 value
->type
->strbuf_append(strbuf
, &value
->vValue
);
1556 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_array
.vData
, value
->type
);
1559 vvalue_strbuf_append_vector(strbuf
, value
->vValue
.vt_vector
, value
->type
);
1562 ep_strbuf_append(strbuf
, "Invalid");
1568 static int parse_CBaseStorageVariant(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
1569 struct CBaseStorageVariant
*value
, const char *text
)
1572 proto_item
*ti
, *ti_type
, *ti_val
;
1573 proto_tree
*tree
, *tr
;
1574 enum vType baseType
, highType
;
1576 ZERO_STRUCT(*value
);
1578 ti
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1579 tree
= proto_item_add_subtree(ti
, ett_CBaseStorageVariant
);
1581 value
->vType
= tvb_get_letohs(tvb
, offset
);
1582 value
->type
= vType_get_type(value
->vType
);
1584 ti_type
= proto_tree_add_text(tree
, tvb
, offset
, 2, "vType: %s", value
->type
->str
);
1587 value
->vData1
= tvb_get_guint8(tvb
, offset
);
1588 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData1: %d", value
->vData1
);
1591 value
->vData2
= tvb_get_guint8(tvb
, offset
);
1592 proto_tree_add_text(tree
, tvb
, offset
, 1, "vData2: %d", value
->vData2
);
1595 baseType
= value
->vType
& 0x00FF;
1596 highType
= value
->vType
& 0xFF00;
1598 if (value
->type
== NULL
) {
1602 ti_val
= proto_tree_add_text(tree
, tvb
, offset
, 0, "vValue");
1606 len
= value
->type
->tvb_get(tvb
, offset
, &value
->vValue
.vt_single
);
1610 proto_item_append_text(ti_type
, "|VT_VECTOR");
1611 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Vector
);
1613 len
= vvalue_tvb_vector(tvb
, offset
, &value
->vValue
.vt_vector
, value
->type
);
1614 proto_tree_add_text(tr
, tvb
, offset
, 4, "num: %d", value
->vValue
.vt_vector
.len
);
1618 guint16 cDims
, fFeatures
;
1619 guint32 cbElements
, cElements
, lLbound
;
1622 proto_item_append_text(ti_type
, "|VT_ARRAY");
1623 tr
= proto_item_add_subtree(ti_val
, ett_CBaseStorageVariant_Array
);
1625 cDims
= tvb_get_letohs(tvb
, offset
);
1626 proto_tree_add_text(tr
, tvb
, offset
, 2, "cDims: %d", cDims
);
1629 fFeatures
= tvb_get_letohs(tvb
, offset
);
1630 proto_tree_add_text(tr
, tvb
, offset
, 2, "fFeaturess: %d", fFeatures
);
1633 cbElements
= tvb_get_letohl(tvb
, offset
);
1634 proto_tree_add_text(tr
, tvb
, offset
, 4, "cbElements: %d", cbElements
);
1636 for (i
=0; i
<cDims
; i
++) {
1637 cElements
= tvb_get_letohl(tvb
, offset
);
1638 lLbound
= tvb_get_letohl(tvb
, offset
+ 4);
1639 proto_tree_add_text(tr
, tvb
, offset
, 8, "Rgsabound[%d]: (%d:%d)", i
, cElements
, lLbound
);
1644 len
= vvalue_tvb_vector_internal(tvb
, offset
, &value
->vValue
.vt_array
.vData
, value
->type
, num
);
1649 proto_item_append_text(ti_type
, "|0x%x", highType
);
1651 proto_item_set_end(ti
, tvb
, offset
);
1652 proto_item_set_end(ti_val
, tvb
, offset
);
1654 proto_item_append_text(ti_val
, " %s", str_CBaseStorageVariant(value
, false));
1655 proto_item_append_text(ti
, " %s", str_CBaseStorageVariant(value
, true));
1660 proto_item_append_text(ti
, ": sorry, vType %02x not handled yet!", (unsigned)value
->vType
);
1666 DBKIND_GUID_NAME
= 0,
1667 DBKIND_GUID_PROPID
= 1
1670 static int parse_CDbColId(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
, proto_tree
*pad_tree
, const char *text
)
1672 guint32 eKind
, ulId
;
1674 static const char *KIND
[] = {"DBKIND_GUID_NAME", "DBKIND_GUID_PROPID"};
1676 proto_item
*tree_item
= proto_tree_add_text(parent_tree
, tvb
, offset
, 0, "%s", text
);
1677 proto_tree
*tree
= proto_item_add_subtree(tree_item
, ett_CDbColId
);
1679 eKind
= tvb_get_letohl(tvb
, offset
);
1680 proto_tree_add_text(tree
, tvb
, offset
, 4, "eKind: %s (%u)", eKind
< 2 ? KIND
[eKind
] : "???", eKind
);
1683 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingGuidAlign");
1685 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "GUID");
1687 ulId
= tvb_get_letohl(tvb
, offset
);
1688 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulId: %d", ulId
);
1691 if (eKind
== DBKIND_GUID_NAME
) {
1693 int len
= ulId
; //*2 ???
1694 name
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, len
, ENC_LITTLE_ENDIAN
);
1695 proto_tree_add_text(tree
, tvb
, offset
, len
, "vString: \"%s\"", name
);
1696 proto_item_append_text(tree_item
, " \"%s\"", name
);
1698 } else if (eKind
== DBKIND_GUID_PROPID
) {
1699 proto_item_append_text(tree_item
, " %08x", ulId
);
1701 proto_item_append_text(tree_item
, "<INVALID>");
1704 proto_item_set_end(tree_item
, tvb
, offset
);
1709 static int parse_CDbProp(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1710 proto_tree
*pad_tree
, struct GuidPropertySet
*propset
,
1711 const char *fmt
, ...)
1713 static const value_string EMPTY_VS
[] = {{0, NULL
}};
1714 const value_string
*vs
= (propset
&& propset
->id_map
) ? propset
->id_map
: EMPTY_VS
;
1715 guint32 id
, opt
, status
;
1716 struct CBaseStorageVariant value
;
1723 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1726 tree
= proto_item_add_subtree(item
, ett_CDbProp
);
1728 id
= tvb_get_letohl(tvb
, offset
);
1729 str
= val_to_str(id
, vs
, "0x%08x");
1730 proto_tree_add_text(tree
, tvb
, offset
, 4, "Id: %s (0x%08x)", str
[0] == '0' ? "" : str
, id
);
1732 proto_item_append_text(item
, " Id: %s", str
);
1734 opt
= tvb_get_letohl(tvb
, offset
);
1735 proto_tree_add_text(tree
, tvb
, offset
, 4, "Options: %08x", opt
);
1738 status
= tvb_get_letohl(tvb
, offset
);
1739 proto_tree_add_text(tree
, tvb
, offset
, 4, "Status: %08x", status
);
1742 offset
= parse_CDbColId(tvb
, offset
, tree
, pad_tree
, "colid");
1744 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &value
, "vValue");
1746 str
= str_CBaseStorageVariant(&value
, true);
1747 proto_item_append_text(item
, " %s", str
);
1748 proto_item_set_end(item
, tvb
, offset
);
1753 static int parse_CDbPropSet(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1754 proto_tree
*pad_tree
, const char *fmt
, ...)
1758 struct GuidPropertySet
*pset
;
1764 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1767 tree
= proto_item_add_subtree(item
, ett_CDbPropSet
);
1769 offset
= parse_guid(tvb
, offset
, tree
, &guid
, "guidPropertySet");
1771 pset
= GuidPropertySet_find_guid(&guid
);
1774 proto_item_append_text(item
, " \"%s\" (%s)", pset
->desc
, pset
->def
);
1776 const char *guid_str
= guid_to_str(&guid
);
1777 proto_item_append_text(item
, " {%s}", guid_str
);
1780 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "guidPropertySet");
1782 num
= tvb_get_letohl(tvb
, offset
);
1783 proto_tree_add_text(tree
, tvb
, offset
, 4, "cProperties: %d", num
);
1785 proto_item_append_text(item
, " Num: %d", num
);
1787 for (i
= 0; i
<num
; i
++) {
1788 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "aProp[%d]", i
);
1789 offset
= parse_CDbProp(tvb
, offset
, tree
, pad_tree
, pset
, "aProp[%d]", i
);
1792 proto_item_set_end(item
, tvb
, offset
);
1796 static int parse_PropertySetArray(tvbuff_t
*tvb
, int offset
, int size_offset
,
1797 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1798 const char *fmt
, ...)
1800 const int offset_in
= offset
;
1808 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1811 tree
= proto_item_add_subtree(item
, ett_CDbPropSet_Array
);
1813 size
= tvb_get_letohl(tvb
, size_offset
);
1814 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_Blob1
, tvb
,
1815 size_offset
, 4, ENC_LITTLE_ENDIAN
);
1817 num
= tvb_get_letohl(tvb
, offset
);
1818 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_PropSets_num
, tvb
,
1819 offset
, 4, ENC_LITTLE_ENDIAN
);
1822 for (i
= 0; i
< (int)num
; i
++) {
1823 offset
= parse_CDbPropSet(tvb
, offset
, tree
, pad_tree
, "PropertySet[%d]", i
);
1826 proto_item_set_end(item
, tvb
, offset
);
1827 DISSECTOR_ASSERT(offset
- offset_in
== (int)size
);
1831 int parse_CColumnSet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const char *fmt
, ...)
1833 guint32 count
, v
, i
;
1839 item
= proto_tree_add_text_valist(tree
, tvb
, offset
, 0, fmt
, ap
);
1842 count
= tvb_get_letohl(tvb
, offset
);
1845 proto_item_append_text(item
, " Count %u [", count
);
1846 for (i
=0; i
<count
; i
++) {
1847 v
= tvb_get_letohl(tvb
, offset
);
1850 proto_item_append_text(item
, ",%u", v
);
1852 proto_item_append_text(item
, "%u", v
);
1855 proto_item_append_text(item
, "]");
1859 /* 2.2.1.23 RANGEBOUNDARY */
1860 int parse_RANGEBOUNDARY(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1861 proto_tree
*pad_tree
, const char *fmt
, ...)
1864 guint8 labelPresent
;
1867 struct CBaseStorageVariant prval
;
1871 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1872 tree
= proto_item_add_subtree(item
, ett_RANGEBOUNDARY
);
1875 ulType
= tvb_get_letohl(tvb
, offset
);
1876 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulType 0x%08x", ulType
);
1877 proto_item_append_text(item
, ": Type 0x%08x", ulType
);
1881 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &prval
, "prVal");
1883 labelPresent
= tvb_get_guint8(tvb
, offset
);
1884 proto_tree_add_text(tree
, tvb
, offset
, 1, "labelPresent: %s", labelPresent
? "True" : "False");
1890 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingLabelPresent");
1892 ccLabel
= tvb_get_letohl(tvb
, offset
);
1893 proto_tree_add_text(tree
, tvb
, offset
, 4, "ccLabel: %u", ccLabel
);
1896 label
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, 2*ccLabel
, ENC_LITTLE_ENDIAN
);
1897 proto_tree_add_text(tree
, tvb
, offset
, 2*ccLabel
, "Label: \"%s\"", label
);
1898 proto_item_append_text(item
, " Label: \"%s\"", label
);
1899 offset
+= 2*ccLabel
;
1902 proto_item_append_text(item
, " Val: %s", str_CBaseStorageVariant(&prval
, true));
1904 proto_item_set_end(item
, tvb
, offset
);
1909 /* 2.2.1.22 CRangeCategSpec */
1910 int parse_CRangeCategSpec(tvbuff_t
*tvb
, int offset
,
1911 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1912 const char *fmt
, ...)
1921 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1922 tree
= proto_item_add_subtree(item
, ett_CRangeCategSpec
);
1925 offset
= parse_lcid(tvb
, offset
, tree
, "lcid");
1927 cRange
= tvb_get_letohl(tvb
, offset
);
1928 proto_tree_add_text(tree
, tvb
, offset
, 4, "cRange 0x%08x", cRange
);
1931 for (i
=0; i
<cRange
; i
++) {
1932 offset
= parse_RANGEBOUNDARY(tvb
, offset
, tree
, pad_tree
, "aRangeBegin[%u]", i
);
1936 proto_item_set_end(item
, tvb
, offset
);
1940 /* 2.2.1.21 CCategSpec */
1941 int parse_CCategSpec(tvbuff_t
*tvb
, int offset
,
1942 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1943 const char *fmt
, ...)
1952 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1953 tree
= proto_item_add_subtree(item
, ett_CCategSpec
);
1956 type
= tvb_get_letohl(tvb
, offset
);
1957 proto_tree_add_text(tree
, tvb
, offset
, 4, "Type 0x%08x", type
);
1958 proto_item_append_text(item
, " Type %u", type
);
1961 offset
= parse_CSort(tvb
, offset
, tree
, pad_tree
, "CSort");
1963 offset
= parse_CRangeCategSpec(tvb
, offset
, tree
, pad_tree
, "CRangeCategSpec");
1965 proto_item_set_end(item
, tvb
, offset
);
1969 /* 2.2.1.25 CAggregSpec */
1970 static int parse_CAggregSpec(tvbuff_t
*tvb
, int offset
,
1971 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
1972 const char *fmt
, ...)
1978 guint32 ccAlias
, idColumn
, ulMaxNumToReturn
, idRepresentative
;
1982 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
1983 tree
= proto_item_add_subtree(item
, ett_CAggregSpec
);
1986 type
= tvb_get_guint8(tvb
, offset
);
1987 proto_tree_add_text(tree
, tvb
, offset
, 1, "type: %u", type
);
1988 proto_item_append_text(item
, "type: %u", type
);
1991 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding");
1993 ccAlias
= tvb_get_letohl(tvb
, offset
);
1994 proto_tree_add_text(tree
, tvb
, offset
, 1, "ccAlias: %u", ccAlias
);
1997 alias
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, 2*ccAlias
, ENC_LITTLE_ENDIAN
);
1998 proto_tree_add_text(tree
, tvb
, offset
, 2*ccAlias
, "Alias: %s", alias
);
1999 offset
+= 2*ccAlias
;
2001 idColumn
= tvb_get_letohl(tvb
, offset
);
2002 proto_tree_add_text(tree
, tvb
, offset
, 1, "idColumn: %u", idColumn
);
2005 ulMaxNumToReturn, idRepresentative;
2007 fprintf(stderr
, "WARNING, dont know if optional members are present!\n ");
2009 proto_item_set_end(item
, tvb
, offset
);
2013 /* 2.2.1.24 CAggregSet */
2014 static int parse_CAggregSet(tvbuff_t
*tvb
, int offset
,
2015 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2016 const char *fmt
, ...)
2025 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2026 tree
= proto_item_add_subtree(item
, ett_CAggregSet
);
2029 cCount
= tvb_get_letohl(tvb
, offset
);
2030 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
2033 for (i
=0; i
<cCount
; i
++) {
2034 /* 2.2.1.25 CAggregSpec */
2035 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "AggregSpecs[%u]", i
);
2038 proto_item_set_end(item
, tvb
, offset
);
2042 /* 2.2.1.27 CAggregSortKey */
2043 static int parse_CAggregSortKey(tvbuff_t
*tvb
, int offset
,
2044 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2045 const char *fmt
, ...)
2054 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2055 tree
= proto_item_add_subtree(item
, ett_CAggregSortKey
);
2058 order
= tvb_get_letohl(tvb
, offset
);
2059 proto_tree_add_text(tree
, tvb
, offset
, 4, "order: %u", order
);
2062 offset
= parse_CAggregSpec(tvb
, offset
, tree
, pad_tree
, "ColumnSpec");
2064 proto_item_set_end(item
, tvb
, offset
);
2069 /* 2.2.1.26 CSortAggregSet */
2070 static int parse_CSortAggregSet(tvbuff_t
*tvb
, int offset
,
2071 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2072 const char *fmt
, ...)
2081 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2082 tree
= proto_item_add_subtree(item
, ett_CSortAggregSet
);
2085 cCount
= tvb_get_letohl(tvb
, offset
);
2086 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
2089 for (i
=0; i
<cCount
; i
++) {
2090 /* 2.2.1.27 CAggregSortKey */
2091 offset
= parse_CAggregSortKey(tvb
, offset
, tree
, pad_tree
, "SortKeys[%u]", i
);
2094 proto_item_set_end(item
, tvb
, offset
);
2098 enum CInGroupSortAggregSet_type
{
2099 GroupIdDefault
= 0x00, /* The default for all ranges. */
2100 GroupIdMinValue
= 0x01, /*The first range in the parent's group.*/
2101 GroupIdNull
= 0x02, /*The last range in the parent's group.*/
2102 GroupIdValue
= 0x03,
2105 /* 2.2.1.29 CInGroupSortAggregSet */
2106 static int parse_CInGroupSortAggregSet(tvbuff_t
*tvb
, int offset
,
2107 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2108 const char *fmt
, ...)
2113 enum CInGroupSortAggregSet_type type
;
2116 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2117 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSet
);
2120 type
= tvb_get_guint8(tvb
, offset
);
2121 proto_tree_add_text(tree
, tvb
, offset
, 1, "Type: 0x%02x", (unsigned)type
);
2124 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "CInGroupSortAggregSet");
2126 if (type
== GroupIdValue
) {
2127 struct CBaseStorageVariant id
;
2128 offset
= parse_CBaseStorageVariant(tvb
, offset
, tree
, pad_tree
, &id
, "inGroupId");
2131 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
2133 proto_item_set_end(item
, tvb
, offset
);
2138 /* 2.2.1.28 CInGroupSortAggregSets */
2139 static int parse_CInGroupSortAggregSets(tvbuff_t
*tvb
, int offset
,
2140 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2141 const char *fmt
, ...)
2150 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2151 tree
= proto_item_add_subtree(item
, ett_CInGroupSortAggregSets
);
2154 cCount
= tvb_get_letohl(tvb
, offset
);
2155 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", cCount
);
2158 for (i
=0; i
<cCount
; i
++) {
2159 /* 2.2.1.29 CInGroupSortAggregSet */
2160 offset
= parse_CInGroupSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortSets[%u]", i
);
2163 proto_item_set_end(item
, tvb
, offset
);
2167 /* 2.2.1.20 CCategorizationSpec */
2168 int parse_CCategorizationSpec(tvbuff_t
*tvb
, int offset
,
2169 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2170 const char *fmt
, ...)
2172 guint32 cMaxResults
;
2179 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2180 tree
= proto_item_add_subtree(item
, ett_CCategorizationSpec
);
2183 /* 2.2.1.18 CColumnSet */
2184 offset
= parse_CColumnSet(tvb
, offset
, tree
, "csColumns");
2186 /* 2.2.1.21 CCategSpec */
2187 offset
= parse_CCategSpec(tvb
, offset
, tree
, pad_tree
, "Spec");
2189 /* 2.2.1.24 CAggregSet */
2190 offset
= parse_CAggregSet(tvb
, offset
, tree
, pad_tree
, "AggregSet");
2192 /* 2.2.1.26 CSortAggregSet */
2193 offset
= parse_CSortAggregSet(tvb
, offset
, tree
, pad_tree
, "SortAggregSet");
2195 /* 2.2.1.28 CInGroupSortAggregSets */
2196 offset
= parse_CInGroupSortAggregSets(tvb
, offset
, tree
, pad_tree
, "InGroupSortAggregSets");
2198 cMaxResults
= tvb_get_letohl(tvb
, offset
);
2199 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", cMaxResults
);
2202 proto_item_set_end(item
, tvb
, offset
);
2206 int parse_CRowsetProperties(tvbuff_t
*tvb
, int offset
,
2207 proto_tree
*parent_tree
, proto_tree
*pad_tree _U_
,
2208 const char *fmt
, ...)
2210 guint32 opt
, maxres
, timeout
;
2217 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2218 tree
= proto_item_add_subtree(item
, ett_CRowsetProperties
);
2221 opt
= tvb_get_letohl(tvb
, offset
);
2222 proto_tree_add_text(tree
, tvb
, offset
, 4, "uBooleanOptions: 0x%08x", opt
);
2225 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMaxOpenRows (ignored)");
2228 proto_tree_add_text(tree
, tvb
, offset
, 4, "ulMemoryUsage (ignored)");
2231 maxres
= tvb_get_letohl(tvb
, offset
);
2232 proto_tree_add_text(tree
, tvb
, offset
, 4, "cMaxResults: %u", maxres
);
2235 timeout
= tvb_get_letohl(tvb
, offset
);
2236 proto_tree_add_text(tree
, tvb
, offset
, 4, "cCmdTimeout: %u", timeout
);
2239 proto_item_set_end(item
, tvb
, offset
);
2243 int parse_CPidMapper(tvbuff_t
*tvb
, int offset
,
2244 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2245 const char *fmt
, ...)
2253 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2254 tree
= proto_item_add_subtree(item
, ett_CPidMapper
);
2257 count
= tvb_get_letohl(tvb
, offset
);
2258 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2261 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "CPidMapper_PropSpec");
2263 for (i
=0; i
<count
; i
++) {
2264 struct CFullPropSpec v
;
2266 offset
= parse_padding(tvb
, offset
, 4, pad_tree
,
2267 "CPidMapper_PropSpec[%u]", i
); //at begin or end of loop???
2268 offset
= parse_CFullPropSpec(tvb
, offset
, tree
, pad_tree
, &v
, "PropSpec[%u]", i
);
2271 proto_item_set_end(item
, tvb
, offset
);
2275 /* 2.2.1.35 CColumnGroup */
2276 int parse_CColumnGroup(tvbuff_t
*tvb
, int offset
,
2277 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2278 const char *fmt
, ...)
2281 proto_item
*item
, *ti
;
2284 guint32 count
, groupPid
, i
;
2287 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2289 tree
= proto_item_add_subtree(item
, ett_CColumnGroup
);
2291 count
= tvb_get_letohl(tvb
, offset
);
2292 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2295 groupPid
= tvb_get_letohl(tvb
, offset
);
2296 ti
= proto_tree_add_text(tree
, tvb
, offset
, 4, "groupPid: 0x%08x", groupPid
);
2297 if ((0xFFFF0000 & groupPid
) == 0x7FFF0000) {
2298 proto_item_append_text(ti
, " Idx: %u", groupPid
& 0xFFFF);
2300 proto_item_append_text(ti
, "<Invalid>");
2304 for (i
=0; i
<count
; i
++) {
2305 /* 2.2.1.36 SProperty */
2306 guint32 pid
, weight
;
2307 pid
= tvb_get_letohl(tvb
, offset
);
2308 weight
= tvb_get_letohl(tvb
, offset
+ 4);
2309 proto_tree_add_text(tree
, tvb
, offset
, 8, "Props[%u]: pid: %u weight: %u", i
, pid
, weight
);
2313 proto_item_set_end(item
, tvb
, offset
);
2317 /* 2.2.1.34 CColumnGroupArray */
2318 int parse_CColumnGroupArray(tvbuff_t
*tvb
, int offset
,
2319 proto_tree
*parent_tree
, proto_tree
*pad_tree
,
2320 const char *fmt
, ...)
2329 item
= proto_tree_add_text_valist(parent_tree
, tvb
, offset
, 0, fmt
, ap
);
2331 tree
= proto_item_add_subtree(item
, ett_CColumnGroupArray
);
2333 count
= tvb_get_letohl(tvb
, offset
);
2334 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2337 for (i
=0; i
<count
; i
++) {
2338 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "aGroupArray[%u]", i
);
2339 offset
= parse_CColumnGroup(tvb
, offset
, tree
, pad_tree
, "aGroupArray[%u]", i
);
2342 proto_item_set_end(item
, tvb
, offset
);
2347 /* Code to actually dissect the packets */
2349 static int dissect_CPMConnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
2357 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
2358 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
2359 proto_item_set_text(ti
, "CPMConnect%s", in
? "In" : "Out");
2360 col_append_str(pinfo
->cinfo
, COL_INFO
, "Connect");
2362 version
= tvb_get_letohl(tvb
, offset
);
2363 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_Connect_Version
, tvb
,
2364 offset
, 4, ENC_LITTLE_ENDIAN
);
2365 if (version
& 0xffff0000) {
2366 proto_item_append_text(ti
, " 64 bit");
2368 switch (version
& 0xffff) {
2370 proto_item_append_text(ti
, " w2k8 or vista");
2373 proto_item_append_text(ti
, " XP or w2k3, with Windows Search 4.0");
2376 proto_item_append_text(ti
, " win7 or w2k8r2");
2382 guint32 blob_size1_off
, blob_size2_off
;
2383 proto_tree
*pad_tree
;
2385 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
2386 pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
2388 proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_ClientIsRemote
, tvb
,
2389 offset
, 4, ENC_LITTLE_ENDIAN
);
2393 blob_size1_off
= offset
;
2396 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcbBlob2");
2399 blob_size2_off
= offset
;
2402 offset
= parse_padding(tvb
, offset
, 16, pad_tree
, "_padding");
2404 len
= tvb_unicode_strsize(tvb
, offset
);
2405 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_MachineName
, tvb
,
2406 offset
, len
, ENC_UTF_16
);
2407 /*This shouldnt be necessary, is this a bug or is there some GUI setting I've missed?*/
2408 proto_item_set_text(ti
, "Remote machine: %s",
2409 tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
2412 len
= tvb_unicode_strsize(tvb
, offset
);
2413 ti
= proto_tree_add_item(tree
, hf_mswsp_msg_ConnectIn_UserName
, tvb
,
2414 offset
, len
, ENC_UTF_16
);
2415 proto_item_set_text(ti
, "User: %s", tvb_get_unicode_string(wmem_packet_scope(), tvb
, offset
, len
, ENC_LITTLE_ENDIAN
));
2418 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "_paddingcPropSets");
2420 offset
= parse_PropertySetArray(tvb
, offset
, blob_size1_off
, tree
, pad_tree
, "PropSets");
2422 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "paddingExtPropset");
2424 offset
= parse_PropertySetArray(tvb
, offset
, blob_size2_off
, tree
, pad_tree
, "ExtPropset");
2426 offset
= parse_padding(tvb
, offset
, 8, pad_tree
, "???");
2428 DISSECTOR_ASSERT(offset
== (int)tvb_length(tvb
));
2430 /* make "Padding" the last item */
2431 proto_tree_move_item(tree
, ti
, proto_tree_get_parent(pad_tree
));
2435 return tvb_length(tvb
);
2438 static int dissect_CPMDisconnect(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2440 col_append_str(pinfo
->cinfo
, COL_INFO
, "Disconnect");
2441 return tvb_length(tvb
);
2444 static int dissect_CPMCreateQuery(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
2450 item
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
2451 tree
= proto_item_add_subtree(item
, ett_mswsp_msg
);
2453 proto_item_set_text(item
, "CPMCreateQuery%s", in
? "In" : "Out");
2454 col_append_str(pinfo
->cinfo
, COL_INFO
, "CreateQuery");
2457 proto_item
*ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
2458 proto_tree
*pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
2459 guint8 CColumnSetPresent
, CRestrictionPresent
, CSortSetPresent
, CCategorizationSetPresent
;
2460 guint32 size
= tvb_get_letohl(tvb
, offset
);
2461 proto_tree_add_text(tree
, tvb
, offset
, 4, "size");
2462 proto_tree_add_text(tree
, tvb
, offset
, size
, "ALL");
2465 CColumnSetPresent
= tvb_get_guint8(tvb
, offset
);
2466 proto_tree_add_text(tree
, tvb
, offset
, 1, "CColumnSetPresent: %s", CColumnSetPresent
? "True" : "False");
2469 if (CColumnSetPresent
) {
2470 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCColumnSetPresent");
2471 offset
= parse_CColumnSet(tvb
, offset
, tree
, "CColumnSet");
2474 CRestrictionPresent
= tvb_get_guint8(tvb
, offset
);
2475 proto_tree_add_text(tree
, tvb
, offset
, 1, "CRestrictionPresent: %s", CColumnSetPresent
? "True" : "False");
2477 if (CRestrictionPresent
) {
2478 offset
= parse_CRestrictionArray(tvb
, offset
, tree
, pad_tree
, "RestrictionArray");
2481 CSortSetPresent
= tvb_get_guint8(tvb
, offset
);
2482 proto_tree_add_text(tree
, tvb
, offset
, 1, "CSortSetPresent: %s", CSortSetPresent
? "True" : "False");
2484 if (CSortSetPresent
) {
2485 offset
= parse_padding(tvb
, offset
, 4, tree
, "paddingCSortSetPresent");
2487 proto_tree_add_text(tree
, tvb
, offset
, 8, "XXX");
2490 offset
= parse_CSortSet(tvb
, offset
, tree
, pad_tree
, "SortSet");
2493 CCategorizationSetPresent
= tvb_get_guint8(tvb
, offset
);
2494 proto_tree_add_text(tree
, tvb
, offset
, 1, "CCategorizationSetPresent: %s", CCategorizationSetPresent
? "True" : "False");
2497 if (CCategorizationSetPresent
) {
2499 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "paddingCCategorizationSetPresent");
2500 /* 2.2.1.19 CCategorizationSet */
2501 count
= tvb_get_letohl(tvb
, offset
);
2502 proto_tree_add_text(tree
, tvb
, offset
, 4, "count: %u", count
);
2504 for (i
=0; i
<count
; i
++) {
2505 offset
= parse_CCategorizationSpec(tvb
, offset
, tree
, pad_tree
, "categories[%u]", i
);
2509 offset
= parse_padding(tvb
, offset
, 4, tree
, "XXXX"); //XXX
2511 offset
= parse_CRowsetProperties(tvb
, offset
, tree
, pad_tree
, "RowSetProperties");
2513 offset
= parse_CPidMapper(tvb
, offset
, tree
, pad_tree
, "PidMapper");
2515 offset
= parse_CColumnGroupArray(tvb
, offset
, tree
, pad_tree
, "GroupArray");
2517 proto_tree_add_text(tree
, tvb
, offset
, 4, "TrueSequential");
2519 proto_tree_add_text(tree
, tvb
, offset
, 4, "WorkIdUnique");
2521 proto_tree_add_text(tree
, tvb
, offset
, -1, "Cursors");
2522 //offset += 4*(#CategorizationSet + 1);
2525 return tvb_length(tvb
);
2528 static int dissect_CPMFreeCursor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2530 col_append_str(pinfo
->cinfo
, COL_INFO
, "FreeCursor");
2531 return tvb_length(tvb
);
2534 static int dissect_CPMGetRows(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2536 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRows");
2537 return tvb_length(tvb
);
2540 static int dissect_CPMRatioFinished(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2542 col_append_str(pinfo
->cinfo
, COL_INFO
, "RatioFinished");
2543 return tvb_length(tvb
);
2546 static int dissect_CPMCompareBmk(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2548 col_append_str(pinfo
->cinfo
, COL_INFO
, "CompareBmk");
2549 return tvb_length(tvb
);
2552 static int dissect_CPMGetApproximatePosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2554 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetApproximatePosition");
2555 return tvb_length(tvb
);
2559 static int dissect_CPMSetBindings(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
2563 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetBindings");
2567 proto_tree
*tree
, *pad_tree
;
2568 guint32 size
, num
, n
;
2570 ti
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
2571 tree
= proto_item_add_subtree(ti
, ett_mswsp_msg
);
2573 proto_item_set_text(ti
, "SetBindingsIn");
2575 ti
= proto_tree_add_text(tree
, tvb
, offset
, 0, "Padding");
2576 pad_tree
= proto_item_add_subtree(ti
, ett_mswsp_pad
);
2578 proto_tree_add_text(tree
, tvb
, offset
, 4, "hCursor");
2580 proto_tree_add_text(tree
, tvb
, offset
, 4, "cbRow");
2583 size
= tvb_get_letohl(tvb
, offset
);
2584 proto_tree_add_text(tree
, tvb
, offset
, 4, "cbBindingDesc: %d", size
);
2587 proto_tree_add_text(tree
, tvb
, offset
, 4, "dummy");
2590 num
= tvb_get_letohl(tvb
, offset
);
2591 proto_tree_add_text(tree
, tvb
, offset
, 4, "cColumns: %u", num
);
2594 proto_tree_add_text(tree
, tvb
, offset
, size
-4, "aColumns");
2595 for (n
=0; n
<num
; n
++) {
2596 offset
= parse_padding(tvb
, offset
, 4, pad_tree
, "padding_aColumns[%u]", n
);
2597 offset
= parse_CTableColumn(tvb
, offset
, tree
, pad_tree
, "aColumns[%u]", n
);
2600 } else { /* server only returns status with header */
2603 return tvb_length(tvb
);
2606 static int dissect_CPMGetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2608 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetNotify");
2609 return tvb_length(tvb
);
2612 static int dissect_CPMSendNotifyOut(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2614 col_append_str(pinfo
->cinfo
, COL_INFO
, "SendNotify");
2615 return tvb_length(tvb
);
2618 static int dissect_CPMGetQueryStatus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, gboolean in
)
2624 item
= proto_tree_add_item(parent_tree
, hf_mswsp_msg
, tvb
, offset
, -1, ENC_NA
);
2625 tree
= proto_item_add_subtree(item
, ett_mswsp_msg
);
2627 proto_item_set_text(item
, "GetQueryStatus%s", in
? "In" : "Out");
2628 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatus");
2632 proto_tree_add_text(tree
, tvb
, offset
, 4, "hCursor");
2636 proto_tree_add_text(tree
, tvb
, offset
, 4, "QStatus");
2640 return tvb_length(tvb
);
2643 static int dissect_CPMCiState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2645 col_append_str(pinfo
->cinfo
, COL_INFO
, "CiState");
2646 return tvb_length(tvb
);
2649 static int dissect_CPMFetchValue(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2651 col_append_str(pinfo
->cinfo
, COL_INFO
, "FetchValue");
2652 return tvb_length(tvb
);
2655 static int dissect_CPMGetQueryStatusEx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2657 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetQueryStatusEx");
2658 return tvb_length(tvb
);
2661 static int dissect_CPMRestartPosition(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2663 col_append_str(pinfo
->cinfo
, COL_INFO
, "RestartPosition");
2664 return tvb_length(tvb
);
2667 static int dissect_CPMSetCatState(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2669 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetCatState");
2670 return tvb_length(tvb
);
2673 static int dissect_CPMGetRowsetNotify(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2675 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetRowsetNotify");
2676 return tvb_length(tvb
);
2679 static int dissect_CPMFindIndices(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2681 col_append_str(pinfo
->cinfo
, COL_INFO
, "FindIndices");
2682 return tvb_length(tvb
);
2685 static int dissect_CPMSetScopePrioritization(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2687 col_append_str(pinfo
->cinfo
, COL_INFO
, "SetScopePrioritization");
2688 return tvb_length(tvb
);
2691 static int dissect_CPMGetScopeStatistics(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree _U_
, gboolean in _U_
)
2693 col_append_str(pinfo
->cinfo
, COL_INFO
, "GetScopeStatistics");
2694 return tvb_length(tvb
);
2697 static void debug_frame(int frame
)
2699 static const char *dbg_wait
= NULL
;
2700 static int wait_frame
= -1;
2702 if (dbg_wait
== NULL
) {
2703 dbg_wait
= getenv("DBG_FRAME");
2704 if (dbg_wait
== NULL
) {
2707 wait_frame
= atoi(dbg_wait
);
2711 if (frame
== wait_frame
) {
2712 static volatile gboolean wait
= 1;
2713 fprintf(stderr
, "waiting for debugger with pid: %u\n", getpid());
2722 dissect_mswsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, gboolean in
)
2724 proto_tree
*mswsp_tree
= NULL
;
2731 int (*fn
)(tvbuff_t
*, packet_info
*, proto_tree
*, gboolean
);
2733 if (tvb_length(tvb
) < 16) {
2737 hdr
.msg
= tvb_get_letohl(tvb
, 0);
2741 fn
= dissect_CPMConnect
;
2744 fn
= dissect_CPMDisconnect
;
2747 fn
= dissect_CPMCreateQuery
;
2750 fn
= dissect_CPMFreeCursor
;
2753 fn
= dissect_CPMGetRows
;
2756 fn
= dissect_CPMRatioFinished
;
2759 fn
= dissect_CPMCompareBmk
;
2762 fn
= dissect_CPMGetApproximatePosition
;
2765 fn
= dissect_CPMSetBindings
;
2768 fn
= dissect_CPMGetNotify
;
2771 fn
= dissect_CPMSendNotifyOut
;
2774 fn
= dissect_CPMGetQueryStatus
;
2777 fn
= dissect_CPMCiState
;
2780 fn
= dissect_CPMFetchValue
;
2783 fn
= dissect_CPMGetQueryStatusEx
;
2786 fn
= dissect_CPMRestartPosition
;
2789 fn
= dissect_CPMSetCatState
;
2792 fn
= dissect_CPMGetRowsetNotify
;
2795 fn
= dissect_CPMFindIndices
;
2798 fn
= dissect_CPMSetScopePrioritization
;
2801 fn
= dissect_CPMGetScopeStatistics
;
2807 hdr
.status
= tvb_get_letohl(tvb
, 4);
2808 hdr
.checksum
= tvb_get_letohl(tvb
, 8);
2810 /* col_set_str(pinfo->cinfo, COL_PROTOCOL, "MS-WSP"); */
2811 col_append_str(pinfo
->cinfo
, COL_PROTOCOL
, " WSP");
2812 /* col_clear(pinfo->cinfo, COL_INFO); */
2814 col_set_str(pinfo
->cinfo
, COL_INFO
, "WSP ");
2815 col_append_str(pinfo
->cinfo
, COL_INFO
, in
? "Request: " : "Response: ");
2818 proto_tree
*hdr_tree
;
2819 proto_item
*ti
, *hti
;
2821 ti
= proto_tree_add_item(tree
, proto_mswsp
, tvb
, 0, -1, ENC_NA
);
2822 mswsp_tree
= proto_item_add_subtree(ti
, ett_mswsp
);
2824 hti
= proto_tree_add_item(mswsp_tree
, hf_mswsp_hdr
, tvb
, 0, 16, ENC_NA
);
2825 hdr_tree
= proto_item_add_subtree(hti
, ett_mswsp_hdr
);
2827 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_msg
, tvb
,
2828 0, 4, ENC_LITTLE_ENDIAN
);
2829 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_status
,
2830 tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
2831 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_checksum
,
2832 tvb
, 8, 4, ENC_LITTLE_ENDIAN
);
2833 proto_tree_add_item(hdr_tree
, hf_mswsp_hdr_reserved
, tvb
,
2834 12, 4, ENC_LITTLE_ENDIAN
);
2837 fn(tvb
, pinfo
, mswsp_tree
, in
);
2839 /* Return the amount of data this dissector was able to dissect */
2840 return tvb_length(tvb
);
2844 /* Register the protocol with Wireshark */
2846 /* this format is require because a script is used to build the C function
2847 that calls all the protocol registration.
2851 proto_register_mswsp(void)
2853 module_t
*mswsp_module
;
2855 /* Setup list of header fields See Section 1.6.1 for details*/
2856 static const value_string msg_ids
[] = {
2857 {0x000000C8, "CPMConnect"}, /* In/Out */
2858 {0x000000C9, "CPMDisconnect"},
2859 {0x000000CA, "CPMCreateQuery"}, /* In/Out */
2860 {0x000000CB, "CPMFreeCursor"}, /* In/Out */
2861 {0x000000CC, "CPMGetRows"}, /* In/Out */
2862 {0x000000CD, "CPMRatioFinished"}, /* In/Out */
2863 {0x000000CE, "CPMCompareBmk"}, /* In/Out */
2864 {0x000000CF, "CPMGetApproximatePosition"}, /* In/Out */
2865 {0x000000D0, "CPMSetBindingsIn"},
2866 {0x000000D1, "CPMGetNotify"},
2867 {0x000000D2, "CPMSendNotifyOut"},
2868 {0x000000D7, "CPMGetQueryStatusIn"}, /* In/Out */
2869 {0x000000D9, "CPMCiStateInOut"},
2870 {0x000000E4, "CPMFetchValue"}, /* In/Out */
2871 {0x000000E7, "CPMGetQueryStatusEx"}, /* In/Out */
2872 {0x000000E8, "CPMRestartPositionIn"},
2873 {0x000000EC, "CPMSetCatStateIn"}, /* (not supported) */
2874 {0x000000F1, "CPMGetRowsetNotify"}, /* In/Out */
2875 {0x000000F2, "CPMFindIndices"}, /* In/Out */
2876 {0x000000F3, "CPMSetScopePrioritization"}, /* In/Out */
2877 {0x000000F4, "CPMGetScopeStatistics"}, /* In/Out */
2879 static hf_register_info hf
[] = {
2881 { "Header", "mswsp.hdr",
2882 FT_NONE
, BASE_NONE
, NULL
, 0,
2883 "Message header", HFILL
}
2885 { &hf_mswsp_hdr_msg
,
2886 { "Msg id", "mswsp.hdr.id",
2887 FT_UINT32
, BASE_HEX
, VALS(msg_ids
), 0,
2888 "Message id", HFILL
}
2890 { &hf_mswsp_hdr_status
,
2891 { "Status", "mswsp.hdr.status",
2892 FT_UINT32
, BASE_HEX
, NULL
, 0,
2895 { &hf_mswsp_hdr_checksum
,
2896 { "checksum", "mswsp.hdr.checksum",
2897 FT_UINT32
, BASE_HEX
, NULL
, 0,
2900 { &hf_mswsp_hdr_reserved
,
2901 { "Reserved", "mswsp.hdr.reserved",
2902 FT_UINT32
, BASE_HEX
, NULL
, 0,
2906 { "msg", "mswsp.msg",
2907 FT_NONE
, BASE_NONE
, NULL
, 0,
2910 { &hf_mswsp_msg_Connect_Version
,
2911 { "Version", "mswsp.Connect.version",
2912 FT_UINT32
, BASE_HEX
, NULL
, 0,
2915 { &hf_mswsp_msg_ConnectIn_ClientIsRemote
,
2916 { "Remote", "mswsp.ConnectIn.isRemote",
2917 FT_BOOLEAN
, BASE_HEX
, NULL
, 0,
2918 "Client is remote",HFILL
}
2920 { &hf_mswsp_msg_ConnectIn_Blob1
,
2921 { "Size", "mswsp.ConnectIn.propset.size",
2922 FT_UINT32
, BASE_DEC
, NULL
, 0,
2923 "Size of PropSet fields",HFILL
}
2925 { &hf_mswsp_msg_ConnectIn_Blob2
,
2926 { "Size", "mswsp.ConnectIn.extpropset.size",
2927 FT_UINT32
, BASE_DEC
, NULL
, 0,
2928 "Size of ExtPropSet fields",HFILL
}
2930 { &hf_mswsp_msg_ConnectIn_MachineName
,
2931 { "Remote machine", "mswsp.ConnectIn.machine",
2932 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2933 "Name of remote machine",HFILL
}
2935 { &hf_mswsp_msg_ConnectIn_UserName
,
2936 { "User", "mswsp.ConnectIn.user",
2937 FT_STRINGZ
, BASE_NONE
, NULL
, 0,
2938 "Name of remote user",HFILL
}
2940 { &hf_mswsp_msg_ConnectIn_PropSets_num
,
2941 { "Num", "mswsp.ConnectIn.propset.num",
2942 FT_UINT32
, BASE_DEC
, NULL
, 0,
2943 "Number of Property Sets", HFILL
}
2945 { &hf_mswsp_msg_ConnectIn_ExtPropSets_num
,
2946 { "Num", "mswsp.ConnectIn.extpropset.num",
2947 FT_UINT32
, BASE_DEC
, NULL
, 0,
2948 "Number of extended Property Sets", HFILL
}
2953 /* Setup protocol subtree array */
2954 static gint
*ett
[] = {
2959 &ett_mswsp_property_restriction
,
2960 &ett_CRestrictionArray
,
2961 &ett_CBaseStorageVariant
,
2962 &ett_CBaseStorageVariant_Vector
,
2963 &ett_CBaseStorageVariant_Array
,
2968 &ett_CDbPropSet_Array
,
2970 &ett_CNodeRestriction
,
2971 &ett_CPropertyRestriction
,
2972 &ett_CCoercionRestriction
,
2973 &ett_CContentRestriction
,
2975 &ett_CRangeCategSpec
,
2979 &ett_CCategorizationSpec
,
2980 &ett_CAggregSortKey
,
2981 &ett_CSortAggregSet
,
2982 &ett_CInGroupSortAggregSet
,
2983 &ett_CInGroupSortAggregSets
,
2984 &ett_CRowsetProperties
,
2989 &ett_CNatLanguageRestriction
,
2991 &ett_CColumnGroupArray
,
2998 /* Register the protocol name and description */
2999 proto_mswsp
= proto_register_protocol("Windows Search Protocol",
3002 /* Required function calls to register the header fields and subtrees used */
3003 proto_register_field_array(proto_mswsp
, hf
, array_length(hf
));
3004 proto_register_subtree_array(ett
, array_length(ett
));
3006 for (i
=0; i
<(int)array_length(GuidPropertySet
); i
++) {
3007 guids_add_guid(&GuidPropertySet
[i
].guid
, GuidPropertySet
[i
].def
);
3011 /* Register preferences module (See Section 2.6 for more on preferences) */
3012 /* (Registration of a prefs callback is not required if there are no */
3013 /* prefs-dependent registration functions (eg: a port pref). */
3014 /* See proto_reg_handoff below. */
3015 /* If a prefs callback is not needed, use NULL instead of */
3016 /* proto_reg_handoff_mswsp in the following). */
3017 mswsp_module
= prefs_register_protocol(proto_mswsp
,
3018 proto_reg_handoff_mswsp
);
3020 /* Register preferences module under preferences subtree.
3021 Use this function instead of prefs_register_protocol if you want to group
3022 preferences of several protocols under one preferences subtree.
3023 Argument subtree identifies grouping tree node name, several subnodes can be
3024 specified using slash '/' (e.g. "OSI/X.500" - protocol preferences will be
3025 accessible under Protocols->OSI->X.500-><PROTOSHORTNAME> preferences node.
3027 /* mswsp_module = prefs_register_protocol_subtree(subtree, */
3028 /* proto_mswsp, proto_reg_handoff_mswsp); */
3030 /* Register a sample preference */
3031 prefs_register_bool_preference(mswsp_module
, "show_hex",
3032 "Display numbers in Hex",
3033 "Enable to display numerical values in hexadecimal.",
3036 /* Register a sample port preference */
3037 prefs_register_uint_preference(mswsp_module
, "tcp.port", "mswsp TCP Port",
3038 " mswsp TCP port if other than the default",
3042 static int dissect_mswsp_smb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
3043 smb_info_t
*si
= pinfo
->private_data
;
3044 gboolean in
= si
->request
;
3046 smb_transact_info_t
*tri
= (si
->sip
->extra_info_type
== SMB_EI_TRI
) ? si
->sip
->extra_info
: NULL
;
3047 smb_fid_info_t
*fid_info
= NULL
;
3050 debug_frame((int)pinfo
->fd
->num
);
3052 fprintf(stderr
, "dissect_mswsp_smb %s frame: %d tid: %d op: %02x ",
3053 in
? "Request" : "Response",
3054 pinfo
->fd
->num
, si
->tid
, si
->cmd
);
3057 fprintf(stderr
, " extra_info_type: %d\n", si
->sip
->extra_info_type
);
3061 for (iter
= si
->ct
->GSL_fid_info
; iter
; iter
= g_slist_next(iter
)) {
3062 smb_fid_info_t
*info
= iter
->data
;
3063 if ((info
->tid
== si
->tid
) && (info
->fid
== tri
->fid
)) {
3069 if (!fid_info
|| !fid_info
->fsi
|| !fid_info
->fsi
->filename
) {
3070 fprintf(stderr
, " no %s\n", fid_info
? (fid_info
->fsi
? "filename" : "fsi") : "fid_info");
3074 fprintf(stderr
, " file: %s\n", fid_info
->fsi
->filename
);
3076 if (strcasecmp(fid_info
->fsi
->filename
, "\\MsFteWds") != 0) {
3080 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
3084 static int dissect_mswsp_smb2(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
) {
3085 smb2_info_t
*si
= pinfo
->private_data
;
3086 gboolean in
= !(si
->flags
& SMB2_FLAGS_RESPONSE
);
3088 //si->tree->share_type == SMB2_SHARE_TYPE_PIPE
3089 //si->tree->connect_frame
3091 debug_frame((int)pinfo
->fd
->num
);
3093 fprintf(stderr
, "dissect_mswsp %d <> %d : op %02x %s %s type: %d extra_file: %s\n",
3094 pinfo
->fd
->num
, si
->tree
? (int)si
->tree
->connect_frame
: -1,
3096 pinfo
->dcerpc_procedure_name
? pinfo
->dcerpc_procedure_name
: "<NULL>",
3097 in
? "Request" : "Response", si
->tree
? si
->tree
->share_type
: -1,
3098 si
->saved
? (si
->saved
->extra_info_type
== SMB2_EI_FILENAME
? (char*)si
->saved
->extra_info
: "<OTHER>") : "<NONE>"
3102 if (strcmp(pinfo
->dcerpc_procedure_name
, "File: MsFteWds") != 0) {
3106 return dissect_mswsp(tvb
, pinfo
, tree
, in
);
3111 /* If this dissector uses sub-dissector registration add a registration routine.
3112 This exact format is required because a script is used to find these
3113 routines and create the code that calls these routines.
3115 If this function is registered as a prefs callback (see prefs_register_protocol
3116 above) this function is also called by preferences whenever "Apply" is pressed;
3117 In that case, it should accommodate being called more than once.
3119 Simple form of proto_reg_handoff_mswsp which can be used if there are
3120 no prefs-dependent registration function calls.
3124 proto_reg_handoff_mswsp(void)
3126 heur_dissector_add("smb_transact", dissect_mswsp_smb
, proto_mswsp
);
3127 heur_dissector_add("smb2_heur_subdissectors", dissect_mswsp_smb2
, proto_mswsp
);
3132 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3137 * indent-tabs-mode: nil
3140 * vi: set shiftwidth=4 tabstop=8 expandtab:
3141 * :indentSize=4:tabSize=8:noTabs=true: