Add tvbuff class.
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  *
5  * $Id: packet-smb.c,v 1.65 2000/05/11 08:15:46 gram Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-pop.c
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
40 #endif
41
42 #include <time.h>
43 #include <string.h>
44 #include <glib.h>
45 #include <ctype.h>
46 #include "packet.h"
47 #include "conversation.h"
48 #include "smb.h"
49 #include "alignment.h"
50
51 guint32 dissect_mailslot_smb(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int, int, const u_char *, int, int, int, int);
52
53 guint32 dissect_pipe_smb(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int, int, const u_char *, int, int, int, int);
54
55
56 static int proto_smb = -1;
57
58 static gint ett_smb = -1;
59 static gint ett_smb_fileattributes = -1;
60 static gint ett_smb_capabilities = -1;
61 static gint ett_smb_aflags = -1;
62 static gint ett_smb_dialects = -1;
63 static gint ett_smb_mode = -1;
64 static gint ett_smb_rawmode = -1;
65 static gint ett_smb_flags = -1;
66 static gint ett_smb_flags2 = -1;
67 static gint ett_smb_desiredaccess = -1;
68 static gint ett_smb_search = -1;
69 static gint ett_smb_file = -1;
70 static gint ett_smb_openfunction = -1;
71 static gint ett_smb_filetype = -1;
72 static gint ett_smb_action = -1;
73 static gint ett_smb_writemode = -1;
74 static gint ett_smb_lock_type = -1;
75
76
77
78 /*
79  * Struct passed to each SMB decode routine of info it may need
80  */
81
82 char *decode_smb_name(unsigned char);
83
84 int smb_packet_init_count = 200;
85
86 struct smb_request_key {
87   guint32 conversation;
88   guint16 mid;
89 };
90
91
92 GHashTable *smb_request_hash = NULL;
93 GMemChunk *smb_request_keys = NULL;
94 GMemChunk *smb_request_vals = NULL;
95
96 /* Hash Functions */
97 gint
98 smb_equal(gconstpointer v, gconstpointer w)
99 {
100   struct smb_request_key *v1 = (struct smb_request_key *)v;
101   struct smb_request_key *v2 = (struct smb_request_key *)w;
102
103 #if defined(DEBUG_SMB_HASH)
104   printf("Comparing %08X:%u\n      and %08X:%u\n",
105          v1 -> conversation, v1 -> mid,
106          v2 -> conversation, v2 -> mid);
107 #endif
108
109   if (v1 -> conversation == v2 -> conversation &&
110       v1 -> mid          == v2 -> mid) {
111
112     return 1;
113
114   }
115
116   return 0;
117 }
118
119 guint 
120 smb_hash (gconstpointer v)
121 {
122   struct smb_request_key *key = (struct smb_request_key *)v;
123   guint val;
124
125   val = key -> conversation + key -> mid;
126
127 #if defined(DEBUG_SMB_HASH)
128   printf("SMB Hash calculated as %u\n", val);
129 #endif
130
131   return val;
132
133 }
134
135 /*
136  * Free up any state information we've saved, and re-initialize the
137  * tables of state information.
138  */
139 static void
140 smb_init_protocol(void)
141 {
142 #if defined(DEBUG_SMB_HASH)
143   printf("Initializing SMB hashtable area\n");
144 #endif
145
146   if (smb_request_hash)
147     g_hash_table_destroy(smb_request_hash);
148   if (smb_request_keys)
149     g_mem_chunk_destroy(smb_request_keys);
150   if (smb_request_vals)
151     g_mem_chunk_destroy(smb_request_vals);
152
153   smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
154   smb_request_keys = g_mem_chunk_new("smb_request_keys",
155                                      sizeof(struct smb_request_key),
156                                      smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
157   smb_request_vals = g_mem_chunk_new("smb_request_vals",
158                                      sizeof(struct smb_request_val),
159                                      smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
160 }
161
162 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int, int, int);
163
164 char *SMB_names[256] = {
165   "SMBcreatedirectory",
166   "SMBdeletedirectory",
167   "SMBopen",
168   "SMBcreate",
169   "SMBclose",
170   "SMBflush",
171   "SMBunlink",
172   "SMBmv",
173   "SMBgetatr",
174   "SMBsetatr",
175   "SMBread",
176   "SMBwrite",
177   "SMBlock",
178   "SMBunlock",
179   "SMBctemp",
180   "SMBmknew",
181   "SMBchkpth",
182   "SMBexit",
183   "SMBlseek",
184   "SMBlockread",
185   "SMBwriteunlock",
186   "unknown-0x15",
187   "unknown-0x16",
188   "unknown-0x17",
189   "unknown-0x18",
190   "unknown-0x19",
191   "SMBreadBraw",
192   "SMBreadBmpx",
193   "SMBreadBs",
194   "SMBwriteBraw",
195   "SMBwriteBmpx",
196   "SMBwriteBs",
197   "SMBwriteC",
198   "unknown-0x21",
199   "SMBsetattrE",
200   "SMBgetattrE",
201   "SMBlockingX",
202   "SMBtrans",
203   "SMBtranss",
204   "SMBioctl",
205   "SMBioctls",
206   "SMBcopy",
207   "SMBmove",
208   "SMBecho",
209   "SMBwriteclose",
210   "SMBopenX",
211   "SMBreadX",
212   "SMBwriteX",
213   "unknown-0x30",
214   "SMBcloseandtreedisc",
215   "SMBtrans2",
216   "SMBtrans2secondary",
217   "SMBfindclose2",
218   "SMBfindnotifyclose",
219   "unknown-0x36",
220   "unknown-0x37",
221   "unknown-0x38",
222   "unknown-0x39",
223   "unknown-0x3A",
224   "unknown-0x3B",
225   "unknown-0x3C",
226   "unknown-0x3D",
227   "unknown-0x3E",
228   "unknown-0x3F",
229   "unknown-0x40",
230   "unknown-0x41",
231   "unknown-0x42",
232   "unknown-0x43",
233   "unknown-0x44",
234   "unknown-0x45",
235   "unknown-0x46",
236   "unknown-0x47",
237   "unknown-0x48",
238   "unknown-0x49",
239   "unknown-0x4A",
240   "unknown-0x4B",
241   "unknown-0x4C",
242   "unknown-0x4D",
243   "unknown-0x4E",
244   "unknown-0x4F",
245   "unknown-0x50",
246   "unknown-0x51",
247   "unknown-0x52",
248   "unknown-0x53",
249   "unknown-0x54",
250   "unknown-0x55",
251   "unknown-0x56",
252   "unknown-0x57",
253   "unknown-0x58",
254   "unknown-0x59",
255   "unknown-0x5A",
256   "unknown-0x5B",
257   "unknown-0x5C",
258   "unknown-0x5D",
259   "unknown-0x5E",
260   "unknown-0x5F",
261   "unknown-0x60",
262   "unknown-0x61",
263   "unknown-0x62",
264   "unknown-0x63",
265   "unknown-0x64",
266   "unknown-0x65",
267   "unknown-0x66",
268   "unknown-0x67",
269   "unknown-0x68",
270   "unknown-0x69",
271   "unknown-0x6A",
272   "unknown-0x6B",
273   "unknown-0x6C",
274   "unknown-0x6D",
275   "unknown-0x6E",
276   "unknown-0x6F",
277   "SMBtcon",
278   "SMBtdis",
279   "SMBnegprot",
280   "SMBsesssetupX",
281   "SMBlogoffX",
282   "SMBtconX",
283   "unknown-0x76",
284   "unknown-0x77",
285   "unknown-0x78",
286   "unknown-0x79",
287   "unknown-0x7A",
288   "unknown-0x7B",
289   "unknown-0x7C",
290   "unknown-0x7D",
291   "unknown-0x7E",
292   "unknown-0x7F",
293   "SMBdskattr",
294   "SMBsearch",
295   "SMBffirst",
296   "SMBfunique",
297   "SMBfclose",
298   "unknown-0x85",
299   "unknown-0x86",
300   "unknown-0x87",
301   "unknown-0x88",
302   "unknown-0x89",
303   "unknown-0x8A",
304   "unknown-0x8B",
305   "unknown-0x8C",
306   "unknown-0x8D",
307   "unknown-0x8E",
308   "unknown-0x8F",
309   "unknown-0x90",
310   "unknown-0x91",
311   "unknown-0x92",
312   "unknown-0x93",
313   "unknown-0x94",
314   "unknown-0x95",
315   "unknown-0x96",
316   "unknown-0x97",
317   "unknown-0x98",
318   "unknown-0x99",
319   "unknown-0x9A",
320   "unknown-0x9B",
321   "unknown-0x9C",
322   "unknown-0x9D",
323   "unknown-0x9E",
324   "unknown-0x9F",
325   "SMBnttransact",
326   "SMBnttransactsecondary",
327   "SMBntcreateX",
328   "unknown-0xA3",
329   "SMBntcancel",
330   "unknown-0xA5",
331   "unknown-0xA6",
332   "unknown-0xA7",
333   "unknown-0xA8",
334   "unknown-0xA9",
335   "unknown-0xAA",
336   "unknown-0xAB",
337   "unknown-0xAC",
338   "unknown-0xAD",
339   "unknown-0xAE",
340   "unknown-0xAF",
341   "unknown-0xB0",
342   "unknown-0xB1",
343   "unknown-0xB2",
344   "unknown-0xB3",
345   "unknown-0xB4",
346   "unknown-0xB5",
347   "unknown-0xB6",
348   "unknown-0xB7",
349   "unknown-0xB8",
350   "unknown-0xB9",
351   "unknown-0xBA",
352   "unknown-0xBB",
353   "unknown-0xBC",
354   "unknown-0xBD",
355   "unknown-0xBE",
356   "unknown-0xBF",
357   "SMBsplopen",
358   "SMBsplwr",
359   "SMBsplclose",
360   "SMBsplretq",
361   "unknown-0xC4",
362   "unknown-0xC5",
363   "unknown-0xC6",
364   "unknown-0xC7",
365   "unknown-0xC8",
366   "unknown-0xC9",
367   "unknown-0xCA",
368   "unknown-0xCB",
369   "unknown-0xCC",
370   "unknown-0xCD",
371   "unknown-0xCE",
372   "unknown-0xCF",
373   "SMBsends",
374   "SMBsendb",
375   "SMBfwdname",
376   "SMBcancelf",
377   "SMBgetmac",
378   "SMBsendstrt",
379   "SMBsendend",
380   "SMBsendtxt",
381   "SMBreadbulk",
382   "SMBwritebulk",
383   "SMBwritebulkdata",
384   "unknown-0xDB",
385   "unknown-0xDC",
386   "unknown-0xDD",
387   "unknown-0xDE",
388   "unknown-0xDF",
389   "unknown-0xE0",
390   "unknown-0xE1",
391   "unknown-0xE2",
392   "unknown-0xE3",
393   "unknown-0xE4",
394   "unknown-0xE5",
395   "unknown-0xE6",
396   "unknown-0xE7",
397   "unknown-0xE8",
398   "unknown-0xE9",
399   "unknown-0xEA",
400   "unknown-0xEB",
401   "unknown-0xEC",
402   "unknown-0xED",
403   "unknown-0xEE",
404   "unknown-0xEF",
405   "unknown-0xF0",
406   "unknown-0xF1",
407   "unknown-0xF2",
408   "unknown-0xF3",
409   "unknown-0xF4",
410   "unknown-0xF5",
411   "unknown-0xF6",
412   "unknown-0xF7",
413   "unknown-0xF8",
414   "unknown-0xF9",
415   "unknown-0xFA",
416   "unknown-0xFB",
417   "unknown-0xFC",
418   "unknown-0xFD",
419   "SMBinvalid",
420   "unknown-0xFF"
421 };
422
423 void 
424 dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
425 {
426
427   if (tree) {
428
429     proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)", 
430                         END_OF_FRAME); 
431
432   }
433
434 }
435
436 /* 
437  * Dissect a UNIX like date ...
438  */
439
440 struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
441                       conflict with /usr/include/time.h on some NetBSD
442                       systems */
443
444 static char *
445 dissect_smbu_date(guint16 date, guint16 time)
446
447 {
448   static char         datebuf[4+2+2+2+1];
449   time_t              ltime = (date << 16) + time;
450
451   _gtime = gmtime(&ltime);
452   sprintf(datebuf, "%04d-%02d-%02d",
453           1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
454
455   return datebuf;
456
457 }
458
459 /*
460  * Relies on time
461  */
462 static char *
463 dissect_smbu_time(guint16 date, guint16 time)
464
465 {
466   static char timebuf[2+2+2+2+1];
467
468   sprintf(timebuf, "%02d:%02d:%02d",
469           _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
470
471   return timebuf;
472
473 }
474
475 /*
476  * Dissect a DOS-format date.
477  */
478 static char *
479 dissect_dos_date(guint16 date)
480 {
481         static char datebuf[4+2+2+1];
482
483         sprintf(datebuf, "%04d-%02d-%02d",
484             ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
485         return datebuf;
486 }
487
488 /*
489  * Dissect a DOS-format time.
490  */
491 static char *
492 dissect_dos_time(guint16 time)
493 {
494         static char timebuf[2+2+2+1];
495
496         sprintf(timebuf, "%02d:%02d:%02d",
497             (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
498         return timebuf;
499 }
500
501 /* Max string length for displaying Unicode strings.  */
502 #define MAX_UNICODE_STR_LEN     256
503
504 /* Turn a little-endian Unicode '\0'-terminated string into a string we
505    can display.
506    XXX - for now, we just handle the ISO 8859-1 characters. */
507 static gchar *
508 unicode_to_str(const guint8 *us, int *us_lenp) {
509   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
510   static gchar *cur;
511   gchar        *p;
512   int           len;
513   int           us_len;
514   int           overflow = 0;
515
516   if (cur == &str[0][0]) {
517     cur = &str[1][0];
518   } else if (cur == &str[1][0]) {  
519     cur = &str[2][0];
520   } else {  
521     cur = &str[0][0];
522   }
523   p = cur;
524   len = MAX_UNICODE_STR_LEN;
525   us_len = 0;
526   while (*us != 0 || *(us + 1) != 0) {
527     if (len > 0) {
528       *p++ = *us;
529       len--;
530     } else
531       overflow = 1;
532     us += 2;
533     us_len += 2;
534   }
535   if (overflow) {
536     /* Note that we're not showing the full string.  */
537     *p++ = '.';
538     *p++ = '.';
539     *p++ = '.';
540   }
541   *p = '\0';
542   *us_lenp = us_len;
543   return cur;
544 }
545
546 /*
547  * Each dissect routine is passed an offset to wct and works from there 
548  */
549
550 void
551 dissect_flush_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
552
553 {
554   guint8        WordCount;
555   guint16       FID;
556   guint16       ByteCount;
557
558   if (dirn == 1) { /* Request(s) dissect code */
559
560     /* Build display for: Word Count (WCT) */
561
562     WordCount = GBYTE(pd, offset);
563
564     if (tree) {
565
566       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
567
568     }
569
570     offset += 1; /* Skip Word Count (WCT) */
571
572     /* Build display for: FID */
573
574     FID = GSHORT(pd, offset);
575
576     if (tree) {
577
578       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
579
580     }
581
582     offset += 2; /* Skip FID */
583
584     /* Build display for: Byte Count */
585
586     ByteCount = GSHORT(pd, offset);
587
588     if (tree) {
589
590       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
591
592     }
593
594     offset += 2; /* Skip Byte Count */
595
596   }
597
598   if (dirn == 0) { /* Response(s) dissect code */
599
600     /* Build display for: Word Count (WCT) */
601
602     WordCount = GBYTE(pd, offset);
603
604     if (tree) {
605
606       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
607
608     }
609
610     offset += 1; /* Skip Word Count (WCT) */
611
612     /* Build display for: Byte Count (BCC) */
613
614     ByteCount = GSHORT(pd, offset);
615
616     if (tree) {
617
618       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
619
620     }
621
622     offset += 2; /* Skip Byte Count (BCC) */
623
624   }
625
626 }
627
628 void
629 dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
630
631 {
632   guint8        WordCount;
633   guint16       TotalUnits;
634   guint16       Reserved;
635   guint16       FreeUnits;
636   guint16       ByteCount;
637   guint16       BlocksPerUnit;
638   guint16       BlockSize;
639
640   if (dirn == 1) { /* Request(s) dissect code */
641
642     /* Build display for: Word Count (WCT) */
643
644     WordCount = GBYTE(pd, offset);
645
646     if (tree) {
647
648       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
649
650     }
651
652     offset += 1; /* Skip Word Count (WCT) */
653
654     /* Build display for: Byte Count (BCC) */
655
656     ByteCount = GSHORT(pd, offset);
657
658     if (tree) {
659
660       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
661
662     }
663
664     offset += 2; /* Skip Byte Count (BCC) */
665
666   }
667
668   if (dirn == 0) { /* Response(s) dissect code */
669
670     /* Build display for: Word Count (WCT) */
671
672     WordCount = GBYTE(pd, offset);
673
674     if (tree) {
675
676       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
677
678     }
679
680     offset += 1; /* Skip Word Count (WCT) */
681
682     if (WordCount > 0) {
683
684       /* Build display for: Total Units */
685
686       TotalUnits = GSHORT(pd, offset);
687
688       if (tree) {
689
690         proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);
691
692       }
693
694       offset += 2; /* Skip Total Units */
695
696       /* Build display for: Blocks Per Unit */
697
698       BlocksPerUnit = GSHORT(pd, offset);
699
700       if (tree) {
701
702         proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);
703
704       }
705
706       offset += 2; /* Skip Blocks Per Unit */
707
708       /* Build display for: Block Size */
709
710       BlockSize = GSHORT(pd, offset);
711
712       if (tree) {
713
714         proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);
715
716       }
717
718       offset += 2; /* Skip Block Size */
719
720       /* Build display for: Free Units */
721
722       FreeUnits = GSHORT(pd, offset);
723
724       if (tree) {
725
726         proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);
727
728       }
729
730       offset += 2; /* Skip Free Units */
731
732       /* Build display for: Reserved */
733
734       Reserved = GSHORT(pd, offset);
735
736       if (tree) {
737
738         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
739
740       }
741
742       offset += 2; /* Skip Reserved */
743
744     }
745
746     /* Build display for: Byte Count (BCC) */
747
748     ByteCount = GSHORT(pd, offset);
749
750     if (tree) {
751
752       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
753
754     }
755
756     offset += 2; /* Skip Byte Count (BCC) */
757
758   }
759
760 }
761
762 void
763 dissect_set_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
764
765 {
766   proto_tree    *Attributes_tree;
767   proto_item    *ti;
768   guint8        WordCount;
769   guint8        ByteCount;
770   guint8        BufferFormat;
771   guint16       Reserved5;
772   guint16       Reserved4;
773   guint16       Reserved3;
774   guint16       Reserved2;
775   guint16       Reserved1;
776   guint16       LastWriteTime;
777   guint16       LastWriteDate;
778   guint16       Attributes;
779   const char    *FileName;
780
781   if (dirn == 1) { /* Request(s) dissect code */
782
783     /* Build display for: Word Count (WCT) */
784
785     WordCount = GBYTE(pd, offset);
786
787     if (tree) {
788
789       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
790
791     }
792
793     offset += 1; /* Skip Word Count (WCT) */
794
795     if (WordCount > 0) {
796
797       /* Build display for: Attributes */
798
799       Attributes = GSHORT(pd, offset);
800
801       if (tree) {
802
803         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
804         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
805         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
806                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
807         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
808                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
809         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
810                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
811         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
812                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
813         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
814                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
815         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
816                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
817         
818       }
819
820       offset += 2; /* Skip Attributes */
821
822       /* Build display for: Last Write Time */
823
824       LastWriteTime = GSHORT(pd, offset);
825
826       if (tree) {
827
828         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
829
830       }
831
832       offset += 2; /* Skip Last Write Time */
833
834       /* Build display for: Last Write Date */
835
836       LastWriteDate = GSHORT(pd, offset);
837
838       if (tree) {
839
840         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
841
842       }
843
844       offset += 2; /* Skip Last Write Date */
845
846       /* Build display for: Reserved 1 */
847
848       Reserved1 = GSHORT(pd, offset);
849
850       if (tree) {
851
852         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
853
854       }
855
856       offset += 2; /* Skip Reserved 1 */
857
858       /* Build display for: Reserved 2 */
859
860       Reserved2 = GSHORT(pd, offset);
861
862       if (tree) {
863
864         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
865
866       }
867
868       offset += 2; /* Skip Reserved 2 */
869
870       /* Build display for: Reserved 3 */
871
872       Reserved3 = GSHORT(pd, offset);
873
874       if (tree) {
875
876         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
877
878       }
879
880       offset += 2; /* Skip Reserved 3 */
881
882       /* Build display for: Reserved 4 */
883
884       Reserved4 = GSHORT(pd, offset);
885
886       if (tree) {
887
888         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
889
890       }
891
892       offset += 2; /* Skip Reserved 4 */
893
894       /* Build display for: Reserved 5 */
895
896       Reserved5 = GSHORT(pd, offset);
897
898       if (tree) {
899
900         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
901
902       }
903
904       offset += 2; /* Skip Reserved 5 */
905
906     }
907
908     /* Build display for: Byte Count (BCC) */
909
910     ByteCount = GSHORT(pd, offset);
911
912     if (tree) {
913
914       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
915
916     }
917
918     offset += 2; /* Skip Byte Count (BCC) */
919
920     /* Build display for: Buffer Format */
921
922     BufferFormat = GBYTE(pd, offset);
923
924     if (tree) {
925
926       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
927
928     }
929
930     offset += 1; /* Skip Buffer Format */
931
932     /* Build display for: File Name */
933
934     FileName = pd + offset;
935
936     if (tree) {
937
938       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
939
940     }
941
942     offset += strlen(FileName) + 1; /* Skip File Name */
943
944   }
945
946   if (dirn == 0) { /* Response(s) dissect code */
947
948     /* Build display for: Word Count (WCT) */
949
950     WordCount = GBYTE(pd, offset);
951
952     if (tree) {
953
954       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
955
956     }
957
958     offset += 1; /* Skip Word Count (WCT) */
959
960     /* Build display for: Byte Count (BCC) */
961
962     ByteCount = GBYTE(pd, offset);
963
964     if (tree) {
965
966       proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
967
968     }
969
970     offset += 1; /* Skip Byte Count (BCC) */
971
972   }
973
974 }
975
976 void
977 dissect_write_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
978
979 {
980   guint8        WordCount;
981   guint8        BufferFormat;
982   guint32       Offset;
983   guint16       Remaining;
984   guint16       FID;
985   guint16       DataLength;
986   guint16       Count;
987   guint16       ByteCount;
988
989   if (dirn == 1) { /* Request(s) dissect code */
990
991     /* Build display for: Word Count (WCT) */
992
993     WordCount = GBYTE(pd, offset);
994
995     if (tree) {
996
997       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
998
999     }
1000
1001     offset += 1; /* Skip Word Count (WCT) */
1002
1003     /* Build display for: FID */
1004
1005     FID = GSHORT(pd, offset);
1006
1007     if (tree) {
1008
1009       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1010
1011     }
1012
1013     offset += 2; /* Skip FID */
1014
1015     /* Build display for: Count */
1016
1017     Count = GSHORT(pd, offset);
1018
1019     if (tree) {
1020
1021       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1022
1023     }
1024
1025     offset += 2; /* Skip Count */
1026
1027     /* Build display for: Offset */
1028
1029     Offset = GWORD(pd, offset);
1030
1031     if (tree) {
1032
1033       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1034
1035     }
1036
1037     offset += 4; /* Skip Offset */
1038
1039     /* Build display for: Remaining */
1040
1041     Remaining = GSHORT(pd, offset);
1042
1043     if (tree) {
1044
1045       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
1046
1047     }
1048
1049     offset += 2; /* Skip Remaining */
1050
1051     /* Build display for: Byte Count (BCC) */
1052
1053     ByteCount = GSHORT(pd, offset);
1054
1055     if (tree) {
1056
1057       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1058
1059     }
1060
1061     offset += 2; /* Skip Byte Count (BCC) */
1062
1063     /* Build display for: Buffer Format */
1064
1065     BufferFormat = GBYTE(pd, offset);
1066
1067     if (tree) {
1068
1069       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
1070
1071     }
1072
1073     offset += 1; /* Skip Buffer Format */
1074
1075     /* Build display for: Data Length */
1076
1077     DataLength = GSHORT(pd, offset);
1078
1079     if (tree) {
1080
1081       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
1082
1083     }
1084
1085     offset += 2; /* Skip Data Length */
1086
1087   }
1088
1089   if (dirn == 0) { /* Response(s) dissect code */
1090
1091     /* Build display for: Word Count (WCT) */
1092
1093     WordCount = GBYTE(pd, offset);
1094
1095     if (tree) {
1096
1097       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1098
1099     }
1100
1101     offset += 1; /* Skip Word Count (WCT) */
1102
1103     /* Build display for: Count */
1104
1105     Count = GSHORT(pd, offset);
1106
1107     if (tree) {
1108
1109       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1110
1111     }
1112
1113     offset += 2; /* Skip Count */
1114
1115     /* Build display for: Byte Count (BCC) */
1116
1117     ByteCount = GSHORT(pd, offset);
1118
1119     if (tree) {
1120
1121       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1122
1123     }
1124
1125     offset += 2; /* Skip Byte Count (BCC) */
1126
1127   }
1128
1129 }
1130
1131 void
1132 dissect_read_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *arent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1133
1134 {
1135   guint8        WordCount;
1136   guint8        Pad;
1137   guint32       Reserved1;
1138   guint32       Offset;
1139   guint16       Reserved2;
1140   guint16       Reserved;
1141   guint16       MinCount;
1142   guint16       MaxCount;
1143   guint16       FID;
1144   guint16       DataOffset;
1145   guint16       DataLength;
1146   guint16       DataCompactionMode;
1147   guint16       Count;
1148   guint16       ByteCount;
1149
1150   if (dirn == 1) { /* Request(s) dissect code */
1151
1152     /* Build display for: Word Count (WCT) */
1153
1154     WordCount = GBYTE(pd, offset);
1155
1156     if (tree) {
1157
1158       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1159
1160     }
1161
1162     offset += 1; /* Skip Word Count (WCT) */
1163
1164     /* Build display for: FID */
1165
1166     FID = GSHORT(pd, offset);
1167
1168     if (tree) {
1169
1170       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1171
1172     }
1173
1174     offset += 2; /* Skip FID */
1175
1176     /* Build display for: Offset */
1177
1178     Offset = GWORD(pd, offset);
1179
1180     if (tree) {
1181
1182       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1183
1184     }
1185
1186     offset += 4; /* Skip Offset */
1187
1188     /* Build display for: Max Count */
1189
1190     MaxCount = GSHORT(pd, offset);
1191
1192     if (tree) {
1193
1194       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
1195
1196     }
1197
1198     offset += 2; /* Skip Max Count */
1199
1200     /* Build display for: Min Count */
1201
1202     MinCount = GSHORT(pd, offset);
1203
1204     if (tree) {
1205
1206       proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
1207
1208     }
1209
1210     offset += 2; /* Skip Min Count */
1211
1212     /* Build display for: Reserved 1 */
1213
1214     Reserved1 = GWORD(pd, offset);
1215
1216     if (tree) {
1217
1218       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 1: %u", Reserved1);
1219
1220     }
1221
1222     offset += 4; /* Skip Reserved 1 */
1223
1224     /* Build display for: Reserved 2 */
1225
1226     Reserved2 = GSHORT(pd, offset);
1227
1228     if (tree) {
1229
1230       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
1231
1232     }
1233
1234     offset += 2; /* Skip Reserved 2 */
1235
1236     /* Build display for: Byte Count (BCC) */
1237
1238     ByteCount = GSHORT(pd, offset);
1239
1240     if (tree) {
1241
1242       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1243
1244     }
1245
1246     offset += 2; /* Skip Byte Count (BCC) */
1247
1248   }
1249
1250   if (dirn == 0) { /* Response(s) dissect code */
1251
1252     /* Build display for: Word Count */
1253
1254     WordCount = GBYTE(pd, offset);
1255
1256     if (tree) {
1257
1258       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
1259
1260     }
1261
1262     offset += 1; /* Skip Word Count */
1263
1264     if (WordCount > 0) {
1265
1266       /* Build display for: Offset */
1267
1268       Offset = GWORD(pd, offset);
1269
1270       if (tree) {
1271
1272         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
1273
1274       }
1275
1276       offset += 4; /* Skip Offset */
1277
1278       /* Build display for: Count */
1279
1280       Count = GSHORT(pd, offset);
1281
1282       if (tree) {
1283
1284         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
1285
1286       }
1287
1288       offset += 2; /* Skip Count */
1289
1290       /* Build display for: Reserved */
1291
1292       Reserved = GSHORT(pd, offset);
1293
1294       if (tree) {
1295
1296         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1297
1298       }
1299
1300       offset += 2; /* Skip Reserved */
1301
1302       /* Build display for: Data Compaction Mode */
1303
1304       DataCompactionMode = GSHORT(pd, offset);
1305
1306       if (tree) {
1307
1308         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
1309
1310       }
1311
1312       offset += 2; /* Skip Data Compaction Mode */
1313
1314       /* Build display for: Reserved */
1315
1316       Reserved = GSHORT(pd, offset);
1317
1318       if (tree) {
1319
1320         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
1321
1322       }
1323
1324       offset += 2; /* Skip Reserved */
1325
1326       /* Build display for: Data Length */
1327
1328       DataLength = GSHORT(pd, offset);
1329
1330       if (tree) {
1331
1332         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
1333
1334       }
1335
1336       offset += 2; /* Skip Data Length */
1337
1338       /* Build display for: Data Offset */
1339
1340       DataOffset = GSHORT(pd, offset);
1341
1342       if (tree) {
1343
1344         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
1345
1346       }
1347
1348       offset += 2; /* Skip Data Offset */
1349
1350     }
1351
1352     /* Build display for: Byte Count (BCC) */
1353
1354     ByteCount = GSHORT(pd, offset);
1355
1356     if (tree) {
1357
1358       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1359
1360     }
1361
1362     offset += 2; /* Skip Byte Count (BCC) */
1363
1364     /* Build display for: Pad */
1365
1366     Pad = GBYTE(pd, offset);
1367
1368     if (tree) {
1369
1370       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
1371
1372     }
1373
1374     offset += 1; /* Skip Pad */
1375
1376   }
1377
1378 }
1379
1380 void
1381 dissect_delete_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *paernt, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1382
1383 {
1384   guint8        WordCount;
1385   guint8        BufferFormat;
1386   guint16       ByteCount;
1387   const char    *FileName;
1388
1389   if (dirn == 1) { /* Request(s) dissect code */
1390
1391     /* Build display for: Word Count (WCT) */
1392
1393     WordCount = GBYTE(pd, offset);
1394
1395     if (tree) {
1396
1397       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1398
1399     }
1400
1401     offset += 1; /* Skip Word Count (WCT) */
1402
1403     /* Build display for: Byte Count (BCC) */
1404
1405     ByteCount = GSHORT(pd, offset);
1406
1407     if (tree) {
1408
1409       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1410
1411     }
1412
1413     offset += 2; /* Skip Byte Count (BCC) */
1414
1415     /* Build display for: Buffer Format */
1416
1417     BufferFormat = GBYTE(pd, offset);
1418
1419     if (tree) {
1420
1421       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
1422
1423     }
1424
1425     offset += 1; /* Skip Buffer Format */
1426
1427     /* Build display for: File Name */
1428
1429     FileName = pd + offset;
1430
1431     if (tree) {
1432
1433       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
1434
1435     }
1436
1437     offset += strlen(FileName) + 1; /* Skip File Name */
1438
1439   }
1440
1441   if (dirn == 0) { /* Response(s) dissect code */
1442
1443     /* Build display for: Word Count (WCT) */
1444
1445     WordCount = GBYTE(pd, offset);
1446
1447     if (tree) {
1448
1449       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1450
1451     }
1452
1453     offset += 1; /* Skip Word Count (WCT) */
1454
1455     /* Build display for: Byte Count (BCC) */
1456
1457     ByteCount = GSHORT(pd, offset);
1458
1459     if (tree) {
1460
1461       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1462
1463     }
1464
1465     offset += 2; /* Skip Byte Count (BCC) */
1466
1467   }
1468
1469 }
1470
1471 void
1472 dissect_query_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1473
1474 {
1475   proto_tree    *Attributes_tree;
1476   proto_item    *ti;
1477   guint8        WordCount;
1478   guint32       FileDataSize;
1479   guint32       FileAllocationSize;
1480   guint16       LastWriteTime;
1481   guint16       LastWriteDate;
1482   guint16       LastAccessTime;
1483   guint16       LastAccessDate;
1484   guint16       FID;
1485   guint16       CreationTime;
1486   guint16       CreationDate;
1487   guint16       ByteCount;
1488   guint16       Attributes;
1489
1490   if (dirn == 1) { /* Request(s) dissect code */
1491
1492     /* Build display for: Word Count (WCT) */
1493
1494     WordCount = GBYTE(pd, offset);
1495
1496     if (tree) {
1497
1498       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1499
1500     }
1501
1502     offset += 1; /* Skip Word Count (WCT) */
1503
1504     /* Build display for: FID */
1505
1506     FID = GSHORT(pd, offset);
1507
1508     if (tree) {
1509
1510       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
1511
1512     }
1513
1514     offset += 2; /* Skip FID */
1515
1516     /* Build display for: Byte Count */
1517
1518     ByteCount = GSHORT(pd, offset);
1519
1520     if (tree) {
1521
1522       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
1523
1524     }
1525
1526     offset += 2; /* Skip Byte Count */
1527
1528   }
1529
1530   if (dirn == 0) { /* Response(s) dissect code */
1531
1532     /* Build display for: Word Count (WCT) */
1533
1534     WordCount = GBYTE(pd, offset);
1535
1536     if (tree) {
1537
1538       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1539
1540     }
1541
1542     offset += 1; /* Skip Word Count (WCT) */
1543
1544     if (WordCount > 0) {
1545
1546       /* Build display for: Creation Date */
1547
1548       CreationDate = GSHORT(pd, offset);
1549
1550       if (tree) {
1551
1552         proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
1553
1554       }
1555
1556       offset += 2; /* Skip Creation Date */
1557
1558       /* Build display for: Creation Time */
1559
1560       CreationTime = GSHORT(pd, offset);
1561
1562       if (tree) {
1563
1564         proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
1565
1566       }
1567
1568       offset += 2; /* Skip Creation Time */
1569
1570       /* Build display for: Last Access Date */
1571
1572       LastAccessDate = GSHORT(pd, offset);
1573
1574       if (tree) {
1575
1576         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
1577
1578       }
1579
1580       offset += 2; /* Skip Last Access Date */
1581
1582       /* Build display for: Last Access Time */
1583
1584       LastAccessTime = GSHORT(pd, offset);
1585
1586       if (tree) {
1587
1588         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
1589
1590       }
1591
1592       offset += 2; /* Skip Last Access Time */
1593
1594       /* Build display for: Last Write Date */
1595
1596       LastWriteDate = GSHORT(pd, offset);
1597
1598       if (tree) {
1599
1600         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
1601
1602       }
1603
1604       offset += 2; /* Skip Last Write Date */
1605
1606       /* Build display for: Last Write Time */
1607
1608       LastWriteTime = GSHORT(pd, offset);
1609
1610       if (tree) {
1611
1612         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
1613
1614       }
1615
1616       offset += 2; /* Skip Last Write Time */
1617
1618       /* Build display for: File Data Size */
1619
1620       FileDataSize = GWORD(pd, offset);
1621
1622       if (tree) {
1623         
1624         proto_tree_add_text(tree, NullTVB, offset, 4, "File Data Size: %u", FileDataSize);
1625
1626       }
1627
1628       offset += 4; /* Skip File Data Size */
1629
1630       /* Build display for: File Allocation Size */
1631
1632       FileAllocationSize = GWORD(pd, offset);
1633
1634       if (tree) {
1635
1636         proto_tree_add_text(tree, NullTVB, offset, 4, "File Allocation Size: %u", FileAllocationSize);
1637
1638       }
1639
1640       offset += 4; /* Skip File Allocation Size */
1641
1642       /* Build display for: Attributes */
1643
1644       Attributes = GSHORT(pd, offset);
1645       
1646       if (tree) {
1647
1648         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
1649         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
1650         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1651                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
1652         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1653                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
1654         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1655                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
1656         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1657                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
1658         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1659                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
1660         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
1661                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
1662     
1663       }
1664
1665       offset += 2; /* Skip Attributes */
1666
1667     }
1668
1669     /* Build display for: Byte Count */
1670
1671     ByteCount = GSHORT(pd, offset);
1672
1673     if (tree) {
1674
1675       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
1676
1677     }
1678
1679     offset += 2; /* Skip Byte Count */
1680
1681   }
1682
1683 }
1684
1685 void
1686 dissect_treecon_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1687
1688 {
1689   guint8        WordCount;
1690   guint8        BufferFormat3;
1691   guint8        BufferFormat2;
1692   guint8        BufferFormat1;
1693   guint16       TID;
1694   guint16       MaxBufferSize;
1695   guint16       ByteCount;
1696   const char    *SharePath;
1697   const char    *Service;
1698   const char    *Password;
1699
1700   if (dirn == 1) { /* Request(s) dissect code */
1701
1702     /* Build display for: Word Count (WCT) */
1703
1704     WordCount = GBYTE(pd, offset);
1705
1706     if (tree) {
1707
1708       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1709
1710     }
1711
1712     offset += 1; /* Skip Word Count (WCT) */
1713
1714     /* Build display for: Byte Count (BCC) */
1715
1716     ByteCount = GSHORT(pd, offset);
1717
1718     if (tree) {
1719
1720       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1721
1722     }
1723
1724     offset += 2; /* Skip Byte Count (BCC) */
1725
1726     /* Build display for: BufferFormat1 */
1727
1728     BufferFormat1 = GBYTE(pd, offset);
1729
1730     if (tree) {
1731
1732       proto_tree_add_text(tree, NullTVB, offset, 1, "BufferFormat1: %u", BufferFormat1);
1733
1734     }
1735
1736     offset += 1; /* Skip BufferFormat1 */
1737
1738     /* Build display for: Share Path */
1739
1740     SharePath = pd + offset;
1741
1742     if (tree) {
1743
1744       proto_tree_add_text(tree, NullTVB, offset, strlen(SharePath) + 1, "Share Path: %s", SharePath);
1745
1746     }
1747
1748     offset += strlen(SharePath) + 1; /* Skip Share Path */
1749
1750     /* Build display for: BufferFormat2 */
1751
1752     BufferFormat2 = GBYTE(pd, offset);
1753
1754     if (tree) {
1755
1756       proto_tree_add_text(tree, NullTVB, offset, 1, "BufferFormat2: %u", BufferFormat2);
1757
1758     }
1759
1760     offset += 1; /* Skip BufferFormat2 */
1761
1762     /* Build display for: Password */
1763
1764     Password = pd + offset;
1765
1766     if (tree) {
1767
1768       proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
1769
1770     }
1771
1772     offset += strlen(Password) + 1; /* Skip Password */
1773
1774     /* Build display for: BufferFormat3 */
1775
1776     BufferFormat3 = GBYTE(pd, offset);
1777
1778     if (tree) {
1779
1780       proto_tree_add_text(tree, NullTVB, offset, 1, "BufferFormat3: %u", BufferFormat3);
1781
1782     }
1783
1784     offset += 1; /* Skip BufferFormat3 */
1785
1786     /* Build display for: Service */
1787
1788     Service = pd + offset;
1789
1790     if (tree) {
1791
1792       proto_tree_add_text(tree, NullTVB, offset, strlen(Service) + 1, "Service: %s", Service);
1793
1794     }
1795
1796     offset += strlen(Service) + 1; /* Skip Service */
1797
1798   }
1799
1800   if (dirn == 0) { /* Response(s) dissect code */
1801
1802     /* Build display for: Word Count (WCT) */
1803
1804     WordCount = GBYTE(pd, offset);
1805
1806     if (tree) {
1807
1808       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1809
1810     }
1811
1812     if (errcode != 0) return;
1813
1814     offset += 1; /* Skip Word Count (WCT) */
1815
1816     /* Build display for: Max Buffer Size */
1817
1818     MaxBufferSize = GSHORT(pd, offset);
1819
1820     if (tree) {
1821
1822       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Buffer Size: %u", MaxBufferSize);
1823
1824     }
1825
1826     offset += 2; /* Skip Max Buffer Size */
1827
1828     /* Build display for: TID */
1829
1830     TID = GSHORT(pd, offset);
1831
1832     if (tree) {
1833
1834       proto_tree_add_text(tree, NullTVB, offset, 2, "TID: %u", TID);
1835
1836     }
1837
1838     offset += 2; /* Skip TID */
1839
1840     /* Build display for: Byte Count (BCC) */
1841
1842     ByteCount = GSHORT(pd, offset);
1843
1844     if (tree) {
1845
1846       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
1847
1848     }
1849
1850     offset += 2; /* Skip Byte Count (BCC) */
1851
1852   }
1853
1854 }
1855
1856 /* Generated by build-dissect.pl Vesion 0.6 27-Jun-1999, ACT */
1857 void
1858 dissect_ssetup_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
1859
1860 {
1861   proto_tree    *Capabilities_tree;
1862   proto_item    *ti;
1863   guint8        WordCount;
1864   guint8        AndXReserved;
1865   guint8        AndXCommand = 0xFF;
1866   guint32       SessionKey;
1867   guint32       Reserved;
1868   guint32       Capabilities;
1869   guint16       VcNumber;
1870   guint16       UNICODEAccountPasswordLength;
1871   guint16       PasswordLen;
1872   guint16       MaxMpxCount;
1873   guint16       MaxBufferSize;
1874   guint16       ByteCount;
1875   guint16       AndXOffset = 0;
1876   guint16       Action;
1877   guint16       ANSIAccountPasswordLength;
1878   const char    *UNICODEPassword;
1879   const char    *Password;
1880   const char    *PrimaryDomain;
1881   const char    *NativeOS;
1882   const char    *NativeLanManType;
1883   const char    *NativeLanMan;
1884   const char    *AccountName;
1885   const char    *ANSIPassword;
1886
1887   if (dirn == 1) { /* Request(s) dissect code */
1888
1889     WordCount = GBYTE(pd, offset);
1890
1891     switch (WordCount) {
1892
1893     case 10:
1894
1895       /* Build display for: Word Count (WCT) */
1896
1897       WordCount = GBYTE(pd, offset);
1898
1899       if (tree) {
1900
1901         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
1902
1903       }
1904
1905       offset += 1; /* Skip Word Count (WCT) */
1906
1907       /* Build display for: AndXCommand */
1908
1909       AndXCommand = GBYTE(pd, offset);
1910
1911       if (tree) {
1912
1913         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
1914                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
1915
1916       }
1917
1918       offset += 1; /* Skip AndXCommand */
1919
1920       /* Build display for: AndXReserved */
1921
1922       AndXReserved = GBYTE(pd, offset);
1923
1924       if (tree) {
1925
1926         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
1927
1928       }
1929
1930       offset += 1; /* Skip AndXReserved */
1931
1932       /* Build display for: AndXOffset */
1933
1934       AndXOffset = GSHORT(pd, offset);
1935
1936       if (tree) {
1937
1938         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
1939
1940       }
1941
1942       offset += 2; /* Skip AndXOffset */
1943
1944       /* Build display for: MaxBufferSize */
1945
1946       MaxBufferSize = GSHORT(pd, offset);
1947
1948       if (tree) {
1949
1950         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
1951
1952       }
1953
1954       offset += 2; /* Skip MaxBufferSize */
1955
1956       /* Build display for: MaxMpxCount */
1957
1958       MaxMpxCount = GSHORT(pd, offset);
1959
1960       if (tree) {
1961
1962         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
1963
1964       }
1965
1966       offset += 2; /* Skip MaxMpxCount */
1967
1968       /* Build display for: VcNumber */
1969
1970       VcNumber = GSHORT(pd, offset);
1971
1972       if (tree) {
1973
1974         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
1975
1976       }
1977
1978       offset += 2; /* Skip VcNumber */
1979
1980       /* Build display for: SessionKey */
1981
1982       SessionKey = GWORD(pd, offset);
1983
1984       if (tree) {
1985
1986         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
1987
1988       }
1989
1990       offset += 4; /* Skip SessionKey */
1991
1992       /* Build display for: PasswordLen */
1993
1994       PasswordLen = GSHORT(pd, offset);
1995
1996       if (tree) {
1997
1998         proto_tree_add_text(tree, NullTVB, offset, 2, "PasswordLen: %u", PasswordLen);
1999
2000       }
2001
2002       offset += 2; /* Skip PasswordLen */
2003
2004       /* Build display for: Reserved */
2005
2006       Reserved = GWORD(pd, offset);
2007
2008       if (tree) {
2009
2010         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2011
2012       }
2013
2014       offset += 4; /* Skip Reserved */
2015
2016       /* Build display for: Byte Count (BCC) */
2017
2018       ByteCount = GSHORT(pd, offset);
2019
2020       if (tree) {
2021
2022         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2023
2024       }
2025
2026       offset += 2; /* Skip Byte Count (BCC) */
2027
2028       if (ByteCount > 0) {
2029
2030         /* Build displat for: Password */
2031
2032         Password = pd + offset;
2033
2034         if (tree) {
2035
2036           proto_tree_add_text(tree, NullTVB, offset, strlen(Password) + 1, "Password: %s", Password);
2037
2038         }
2039
2040         offset += PasswordLen;
2041
2042         /* Build display for: AccountName */
2043
2044         AccountName = pd + offset;
2045
2046         if (tree) {
2047
2048           proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "AccountName: %s", AccountName);
2049
2050         }
2051
2052         offset += strlen(AccountName) + 1; /* Skip AccountName */
2053
2054         /* Build display for: PrimaryDomain */
2055
2056         PrimaryDomain = pd + offset;
2057
2058         if (tree) {
2059
2060           proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
2061
2062         }
2063
2064         offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
2065
2066         /* Build display for: NativeOS */
2067
2068         NativeOS = pd + offset;
2069
2070         if (tree) {
2071
2072           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
2073
2074         }
2075
2076         offset += strlen(NativeOS) + 1; /* Skip NativeOS */
2077
2078         /* Build display for: NativeLanMan */
2079
2080         NativeLanMan = pd + offset;
2081
2082         if (tree) {
2083
2084           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "Native Lan Manager: %s", NativeLanMan);
2085
2086         }
2087
2088         offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
2089
2090       }
2091
2092     break;
2093
2094     case 13:
2095
2096       /* Build display for: Word Count (WCT) */
2097
2098       WordCount = GBYTE(pd, offset);
2099
2100       if (tree) {
2101
2102         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2103
2104       }
2105
2106       offset += 1; /* Skip Word Count (WCT) */
2107
2108       /* Build display for: AndXCommand */
2109
2110       AndXCommand = GBYTE(pd, offset);
2111
2112       if (tree) {
2113
2114         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
2115                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
2116
2117       }
2118
2119       offset += 1; /* Skip AndXCommand */
2120
2121       /* Build display for: AndXReserved */
2122
2123       AndXReserved = GBYTE(pd, offset);
2124
2125       if (tree) {
2126
2127         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2128
2129       }
2130
2131       offset += 1; /* Skip AndXReserved */
2132
2133       /* Build display for: AndXOffset */
2134
2135       AndXOffset = GSHORT(pd, offset);
2136
2137       if (tree) {
2138
2139         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2140
2141       }
2142
2143       offset += 2; /* Skip AndXOffset */
2144
2145       /* Build display for: MaxBufferSize */
2146
2147       MaxBufferSize = GSHORT(pd, offset);
2148
2149       if (tree) {
2150
2151         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxBufferSize: %u", MaxBufferSize);
2152
2153       }
2154
2155       offset += 2; /* Skip MaxBufferSize */
2156
2157       /* Build display for: MaxMpxCount */
2158
2159       MaxMpxCount = GSHORT(pd, offset);
2160
2161       if (tree) {
2162
2163         proto_tree_add_text(tree, NullTVB, offset, 2, "MaxMpxCount: %u", MaxMpxCount);
2164
2165       }
2166
2167       offset += 2; /* Skip MaxMpxCount */
2168
2169       /* Build display for: VcNumber */
2170
2171       VcNumber = GSHORT(pd, offset);
2172
2173       if (tree) {
2174
2175         proto_tree_add_text(tree, NullTVB, offset, 2, "VcNumber: %u", VcNumber);
2176
2177       }
2178
2179       offset += 2; /* Skip VcNumber */
2180
2181       /* Build display for: SessionKey */
2182
2183       SessionKey = GWORD(pd, offset);
2184
2185       if (tree) {
2186
2187         proto_tree_add_text(tree, NullTVB, offset, 4, "SessionKey: %u", SessionKey);
2188
2189       }
2190
2191       offset += 4; /* Skip SessionKey */
2192
2193       /* Build display for: ANSI Account Password Length */
2194
2195       ANSIAccountPasswordLength = GSHORT(pd, offset);
2196
2197       if (tree) {
2198
2199         proto_tree_add_text(tree, NullTVB, offset, 2, "ANSI Account Password Length: %u", ANSIAccountPasswordLength);
2200
2201       }
2202
2203       offset += 2; /* Skip ANSI Account Password Length */
2204
2205       /* Build display for: UNICODE Account Password Length */
2206
2207       UNICODEAccountPasswordLength = GSHORT(pd, offset);
2208
2209       if (tree) {
2210
2211         proto_tree_add_text(tree, NullTVB, offset, 2, "UNICODE Account Password Length: %u", UNICODEAccountPasswordLength);
2212
2213       }
2214
2215       offset += 2; /* Skip UNICODE Account Password Length */
2216
2217       /* Build display for: Reserved */
2218
2219       Reserved = GWORD(pd, offset);
2220
2221       if (tree) {
2222
2223         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
2224
2225       }
2226
2227       offset += 4; /* Skip Reserved */
2228
2229       /* Build display for: Capabilities */
2230
2231       Capabilities = GWORD(pd, offset);
2232
2233       if (tree) {
2234
2235         ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%04x", Capabilities);
2236         Capabilities_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
2237         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2238                             decode_boolean_bitfield(Capabilities, 0x0001, 32, " Raw Mode supported", " Raw Mode not supported"));
2239         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2240                             decode_boolean_bitfield(Capabilities, 0x0002, 32, " Raw Mode supported", " MPX Mode not supported"));
2241         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2242                             decode_boolean_bitfield(Capabilities, 0x0004, 32," Unicode supported", " Unicode not supported"));
2243         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2244                             decode_boolean_bitfield(Capabilities, 0x0008, 32, " Large Files supported", " Large Files not supported"));
2245         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2246                             decode_boolean_bitfield(Capabilities, 0x0010, 32, " NT LM 0.12 SMBs supported", " NT LM 0.12 SMBs not supported"));
2247         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2248                             decode_boolean_bitfield(Capabilities, 0x0020, 32, " RPC Remote APIs supported", " RPC Remote APIs not supported"));
2249         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2250                             decode_boolean_bitfield(Capabilities, 0x0040, 32, " NT Status Codes supported", " NT Status Codes not supported"));
2251         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2252                             decode_boolean_bitfield(Capabilities, 0x0080, 32, " Level 2 OpLocks supported", " Level 2 OpLocks not supported"));
2253         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2254                             decode_boolean_bitfield(Capabilities, 0x0100, 32, " Lock&Read supported", " Lock&Read not supported"));
2255         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2256                             decode_boolean_bitfield(Capabilities, 0x0200, 32, " NT Find supported", " NT Find not supported"));
2257         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2258                             decode_boolean_bitfield(Capabilities, 0x1000, 32, " DFS supported", " DFS not supported"));
2259         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2260                             decode_boolean_bitfield(Capabilities, 0x4000, 32, " Large READX supported", " Large READX not supported"));
2261         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2262                             decode_boolean_bitfield(Capabilities, 0x8000, 32, " Large WRITEX supported", " Large WRITEX not supported"));
2263         proto_tree_add_text(Capabilities_tree, NullTVB, offset, 4, "%s",
2264                             decode_boolean_bitfield(Capabilities, 0x80000000, 32, " Extended Security Exchanges supported", " Extended Security Exchanges not supported"));
2265       
2266 }
2267
2268       offset += 4; /* Skip Capabilities */
2269
2270       /* Build display for: Byte Count */
2271
2272       ByteCount = GSHORT(pd, offset);
2273
2274       if (tree) {
2275
2276         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
2277
2278       }
2279
2280       offset += 2; /* Skip Byte Count */
2281
2282       if (ByteCount > 0) {
2283
2284         /* Build display for: ANSI Password */
2285
2286         ANSIPassword = pd + offset;
2287
2288         if (tree) {
2289
2290           proto_tree_add_text(tree, NullTVB, offset, ANSIAccountPasswordLength, "ANSI Password: %s", format_text(ANSIPassword, ANSIAccountPasswordLength));
2291
2292         }
2293
2294         offset += ANSIAccountPasswordLength; /* Skip ANSI Password */
2295         if (ANSIAccountPasswordLength == 0) offset++;  /* Add 1 */
2296
2297         /* Build display for: UNICODE Password */
2298
2299         UNICODEPassword = pd + offset;
2300
2301         if (UNICODEAccountPasswordLength > 0) {
2302
2303           if (tree) {
2304
2305             proto_tree_add_text(tree, NullTVB, offset, UNICODEAccountPasswordLength, "UNICODE Password: %s", format_text(UNICODEPassword, UNICODEAccountPasswordLength));
2306
2307           }
2308
2309           offset += UNICODEAccountPasswordLength; /* Skip UNICODE Password */
2310
2311         }
2312
2313         /* Build display for: Account Name */
2314
2315         AccountName = pd + offset;
2316
2317         if (tree) {
2318
2319           proto_tree_add_text(tree, NullTVB, offset, strlen(AccountName) + 1, "Account Name: %s", AccountName);
2320
2321         }
2322
2323         offset += strlen(AccountName) + 1; /* Skip Account Name */
2324
2325         /* Build display for: Primary Domain */
2326
2327         PrimaryDomain = pd + offset;
2328
2329         if (tree) {
2330
2331           proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "Primary Domain: %s", PrimaryDomain);
2332
2333         }
2334
2335         offset += strlen(PrimaryDomain) + 1; /* Skip Primary Domain */
2336
2337         /* Build display for: Native OS */
2338
2339         NativeOS = pd + offset;
2340
2341         if (tree) {
2342
2343           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
2344
2345         }
2346
2347         offset += strlen(NativeOS) + 1; /* Skip Native OS */
2348
2349         /* Build display for: Native LanMan Type */
2350
2351         NativeLanManType = pd + offset;
2352
2353         if (tree) {
2354
2355           proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanManType) + 1, "Native LanMan Type: %s", NativeLanManType);
2356
2357         }
2358
2359         offset += strlen(NativeLanManType) + 1; /* Skip Native LanMan Type */
2360
2361       }
2362
2363       break;
2364
2365     }
2366
2367
2368     if (AndXCommand != 0xFF) {
2369
2370       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
2371
2372     }
2373
2374   }
2375
2376   if (dirn == 0) { /* Response(s) dissect code */
2377
2378     /* Build display for: Word Count (WCT) */
2379
2380     WordCount = GBYTE(pd, offset);
2381
2382     if (tree) {
2383
2384       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
2385
2386     }
2387
2388     offset += 1; /* Skip Word Count (WCT) */
2389
2390     if (WordCount > 0) {
2391
2392       /* Build display for: AndXCommand */
2393
2394       AndXCommand = GBYTE(pd, offset);
2395
2396       if (tree) {
2397
2398         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
2399                             (AndXCommand == 0xFF ? "No futher commands" : decode_smb_name(AndXCommand)));
2400
2401       }
2402
2403       offset += 1; /* Skip AndXCommand */
2404
2405       /* Build display for: AndXReserved */
2406
2407       AndXReserved = GBYTE(pd, offset);
2408
2409       if (tree) {
2410
2411         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
2412
2413       }
2414
2415       offset += 1; /* Skip AndXReserved */
2416
2417       /* Build display for: AndXOffset */
2418
2419       AndXOffset = GSHORT(pd, offset);
2420
2421       if (tree) {
2422
2423         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
2424
2425       }
2426
2427
2428       offset += 2; /* Skip AndXOffset */
2429
2430       /* Build display for: Action */
2431
2432       Action = GSHORT(pd, offset);
2433
2434       if (tree) {
2435
2436         proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
2437
2438       }
2439
2440       offset += 2; /* Skip Action */
2441
2442     }
2443
2444     /* Build display for: Byte Count (BCC) */
2445
2446     ByteCount = GSHORT(pd, offset);
2447
2448     if (tree) {
2449
2450       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
2451
2452     }
2453
2454     if (errcode != 0 && WordCount == 0xFF) return;  /* No more here ... */
2455
2456     offset += 2; /* Skip Byte Count (BCC) */
2457
2458     if (ByteCount > 0) {
2459
2460       /* Build display for: NativeOS */
2461
2462       NativeOS = pd + offset;
2463
2464       if (tree) {
2465
2466         proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "NativeOS: %s", NativeOS);
2467
2468       }
2469
2470       offset += strlen(NativeOS) + 1; /* Skip NativeOS */
2471
2472       /* Build display for: NativeLanMan */
2473
2474       NativeLanMan = pd + offset;
2475
2476       if (tree) {
2477
2478         proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "NativeLanMan: %s", NativeLanMan);
2479
2480       }
2481
2482       offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
2483
2484       /* Build display for: PrimaryDomain */
2485
2486       PrimaryDomain = pd + offset;
2487
2488       if (tree) {
2489
2490         proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
2491
2492       }
2493
2494       offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
2495
2496     }
2497
2498     if (AndXCommand != 0xFF) {
2499
2500       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
2501
2502     }
2503
2504   }
2505
2506 }
2507
2508 void
2509 dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
2510
2511 {
2512   guint8      wct, andxcmd = 0xFF;
2513   guint16     andxoffs = 0, flags, passwdlen, bcc, optionsup;
2514   const char  *str;
2515   proto_tree  *flags_tree;
2516   proto_item  *ti;
2517
2518   wct = pd[offset];
2519
2520   /* Now figure out what format we are talking about, 2, 3, or 4 response
2521    * words ...
2522    */
2523
2524   if (!((dirn == 1) && (wct == 4)) && !((dirn == 0) && (wct == 2)) &&
2525       !((dirn == 0) && (wct == 3)) && !(wct == 0)) {
2526
2527     if (tree) {
2528
2529       proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);
2530
2531       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
2532
2533       return;
2534
2535     }
2536     
2537   }
2538
2539   if (tree) {
2540
2541     proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
2542
2543   }
2544
2545   offset += 1;
2546
2547   if (wct > 0) {
2548
2549     andxcmd = pd[offset];
2550
2551     if (tree) {
2552
2553       proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
2554                           (andxcmd == 0xFF) ? "No further commands":
2555                           decode_smb_name(andxcmd));
2556                 
2557       proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
2558
2559     }
2560
2561     offset += 2;
2562
2563     andxoffs = GSHORT(pd, offset);
2564
2565     if (tree) {
2566
2567       proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
2568
2569     }
2570
2571     offset += 2;
2572
2573   }
2574
2575   switch (wct) {
2576
2577   case 0:
2578
2579     bcc = GSHORT(pd, offset);
2580
2581     if (tree) {
2582
2583       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2584
2585     }
2586
2587     break;
2588
2589   case 4:
2590
2591     flags = GSHORT(pd, offset);
2592
2593     if (tree) {
2594
2595       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%02x", flags);
2596       flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
2597       proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s", 
2598                           decode_boolean_bitfield(flags, 0x01, 16,
2599                                                   "Disconnect TID",
2600                                                   "Don't disconnect TID"));
2601
2602     }
2603
2604     offset += 2;
2605
2606     passwdlen = GSHORT(pd, offset);
2607
2608     if (tree) {
2609
2610       proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
2611
2612     }
2613
2614     offset += 2;
2615
2616     bcc = GSHORT(pd, offset);
2617
2618     if (tree) {
2619
2620       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2621
2622     }
2623
2624     offset += 2;
2625
2626     str = pd + offset;
2627
2628     if (tree) {
2629
2630       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));
2631
2632     }
2633
2634     offset += passwdlen;
2635
2636     str = pd + offset;
2637
2638     if (tree) {
2639
2640       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Path: %s", str);
2641
2642     }
2643
2644     offset += strlen(str) + 1;
2645
2646     str = pd + offset;
2647
2648     if (tree) {
2649
2650       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
2651
2652     }
2653
2654     break;
2655
2656   case 2:
2657
2658     bcc = GSHORT(pd, offset);
2659
2660     if (tree) {
2661
2662       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2663
2664     }
2665
2666     offset += 2;
2667
2668     str = pd + offset;
2669
2670     if (tree) {
2671
2672       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
2673                           str);
2674
2675     }
2676
2677     offset += strlen(str) + 1;
2678
2679     break;
2680
2681   case 3:
2682
2683     optionsup = GSHORT(pd, offset);
2684
2685     if (tree) {  /* Should break out the bits */
2686
2687       proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x", 
2688                           optionsup);
2689
2690     }
2691
2692     offset += 2;
2693
2694     bcc = GSHORT(pd, offset);
2695
2696     if (tree) {
2697
2698       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2699
2700     }
2701
2702     offset += 2;
2703
2704     str = pd + offset;
2705
2706     if (tree) {
2707
2708       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
2709
2710     }
2711
2712     offset += strlen(str) + 1;
2713
2714     str = pd + offset;
2715
2716     if (tree) {
2717
2718       proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Native File System: %s", str);
2719
2720     }
2721
2722     offset += strlen(str) + 1;
2723
2724     
2725     break;
2726
2727   default:
2728         ; /* nothing */
2729         break;
2730   }
2731
2732   if (andxcmd != 0xFF) /* Process that next command ... ??? */
2733
2734     (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset, errcode, dirn);
2735
2736 }
2737
2738 void 
2739 dissect_negprot_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
2740 {
2741   guint8        wct, enckeylen;
2742   guint16       bcc, mode, rawmode, dialect;
2743   guint32       caps;
2744   proto_tree    *dialects = NULL, *mode_tree, *caps_tree, *rawmode_tree;
2745   proto_item    *ti;
2746   const char    *str;
2747   char          *ustr;
2748   int           ustr_len;
2749
2750   wct = pd[offset];    /* Should be 0, 1 or 13 or 17, I think */
2751
2752   if (!((wct == 0) && (dirn == 1)) && !((wct == 1) && (dirn == 0)) &&
2753       !((wct == 13) && (dirn == 0)) && !((wct == 17) && (dirn == 0))) {
2754     if (tree) {
2755
2756       proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid Negotiate Protocol format. WCT should be zero or 1 or 13 or 17 ..., not %u", wct);
2757
2758       proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
2759
2760       return;
2761     }
2762   }
2763
2764   if (tree) {
2765
2766     proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %d", wct);
2767
2768   }
2769
2770   if (dirn == 0 && errcode != 0) return;  /* No more info ... */
2771
2772   offset += 1; 
2773
2774   /* Now decode the various formats ... */
2775
2776   switch (wct) {
2777
2778   case 0:     /* A request */
2779
2780     bcc = GSHORT(pd, offset);
2781
2782     if (tree) {
2783
2784       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2785
2786     }
2787
2788     offset += 2;
2789
2790     if (tree) {
2791
2792       ti = proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Dialects");
2793       dialects = proto_item_add_subtree(ti, ett_smb_dialects);
2794
2795     }
2796
2797     while (IS_DATA_IN_FRAME(offset)) {
2798       const char *str;
2799
2800       if (tree) {
2801
2802         proto_tree_add_text(dialects, NullTVB, offset, 1, "Dialect Marker: %d", pd[offset]);
2803
2804       }
2805
2806       offset += 1;
2807
2808       str = pd + offset;
2809
2810       if (tree) {
2811
2812         proto_tree_add_text(dialects, NullTVB, offset, strlen(str)+1, "Dialect: %s", str);
2813
2814       }
2815
2816       offset += strlen(str) + 1;
2817
2818     }
2819     break;
2820
2821   case 1:     /* PC NETWORK PROGRAM 1.0 */
2822
2823     dialect = GSHORT(pd, offset);
2824
2825     if (tree) {  /* Hmmmm, what if none of the dialects is recognized */
2826
2827       if (dialect == 0xFFFF) { /* Server didn't like them dialects */
2828
2829         proto_tree_add_text(tree, NullTVB, offset, 2, "Supplied dialects not recognized");
2830
2831       }
2832       else {
2833
2834         proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, PC NETWORK PROTGRAM 1.0", dialect);
2835
2836       }
2837
2838     }
2839
2840     offset += 2;
2841
2842     bcc = GSHORT(pd, offset);
2843
2844     if (tree) {
2845
2846       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2847
2848     }
2849
2850     break;
2851
2852   case 13:    /* Greater than Core and up to and incl LANMAN2.1  */
2853
2854     if (tree) {
2855
2856       proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", GSHORT(pd, offset));
2857
2858     }
2859
2860     /* Much of this is similar to response 17 below */
2861
2862     offset += 2;
2863
2864     mode = GSHORT(pd, offset);
2865
2866     if (tree) {
2867
2868       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Security Mode: 0x%04x", mode);
2869       mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
2870       proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s",
2871                           decode_boolean_bitfield(mode, 0x0001, 16,
2872                                                   "Security  = User",
2873                                                   "Security  = Share"));
2874       proto_tree_add_text(mode_tree, NullTVB, offset, 2, "%s",
2875                           decode_boolean_bitfield(mode, 0x0002, 16,
2876                                                   "Passwords = Encrypted",
2877                                                   "Passwords = Plaintext"));
2878
2879     }
2880
2881     offset += 2;
2882
2883     if (tree) {
2884
2885       proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size:     %u", GSHORT(pd, offset));
2886
2887     }
2888
2889     offset += 2;
2890
2891     if (tree) {
2892
2893       proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
2894
2895     }
2896     
2897     offset += 2;
2898
2899     if (tree) {
2900
2901       proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs:             %u", GSHORT(pd, offset));
2902
2903     }
2904
2905     offset += 2;
2906
2907     rawmode = GSHORT(pd, offset);
2908
2909     if (tree) {
2910
2911       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Raw Mode: 0x%04x", rawmode);
2912       rawmode_tree = proto_item_add_subtree(ti, ett_smb_rawmode);
2913       proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s",
2914                           decode_boolean_bitfield(rawmode, 0x01, 16,
2915                                                   "Read Raw supported",
2916                                                   "Read Raw not supported"));
2917       proto_tree_add_text(rawmode_tree, NullTVB, offset, 2, "%s",
2918                           decode_boolean_bitfield(rawmode, 0x02, 16,
2919                                                   "Write Raw supported",
2920                                                   "Write Raw not supported"));
2921
2922     }
2923
2924     offset += 2;
2925
2926     if (tree) {
2927
2928       proto_tree_add_text(tree, NullTVB, offset, 4, "Session key:         %08x", GWORD(pd, offset));
2929
2930     }
2931
2932     offset += 4;
2933
2934     /* Now the server time, two short parameters ... */
2935
2936     if (tree) {
2937
2938       proto_tree_add_text(tree, NullTVB, offset, 2, "Server Time: %s",
2939                         dissect_dos_time(GSHORT(pd, offset)));
2940       proto_tree_add_text(tree, NullTVB, offset + 2, 2, "Server Date: %s",
2941                         dissect_dos_date(GSHORT(pd, offset + 2)));
2942
2943     }
2944
2945     offset += 4;
2946
2947     /* Server Time Zone, SHORT */
2948
2949     if (tree) {
2950
2951       proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
2952                           (signed)GSSHORT(pd, offset));
2953
2954     }
2955
2956     offset += 2;
2957
2958     /* Challenge Length */
2959
2960     enckeylen = GSHORT(pd, offset);
2961
2962     if (tree) {
2963
2964       proto_tree_add_text(tree, NullTVB, offset, 2, "Challenge Length: %u", enckeylen);
2965
2966     }
2967
2968     offset += 2;
2969
2970     if (tree) {
2971
2972       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u (MBZ)", GSHORT(pd, offset));
2973
2974     }
2975
2976     offset += 2;
2977
2978     bcc = GSHORT(pd, offset);
2979
2980     if (tree) {
2981
2982       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
2983
2984     }
2985
2986     offset += 2;
2987
2988     if (enckeylen) { /* only if non-zero key len */
2989
2990       str = pd + offset;
2991
2992       if (tree) {
2993
2994         proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge: %s",
2995                                 bytes_to_str(str, enckeylen));
2996       }
2997
2998       offset += enckeylen;
2999
3000     }
3001
3002     /* Primary Domain ... */
3003
3004     str = pd + offset;
3005
3006     if (tree) {
3007
3008       proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "Primary Domain: %s", str);
3009
3010     }
3011
3012     break;
3013
3014   case 17:    /* Greater than LANMAN2.1 */
3015
3016     if (tree) {
3017
3018       proto_tree_add_text(tree, NullTVB, offset, 2, "Dialect Index: %u, Greater than LANMAN2.1", GSHORT(pd, offset));
3019
3020     }
3021
3022     offset += 2;
3023
3024     mode = GBYTE(pd, offset);
3025
3026     if (tree) {
3027
3028       ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Security Mode: 0x%02x", mode);
3029       mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
3030       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3031                           decode_boolean_bitfield(mode, 0x01, 8,
3032                                                   "Security  = User",
3033                                                   "Security  = Share"));
3034       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3035                           decode_boolean_bitfield(mode, 0x02, 8,
3036                                                   "Passwords = Encrypted",
3037                                                   "Passwords = Plaintext"));
3038       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3039                           decode_boolean_bitfield(mode, 0x04, 8,
3040                                                   "Security signatures enabled",
3041                                                   "Security signatures not enabled"));
3042       proto_tree_add_text(mode_tree, NullTVB, offset, 1, "%s",
3043                           decode_boolean_bitfield(mode, 0x08, 8,
3044                                                   "Security signatures required",
3045                                                   "Security signatures not required"));
3046
3047     }
3048
3049     offset += 1;
3050
3051     if (tree) {
3052
3053       proto_tree_add_text(tree, NullTVB, offset, 2, "Max multiplex count: %u", GSHORT(pd, offset));
3054
3055     }
3056     
3057     offset += 2;
3058
3059     if (tree) {
3060
3061       proto_tree_add_text(tree, NullTVB, offset, 2, "Max vcs:             %u", GSHORT(pd, offset));
3062
3063     }
3064
3065     offset += 2;
3066
3067     if (tree) {
3068
3069       proto_tree_add_text(tree, NullTVB, offset, 2, "Max buffer size:     %u", GWORD(pd, offset));
3070
3071     }
3072
3073     offset += 4;
3074
3075     if (tree) {
3076
3077       proto_tree_add_text(tree, NullTVB, offset, 4, "Max raw size:        %u", GWORD(pd, offset));
3078
3079     }
3080
3081     offset += 4;
3082
3083     if (tree) {
3084
3085       proto_tree_add_text(tree, NullTVB, offset, 4, "Session key:         %08x", GWORD(pd, offset));
3086
3087     }
3088
3089     offset += 4;
3090
3091     caps = GWORD(pd, offset);
3092
3093     if (tree) {
3094
3095       ti = proto_tree_add_text(tree, NullTVB, offset, 4, "Capabilities: 0x%04x", caps);
3096       caps_tree = proto_item_add_subtree(ti, ett_smb_capabilities);
3097       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3098                           decode_boolean_bitfield(caps, 0x0001, 32,
3099                                                   "Raw Mode supported",
3100                                                   "Raw Mode not supported"));
3101       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3102                           decode_boolean_bitfield(caps, 0x0002, 32,
3103                                                   "MPX Mode supported",
3104                                                   "MPX Mode not supported"));
3105       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3106                           decode_boolean_bitfield(caps, 0x0004, 32,
3107                                                   "Unicode supported",
3108                                                   "Unicode not supported"));
3109       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3110                           decode_boolean_bitfield(caps, 0x0008, 32,
3111                                                   "Large files supported",
3112                                                   "Large files not supported"));
3113       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3114                           decode_boolean_bitfield(caps, 0x0010, 32, 
3115                                                   "NT LM 0.12 SMBs supported",
3116                                                   "NT LM 0.12 SMBs not supported"));
3117       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3118                           decode_boolean_bitfield(caps, 0x0020, 32,
3119                                                   "RPC remote APIs supported",
3120                                                   "RPC remote APIs not supported"));
3121       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3122                           decode_boolean_bitfield(caps, 0x0040, 32,
3123                                                   "NT status codes supported",
3124                                                   "NT status codes  not supported"));
3125       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3126                           decode_boolean_bitfield(caps, 0x0080, 32,
3127                                                   "Level 2 OpLocks supported",
3128                                                   "Level 2 OpLocks not supported"));
3129       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3130                           decode_boolean_bitfield(caps, 0x0100, 32,
3131                                                   "Lock&Read supported",
3132                                                   "Lock&Read not supported"));
3133       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3134                           decode_boolean_bitfield(caps, 0x0200, 32,
3135                                                   "NT Find supported",
3136                                                   "NT Find not supported"));
3137       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3138                           decode_boolean_bitfield(caps, 0x1000, 32,
3139                                                   "DFS supported",
3140                                                   "DFS not supported"));
3141       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3142                           decode_boolean_bitfield(caps, 0x4000, 32,
3143                                                   "Large READX supported",
3144                                                   "Large READX not supported"));
3145       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3146                           decode_boolean_bitfield(caps, 0x8000, 32,
3147                                                   "Large WRITEX supported",
3148                                                   "Large WRITEX not supported"));
3149       proto_tree_add_text(caps_tree, NullTVB, offset, 4, "%s",
3150                           decode_boolean_bitfield(caps, 0x80000000, 32,
3151                                                   "Extended security exchanges supported",
3152                                                   "Extended security exchanges not supported"));
3153     }
3154
3155     offset += 4;
3156
3157     /* Server time, 2 WORDS */
3158
3159     if (tree) {
3160
3161       proto_tree_add_text(tree, NullTVB, offset, 4, "System Time Low: 0x%08x", GWORD(pd, offset));
3162       proto_tree_add_text(tree, NullTVB, offset + 4, 4, "System Time High: 0x%08x", GWORD(pd, offset + 4)); 
3163
3164     }
3165
3166     offset += 8;
3167
3168     /* Server Time Zone, SHORT */
3169
3170     if (tree) {
3171
3172       proto_tree_add_text(tree, NullTVB, offset, 2, "Server time zone: %i min from UTC",
3173                           (signed)GSSHORT(pd, offset));
3174
3175     }
3176
3177     offset += 2;
3178
3179     /* Encryption key len */
3180
3181     enckeylen = pd[offset];
3182
3183     if (tree) {
3184
3185       proto_tree_add_text(tree, NullTVB, offset, 1, "Encryption key len: %u", enckeylen);
3186
3187     }
3188
3189     offset += 1;
3190
3191     bcc = GSHORT(pd, offset);
3192
3193     if (tree) {
3194
3195       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte count (BCC): %u", bcc);
3196
3197     }
3198
3199     offset += 2;
3200
3201     if (enckeylen) { /* only if non-zero key len */
3202
3203       /* Encryption challenge key */
3204
3205       str = pd + offset;
3206
3207       if (tree) {
3208
3209         proto_tree_add_text(tree, NullTVB, offset, enckeylen, "Challenge encryption key: %s",
3210                                 bytes_to_str(str, enckeylen));
3211
3212       }
3213
3214       offset += enckeylen;
3215
3216     }
3217
3218     /* The domain, a null terminated string; Unicode if "caps" has
3219        the 0x0004 bit set, ASCII (OEM character set) otherwise.
3220        XXX - for now, we just handle the ISO 8859-1 subset of Unicode. */
3221
3222     str = pd + offset;
3223
3224     if (tree) {
3225
3226       if (caps & 0x0004) {
3227         ustr = unicode_to_str(str, &ustr_len);
3228         proto_tree_add_text(tree, NullTVB, offset, ustr_len+2, "OEM domain name: %s", ustr);
3229       } else {
3230         proto_tree_add_text(tree, NullTVB, offset, strlen(str)+1, "OEM domain name: %s", str);
3231       }
3232
3233     }
3234
3235     break;
3236
3237   default:    /* Baddd */
3238
3239     if (tree)
3240       proto_tree_add_text(tree, NullTVB, offset, 1, "Bad format, should never get here");
3241     return;
3242
3243   }
3244
3245 }
3246
3247 void
3248 dissect_deletedir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3249
3250 {
3251   guint8        WordCount;
3252   guint8        BufferFormat;
3253   guint16       ByteCount;
3254   const char    *DirectoryName;
3255
3256   if (dirn == 1) { /* Request(s) dissect code */
3257
3258     /* Build display for: Word Count (WCT) */
3259
3260     WordCount = GBYTE(pd, offset);
3261
3262     if (tree) {
3263
3264       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3265
3266     }
3267
3268     offset += 1; /* Skip Word Count (WCT) */
3269
3270     /* Build display for: Byte Count (BCC) */
3271
3272     ByteCount = GSHORT(pd, offset);
3273
3274     if (tree) {
3275
3276       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3277
3278     }
3279
3280     offset += 2; /* Skip Byte Count (BCC) */
3281
3282     /* Build display for: Buffer Format */
3283
3284     BufferFormat = GBYTE(pd, offset);
3285
3286     if (tree) {
3287
3288       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
3289
3290     }
3291
3292     offset += 1; /* Skip Buffer Format */
3293
3294     /* Build display for: Directory Name */
3295
3296     DirectoryName = pd + offset;
3297
3298     if (tree) {
3299
3300       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
3301
3302     }
3303
3304     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
3305
3306   }
3307
3308   if (dirn == 0) { /* Response(s) dissect code */
3309
3310     /* Build display for: Word Count (WCT) */
3311
3312     WordCount = GBYTE(pd, offset);
3313
3314     if (tree) {
3315
3316       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3317
3318     }
3319
3320     offset += 1; /* Skip Word Count (WCT) */
3321
3322     /* Build display for: Byte Count (BCC) */
3323
3324     ByteCount = GSHORT(pd, offset);
3325
3326     if (tree) {
3327
3328       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3329
3330     }
3331
3332     offset += 2; /* Skip Byte Count (BCC) */
3333
3334   }
3335
3336 }
3337
3338 void
3339 dissect_createdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3340
3341 {
3342   guint8        WordCount;
3343   guint8        BufferFormat;
3344   guint16       ByteCount;
3345   const char    *DirectoryName;
3346
3347   if (dirn == 1) { /* Request(s) dissect code */
3348
3349     /* Build display for: Word Count (WCT) */
3350
3351     WordCount = GBYTE(pd, offset);
3352
3353     if (tree) {
3354
3355       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3356
3357     }
3358
3359     offset += 1; /* Skip Word Count (WCT) */
3360
3361     /* Build display for: Byte Count (BCC) */
3362
3363     ByteCount = GSHORT(pd, offset);
3364
3365     if (tree) {
3366
3367       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3368
3369     }
3370
3371     offset += 2; /* Skip Byte Count (BCC) */
3372
3373     /* Build display for: Buffer Format */
3374
3375     BufferFormat = GBYTE(pd, offset);
3376
3377     if (tree) {
3378
3379       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
3380
3381     }
3382
3383     offset += 1; /* Skip Buffer Format */
3384
3385     /* Build display for: Directory Name */
3386
3387     DirectoryName = pd + offset;
3388
3389     if (tree) {
3390
3391       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
3392
3393     }
3394
3395     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
3396
3397   }
3398
3399   if (dirn == 0) { /* Response(s) dissect code */
3400
3401     /* Build display for: Word Count (WCT) */
3402
3403     WordCount = GBYTE(pd, offset);
3404
3405     if (tree) {
3406
3407       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3408
3409     }
3410
3411     offset += 1; /* Skip Word Count (WCT) */
3412
3413     /* Build display for: Byte Count (BCC) */
3414
3415     ByteCount = GSHORT(pd, offset);
3416
3417     if (tree) {
3418
3419       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3420
3421     }
3422
3423     offset += 2; /* Skip Byte Count (BCC) */
3424
3425   }
3426
3427 }
3428
3429 void
3430 dissect_checkdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3431
3432 {
3433   guint8        WordCount;
3434   guint8        BufferFormat;
3435   guint16       ByteCount;
3436   const char    *DirectoryName;
3437
3438   if (dirn == 1) { /* Request(s) dissect code */
3439
3440     /* Build display for: Word Count (WCT) */
3441
3442     WordCount = GBYTE(pd, offset);
3443
3444     if (tree) {
3445
3446       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3447
3448     }
3449
3450     offset += 1; /* Skip Word Count (WCT) */
3451
3452     /* Build display for: Byte Count (BCC) */
3453
3454     ByteCount = GSHORT(pd, offset);
3455
3456     if (tree) {
3457
3458       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3459
3460     }
3461
3462     offset += 2; /* Skip Byte Count (BCC) */
3463
3464     /* Build display for: Buffer Format */
3465
3466     BufferFormat = GBYTE(pd, offset);
3467
3468     if (tree) {
3469
3470       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
3471
3472     }
3473
3474     offset += 1; /* Skip Buffer Format */
3475
3476     /* Build display for: Directory Name */
3477
3478     DirectoryName = pd + offset;
3479
3480     if (tree) {
3481
3482       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
3483
3484     }
3485
3486     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
3487
3488   }
3489
3490   if (dirn == 0) { /* Response(s) dissect code */
3491
3492     /* Build display for: Word Count (WCT) */
3493
3494     WordCount = GBYTE(pd, offset);
3495
3496     if (tree) {
3497
3498       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3499
3500     }
3501
3502     offset += 1; /* Skip Word Count (WCT) */
3503
3504     /* Build display for: Byte Count (BCC) */
3505
3506     ByteCount = GSHORT(pd, offset);
3507
3508     if (tree) {
3509
3510       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
3511
3512     }
3513
3514     offset += 2; /* Skip Byte Count (BCC) */
3515
3516   }
3517
3518 }
3519
3520 void
3521 dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
3522
3523 {
3524   static const value_string OpenFunction_0x10[] = {
3525         { 0, "Fail if file does not exist"},
3526         { 16, "Create file if it does not exist"},
3527         { 0, NULL}
3528   };
3529   static const value_string OpenFunction_0x03[] = {
3530         { 0, "Fail if file exists"},
3531         { 1, "Open file if it exists"},
3532         { 2, "Truncate File if it exists"},
3533         { 0, NULL}
3534   };
3535   static const value_string FileType_0xFFFF[] = {
3536         { 0, "Disk file or directory"},
3537         { 1, "Named pipe in byte mode"},
3538         { 2, "Named pipe in message mode"},
3539         { 3, "Spooled printer"},
3540         { 0, NULL}
3541   };
3542   static const value_string DesiredAccess_0x70[] = {
3543         { 00, "Compatibility mode"},
3544         { 16, "Deny read/write/execute (exclusive)"},
3545         { 32, "Deny write"},
3546         { 48, "Deny read/execute"},
3547         { 64, "Deny none"},
3548         { 0, NULL}
3549   };
3550   static const value_string DesiredAccess_0x700[] = {
3551         { 0, "Locality of reference unknown"},
3552         { 256, "Mainly sequential access"},
3553         { 512, "Mainly random access"},
3554         { 768, "Random access with some locality"},
3555         {0, NULL}
3556   };
3557   static const value_string DesiredAccess_0x4000[] = {
3558         { 0, "Write through mode disabled"},
3559         { 16384, "Write through mode enabled"},
3560         {0, NULL}
3561   };
3562   static const value_string DesiredAccess_0x1000[] = {
3563         { 0, "Normal file (caching permitted)"},
3564         { 4096, "Do not cache this file"},
3565         {0, NULL}
3566   };
3567   static const value_string DesiredAccess_0x07[] = {
3568         { 0, "Open for reading"},
3569         { 1, "Open for writing"},
3570         { 2, "Open for reading and writing"},
3571         { 3, "Open for execute"},
3572         {0, NULL}
3573   };
3574   static const value_string Action_0x8000[] = {
3575         { 0, "File opened by another user (or mode not supported by server)"},
3576         { 32768, "File is opened only by this user at present"},
3577         {0, NULL}
3578   };
3579   static const value_string Action_0x0003[] = {
3580         { 0, "No action taken?"},
3581         { 1, "The file existed and was opened"},
3582         { 2, "The file did not exist but was created"},
3583         { 3, "The file existed and was truncated"},
3584         {0, NULL}
3585   };
3586   proto_tree    *Search_tree;
3587   proto_tree    *OpenFunction_tree;
3588   proto_tree    *Flags_tree;
3589   proto_tree    *File_tree;
3590   proto_tree    *FileType_tree;
3591   proto_tree    *FileAttributes_tree;
3592   proto_tree    *DesiredAccess_tree;
3593   proto_tree    *Action_tree;
3594   proto_item    *ti;
3595   guint8        WordCount;
3596   guint8        AndXReserved;
3597   guint8        AndXCommand = 0xFF;
3598   guint32       ServerFID;
3599   guint32       Reserved2;
3600   guint32       Reserved1;
3601   guint32       DataSize;
3602   guint32       AllocatedSize;
3603   guint16       Search;
3604   guint16       Reserved;
3605   guint16       OpenFunction;
3606   guint16       LastWriteTime;
3607   guint16       LastWriteDate;
3608   guint16       GrantedAccess;
3609   guint16       Flags;
3610   guint16       FileType;
3611   guint16       FileAttributes;
3612   guint16       File;
3613   guint16       FID;
3614   guint16       DeviceState;
3615   guint16       DesiredAccess;
3616   guint16       CreationTime;
3617   guint16       CreationDate;
3618   guint16       ByteCount;
3619   guint16       AndXOffset = 0;
3620   guint16       Action;
3621   const char    *FileName;
3622
3623   if (dirn == 1) { /* Request(s) dissect code */
3624
3625     /* Build display for: Word Count (WCT) */
3626
3627     WordCount = GBYTE(pd, offset);
3628
3629     if (tree) {
3630
3631       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3632
3633     }
3634
3635     offset += 1; /* Skip Word Count (WCT) */
3636
3637     /* Build display for: AndXCommand */
3638
3639     AndXCommand = GBYTE(pd, offset);
3640
3641     if (tree) {
3642
3643       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
3644                           (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
3645
3646     }
3647
3648     offset += 1; /* Skip AndXCommand */
3649
3650     /* Build display for: AndXReserved */
3651
3652     AndXReserved = GBYTE(pd, offset);
3653
3654     if (tree) {
3655
3656       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
3657
3658     }
3659
3660     offset += 1; /* Skip AndXReserved */
3661
3662     /* Build display for: AndXOffset */
3663
3664     AndXOffset = GSHORT(pd, offset);
3665
3666     if (tree) {
3667
3668       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
3669
3670     }
3671
3672     offset += 2; /* Skip AndXOffset */
3673
3674     /* Build display for: Flags */
3675
3676     Flags = GSHORT(pd, offset);
3677
3678     if (tree) {
3679
3680       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
3681       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
3682       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
3683                           decode_boolean_bitfield(Flags, 0x01, 16, "Dont Return Additional Info", "Return Additional Info"));
3684       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
3685                           decode_boolean_bitfield(Flags, 0x02, 16, "Exclusive OpLock not Requested", "Exclusive OpLock Requested"));
3686       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
3687                           decode_boolean_bitfield(Flags, 0x04, 16, "Batch OpLock not Requested", "Batch OpLock Requested"));
3688     
3689 }
3690
3691     offset += 2; /* Skip Flags */
3692
3693     /* Build display for: Desired Access */
3694
3695     DesiredAccess = GSHORT(pd, offset);
3696
3697     if (tree) {
3698
3699       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Desired Access: 0x%02x", DesiredAccess);
3700       DesiredAccess_tree = proto_item_add_subtree(ti, ett_smb_desiredaccess);
3701       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3702                           decode_enumerated_bitfield(DesiredAccess, 0x07, 16, DesiredAccess_0x07, "%s"));
3703       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3704                           decode_enumerated_bitfield(DesiredAccess, 0x70, 16, DesiredAccess_0x70, "%s"));
3705       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3706                           decode_enumerated_bitfield(DesiredAccess, 0x700, 16, DesiredAccess_0x700, "%s"));
3707       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3708                           decode_enumerated_bitfield(DesiredAccess, 0x1000, 16, DesiredAccess_0x1000, "%s"));
3709       proto_tree_add_text(DesiredAccess_tree, NullTVB, offset, 2, "%s",
3710                           decode_enumerated_bitfield(DesiredAccess, 0x4000, 16, DesiredAccess_0x4000, "%s"));
3711     
3712 }
3713
3714     offset += 2; /* Skip Desired Access */
3715
3716     /* Build display for: Search */
3717
3718     Search = GSHORT(pd, offset);
3719
3720     if (tree) {
3721
3722       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Search: 0x%02x", Search);
3723       Search_tree = proto_item_add_subtree(ti, ett_smb_search);
3724       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
3725                           decode_boolean_bitfield(Search, 0x01, 16, "Read only file", "Not a read only file"));
3726       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
3727                           decode_boolean_bitfield(Search, 0x02, 16, "Hidden file", "Not a hidden file"));
3728       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
3729                           decode_boolean_bitfield(Search, 0x04, 16, "System file", "Not a system file"));
3730       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
3731                           decode_boolean_bitfield(Search, 0x08, 16, " Volume", "Not a volume"));
3732       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
3733                           decode_boolean_bitfield(Search, 0x10, 16, " Directory", "Not a directory"));
3734       proto_tree_add_text(Search_tree, NullTVB, offset, 2, "%s",
3735                           decode_boolean_bitfield(Search, 0x20, 16, "Archive file", "Do not archive file"));
3736     
3737 }
3738
3739     offset += 2; /* Skip Search */
3740
3741     /* Build display for: File */
3742
3743     File = GSHORT(pd, offset);
3744
3745     if (tree) {
3746
3747       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File: 0x%02x", File);
3748       File_tree = proto_item_add_subtree(ti, ett_smb_file);
3749       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
3750                           decode_boolean_bitfield(File, 0x01, 16, "Read only file", "Not a read only file"));
3751       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
3752                           decode_boolean_bitfield(File, 0x02, 16, "Hidden file", "Not a hidden file"));
3753       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
3754                           decode_boolean_bitfield(File, 0x04, 16, "System file", "Not a system file"));
3755       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
3756                           decode_boolean_bitfield(File, 0x08, 16, " Volume", "Not a volume"));
3757       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
3758                           decode_boolean_bitfield(File, 0x10, 16, " Directory", "Not a directory"));
3759       proto_tree_add_text(File_tree, NullTVB, offset, 2, "%s",
3760                           decode_boolean_bitfield(File, 0x20, 16, "Archive file", "Do not archive file"));
3761     
3762 }
3763
3764     offset += 2; /* Skip File */
3765
3766     /* Build display for: Creation Time */
3767
3768     CreationTime = GSHORT(pd, offset);
3769
3770     if (tree) {
3771
3772
3773     }
3774
3775     offset += 2; /* Skip Creation Time */
3776
3777     /* Build display for: Creation Date */
3778
3779     CreationDate = GSHORT(pd, offset);
3780
3781     if (tree) {
3782
3783       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_smbu_date(CreationDate, CreationTime));
3784       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_smbu_time(CreationDate, CreationTime));
3785
3786     }
3787
3788     offset += 2; /* Skip Creation Date */
3789
3790     /* Build display for: Open Function */
3791
3792     OpenFunction = GSHORT(pd, offset);
3793
3794     if (tree) {
3795
3796       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: 0x%02x", OpenFunction);
3797       OpenFunction_tree = proto_item_add_subtree(ti, ett_smb_openfunction);
3798       proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
3799                           decode_enumerated_bitfield(OpenFunction, 0x10, 16, OpenFunction_0x10, "%s"));
3800       proto_tree_add_text(OpenFunction_tree, NullTVB, offset, 2, "%s",
3801                           decode_enumerated_bitfield(OpenFunction, 0x03, 16, OpenFunction_0x03, "%s"));
3802     
3803 }
3804
3805     offset += 2; /* Skip Open Function */
3806
3807     /* Build display for: Allocated Size */
3808
3809     AllocatedSize = GWORD(pd, offset);
3810
3811     if (tree) {
3812
3813       proto_tree_add_text(tree, NullTVB, offset, 4, "Allocated Size: %u", AllocatedSize);
3814
3815     }
3816
3817     offset += 4; /* Skip Allocated Size */
3818
3819     /* Build display for: Reserved1 */
3820
3821     Reserved1 = GWORD(pd, offset);
3822
3823     if (tree) {
3824
3825       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved1: %u", Reserved1);
3826
3827     }
3828
3829     offset += 4; /* Skip Reserved1 */
3830
3831     /* Build display for: Reserved2 */
3832
3833     Reserved2 = GWORD(pd, offset);
3834
3835     if (tree) {
3836
3837       proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved2: %u", Reserved2);
3838
3839     }
3840
3841     offset += 4; /* Skip Reserved2 */
3842
3843     /* Build display for: Byte Count */
3844
3845     ByteCount = GSHORT(pd, offset);
3846
3847     if (tree) {
3848
3849       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
3850
3851     }
3852
3853     offset += 2; /* Skip Byte Count */
3854
3855     /* Build display for: File Name */
3856
3857     FileName = pd + offset;
3858
3859     if (tree) {
3860
3861       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
3862
3863     }
3864
3865     offset += strlen(FileName) + 1; /* Skip File Name */
3866
3867
3868     if (AndXCommand != 0xFF) {
3869
3870       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
3871
3872     }
3873
3874   }
3875
3876   if (dirn == 0) { /* Response(s) dissect code */
3877
3878     /* Build display for: Word Count (WCT) */
3879
3880     WordCount = GBYTE(pd, offset);
3881
3882     if (tree) {
3883
3884       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
3885
3886     }
3887
3888     offset += 1; /* Skip Word Count (WCT) */
3889
3890     if (WordCount > 0) {
3891
3892       /* Build display for: AndXCommand */
3893
3894       AndXCommand = GBYTE(pd, offset);
3895
3896       if (tree) {
3897
3898         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
3899                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
3900
3901       }
3902
3903       offset += 1; /* Skip AndXCommand */
3904
3905       /* Build display for: AndXReserved */
3906
3907       AndXReserved = GBYTE(pd, offset);
3908
3909       if (tree) {
3910
3911         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
3912
3913       }
3914
3915       offset += 1; /* Skip AndXReserved */
3916
3917       /* Build display for: AndXOffset */
3918
3919       AndXOffset = GSHORT(pd, offset);
3920
3921       if (tree) {
3922
3923         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
3924
3925       }
3926
3927       offset += 2; /* Skip AndXOffset */
3928
3929       /* Build display for: FID */
3930
3931       FID = GSHORT(pd, offset);
3932
3933       if (tree) {
3934
3935         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
3936
3937       }
3938
3939       offset += 2; /* Skip FID */
3940
3941       /* Build display for: FileAttributes */
3942
3943       FileAttributes = GSHORT(pd, offset);
3944
3945       if (tree) {
3946
3947         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "FileAttributes: 0x%02x", FileAttributes);
3948         FileAttributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
3949         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
3950                             decode_boolean_bitfield(FileAttributes, 0x01, 16, "Read only file", "Not a read only file"));
3951         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
3952                             decode_boolean_bitfield(FileAttributes, 0x02, 16, "Hidden file", "Not a hidden file"));
3953         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
3954                             decode_boolean_bitfield(FileAttributes, 0x04, 16, "System file", "Not a system file"));
3955         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
3956                             decode_boolean_bitfield(FileAttributes, 0x08, 16, " Volume", "Not a volume"));
3957         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
3958                             decode_boolean_bitfield(FileAttributes, 0x10, 16, " Directory", "Not a directory"));
3959         proto_tree_add_text(FileAttributes_tree, NullTVB, offset, 2, "%s",
3960                             decode_boolean_bitfield(FileAttributes, 0x20, 16, "Archive file", "Do not archive file"));
3961     
3962       }
3963
3964       offset += 2; /* Skip FileAttributes */
3965
3966       /* Build display for: Last Write Time */
3967
3968       LastWriteTime = GSHORT(pd, offset);
3969
3970       if (tree) {
3971
3972       }
3973
3974       offset += 2; /* Skip Last Write Time */
3975
3976       /* Build display for: Last Write Date */
3977
3978       LastWriteDate = GSHORT(pd, offset);
3979
3980       if (tree) {
3981
3982         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
3983         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
3984
3985
3986       }
3987
3988       offset += 2; /* Skip Last Write Date */
3989
3990       /* Build display for: Data Size */
3991
3992       DataSize = GWORD(pd, offset);
3993
3994       if (tree) {
3995
3996         proto_tree_add_text(tree, NullTVB, offset, 4, "Data Size: %u", DataSize);
3997
3998       }
3999
4000       offset += 4; /* Skip Data Size */
4001
4002       /* Build display for: Granted Access */
4003
4004       GrantedAccess = GSHORT(pd, offset);
4005
4006       if (tree) {
4007
4008         proto_tree_add_text(tree, NullTVB, offset, 2, "Granted Access: %u", GrantedAccess);
4009
4010       }
4011
4012       offset += 2; /* Skip Granted Access */
4013
4014       /* Build display for: File Type */
4015
4016       FileType = GSHORT(pd, offset);
4017
4018       if (tree) {
4019
4020         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "File Type: 0x%02x", FileType);
4021         FileType_tree = proto_item_add_subtree(ti, ett_smb_filetype);
4022         proto_tree_add_text(FileType_tree, NullTVB, offset, 2, "%s",
4023                           decode_enumerated_bitfield(FileType, 0xFFFF, 16, FileType_0xFFFF, "%s"));
4024     
4025       }
4026
4027       offset += 2; /* Skip File Type */
4028
4029       /* Build display for: Device State */
4030
4031       DeviceState = GSHORT(pd, offset);
4032
4033       if (tree) {
4034
4035         proto_tree_add_text(tree, NullTVB, offset, 2, "Device State: %u", DeviceState);
4036
4037       }
4038
4039       offset += 2; /* Skip Device State */
4040
4041       /* Build display for: Action */
4042
4043       Action = GSHORT(pd, offset);
4044
4045       if (tree) {
4046
4047         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Action: 0x%02x", Action);
4048         Action_tree = proto_item_add_subtree(ti, ett_smb_action);
4049         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
4050                             decode_enumerated_bitfield(Action, 0x8000, 16, Action_0x8000, "%s"));
4051         proto_tree_add_text(Action_tree, NullTVB, offset, 2, "%s",
4052                             decode_enumerated_bitfield(Action, 0x0003, 16, Action_0x0003, "%s"));
4053         
4054       }
4055       
4056       offset += 2; /* Skip Action */
4057
4058       /* Build display for: Server FID */
4059       
4060       ServerFID = GWORD(pd, offset);
4061
4062       if (tree) {
4063
4064         proto_tree_add_text(tree, NullTVB, offset, 4, "Server FID: %u", ServerFID);
4065
4066       }
4067
4068       offset += 4; /* Skip Server FID */
4069
4070       /* Build display for: Reserved */
4071
4072       Reserved = GSHORT(pd, offset);
4073
4074       if (tree) {
4075         
4076         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
4077
4078       }
4079
4080       offset += 2; /* Skip Reserved */
4081
4082     }
4083
4084     /* Build display for: Byte Count */
4085
4086     ByteCount = GSHORT(pd, offset);
4087
4088     if (tree) {
4089
4090       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4091
4092     }
4093
4094     offset += 2; /* Skip Byte Count */
4095
4096
4097     if (AndXCommand != 0xFF) {
4098
4099       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
4100
4101     }
4102
4103   }
4104
4105 }
4106
4107 void
4108 dissect_write_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4109
4110 {
4111   proto_tree    *WriteMode_tree;
4112   proto_item    *ti;
4113   guint8        WordCount;
4114   guint8        Pad;
4115   guint32       Timeout;
4116   guint32       Reserved2;
4117   guint32       Offset;
4118   guint16       WriteMode;
4119   guint16       Reserved1;
4120   guint16       Remaining;
4121   guint16       FID;
4122   guint16       DataOffset;
4123   guint16       DataLength;
4124   guint16       Count;
4125   guint16       ByteCount;
4126
4127   if (dirn == 1) { /* Request(s) dissect code */
4128
4129     WordCount = GBYTE(pd, offset);
4130
4131     switch (WordCount) {
4132
4133     case 12:
4134
4135       /* Build display for: Word Count (WCT) */
4136
4137       WordCount = GBYTE(pd, offset);
4138
4139       if (tree) {
4140
4141         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4142
4143       }
4144
4145       offset += 1; /* Skip Word Count (WCT) */
4146
4147       /* Build display for: FID */
4148
4149       FID = GSHORT(pd, offset);
4150
4151       if (tree) {
4152
4153         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4154
4155       }
4156
4157       offset += 2; /* Skip FID */
4158
4159       /* Build display for: Count */
4160
4161       Count = GSHORT(pd, offset);
4162
4163       if (tree) {
4164
4165         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
4166
4167       }
4168
4169       offset += 2; /* Skip Count */
4170
4171       /* Build display for: Reserved 1 */
4172
4173       Reserved1 = GSHORT(pd, offset);
4174
4175       if (tree) {
4176
4177         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
4178
4179       }
4180
4181       offset += 2; /* Skip Reserved 1 */
4182
4183       /* Build display for: Offset */
4184
4185       Offset = GWORD(pd, offset);
4186
4187       if (tree) {
4188
4189         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
4190
4191       }
4192
4193       offset += 4; /* Skip Offset */
4194
4195       /* Build display for: Timeout */
4196
4197       Timeout = GWORD(pd, offset);
4198
4199       if (tree) {
4200
4201         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
4202
4203       }
4204
4205       offset += 4; /* Skip Timeout */
4206
4207       /* Build display for: WriteMode */
4208
4209       WriteMode = GSHORT(pd, offset);
4210
4211       if (tree) {
4212
4213         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
4214         WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
4215         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4216                             decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
4217         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4218                             decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
4219       
4220 }
4221
4222       offset += 2; /* Skip WriteMode */
4223
4224       /* Build display for: Reserved 2 */
4225
4226       Reserved2 = GWORD(pd, offset);
4227
4228       if (tree) {
4229
4230         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
4231
4232       }
4233
4234       offset += 4; /* Skip Reserved 2 */
4235
4236       /* Build display for: Data Length */
4237
4238       DataLength = GSHORT(pd, offset);
4239
4240       if (tree) {
4241
4242         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
4243
4244       }
4245
4246       offset += 2; /* Skip Data Length */
4247
4248       /* Build display for: Data Offset */
4249
4250       DataOffset = GSHORT(pd, offset);
4251
4252       if (tree) {
4253
4254         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
4255
4256       }
4257
4258       offset += 2; /* Skip Data Offset */
4259
4260       /* Build display for: Byte Count (BCC) */
4261
4262       ByteCount = GSHORT(pd, offset);
4263
4264       if (tree) {
4265
4266         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4267
4268       }
4269
4270       offset += 2; /* Skip Byte Count (BCC) */
4271
4272       /* Build display for: Pad */
4273
4274       Pad = GBYTE(pd, offset);
4275
4276       if (tree) {
4277
4278         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
4279
4280       }
4281
4282       offset += 1; /* Skip Pad */
4283
4284     break;
4285
4286     case 14:
4287
4288       /* Build display for: Word Count (WCT) */
4289
4290       WordCount = GBYTE(pd, offset);
4291
4292       if (tree) {
4293
4294         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4295
4296       }
4297
4298       offset += 1; /* Skip Word Count (WCT) */
4299
4300       /* Build display for: FID */
4301
4302       FID = GSHORT(pd, offset);
4303
4304       if (tree) {
4305
4306         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4307
4308       }
4309
4310       offset += 2; /* Skip FID */
4311
4312       /* Build display for: Count */
4313
4314       Count = GSHORT(pd, offset);
4315
4316       if (tree) {
4317
4318         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
4319
4320       }
4321
4322       offset += 2; /* Skip Count */
4323
4324       /* Build display for: Reserved 1 */
4325
4326       Reserved1 = GSHORT(pd, offset);
4327
4328       if (tree) {
4329
4330         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
4331
4332       }
4333
4334       offset += 2; /* Skip Reserved 1 */
4335
4336       /* Build display for: Timeout */
4337
4338       Timeout = GWORD(pd, offset);
4339
4340       if (tree) {
4341
4342         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
4343
4344       }
4345
4346       offset += 4; /* Skip Timeout */
4347
4348       /* Build display for: WriteMode */
4349
4350       WriteMode = GSHORT(pd, offset);
4351
4352       if (tree) {
4353
4354         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
4355         WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
4356         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4357                             decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
4358         proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
4359                             decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining (pipe/dev)", "Dont return Remaining (pipe/dev)"));
4360       
4361 }
4362
4363       offset += 2; /* Skip WriteMode */
4364
4365       /* Build display for: Reserved 2 */
4366
4367       Reserved2 = GWORD(pd, offset);
4368
4369       if (tree) {
4370
4371         proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved 2: %u", Reserved2);
4372
4373       }
4374
4375       offset += 4; /* Skip Reserved 2 */
4376
4377       /* Build display for: Data Length */
4378
4379       DataLength = GSHORT(pd, offset);
4380
4381       if (tree) {
4382
4383         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
4384
4385       }
4386
4387       offset += 2; /* Skip Data Length */
4388
4389       /* Build display for: Data Offset */
4390
4391       DataOffset = GSHORT(pd, offset);
4392
4393       if (tree) {
4394
4395         proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
4396
4397       }
4398
4399       offset += 2; /* Skip Data Offset */
4400
4401       /* Build display for: Byte Count (BCC) */
4402
4403       ByteCount = GSHORT(pd, offset);
4404
4405       if (tree) {
4406
4407         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4408
4409       }
4410
4411       offset += 2; /* Skip Byte Count (BCC) */
4412
4413       /* Build display for: Pad */
4414
4415       Pad = GBYTE(pd, offset);
4416
4417       if (tree) {
4418
4419         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
4420
4421       }
4422
4423       offset += 1; /* Skip Pad */
4424
4425     break;
4426
4427     }
4428
4429   }
4430
4431   if (dirn == 0) { /* Response(s) dissect code */
4432
4433     /* Build display for: Word Count (WCT) */
4434
4435     WordCount = GBYTE(pd, offset);
4436
4437     if (tree) {
4438
4439       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4440
4441     }
4442
4443     offset += 1; /* Skip Word Count (WCT) */
4444
4445     if (WordCount > 0) {
4446
4447       /* Build display for: Remaining */
4448
4449       Remaining = GSHORT(pd, offset);
4450
4451       if (tree) {
4452
4453         proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
4454
4455       }
4456
4457       offset += 2; /* Skip Remaining */
4458
4459     }
4460
4461     /* Build display for: Byte Count */
4462
4463     ByteCount = GSHORT(pd, offset);
4464
4465     if (tree) {
4466
4467       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4468
4469     }
4470
4471     offset += 2; /* Skip Byte Count */
4472
4473   }
4474
4475 }
4476
4477 void
4478 dissect_tdis_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4479
4480 {
4481   guint8        WordCount;
4482   guint16       ByteCount;
4483
4484   if (dirn == 1) { /* Request(s) dissect code */
4485
4486     /* Build display for: Word Count (WCT) */
4487
4488     WordCount = GBYTE(pd, offset);
4489
4490     if (tree) {
4491
4492       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4493
4494     }
4495
4496     offset += 1; /* Skip Word Count (WCT) */
4497
4498     /* Build display for: Byte Count (BCC) */
4499
4500     ByteCount = GSHORT(pd, offset);
4501
4502     if (tree) {
4503
4504       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4505
4506     }
4507
4508     offset += 2; /* Skip Byte Count (BCC) */
4509
4510   }
4511
4512   if (dirn == 0) { /* Response(s) dissect code */
4513
4514     /* Build display for: Word Count (WCT) */
4515
4516     WordCount = GBYTE(pd, offset);
4517
4518     if (tree) {
4519
4520       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4521
4522     }
4523
4524     offset += 1; /* Skip Word Count (WCT) */
4525
4526     /* Build display for: Byte Count (BCC) */
4527
4528     ByteCount = GSHORT(pd, offset);
4529
4530     if (tree) {
4531
4532       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4533
4534     }
4535
4536     offset += 2; /* Skip Byte Count (BCC) */
4537
4538   }
4539
4540 }
4541
4542 void
4543 dissect_move_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4544
4545 {
4546   static const value_string Flags_0x03[] = {
4547         { 0, "Target must be a file"},
4548         { 1, "Target must be a directory"},
4549         { 2, "Reserved"},
4550         { 3, "Reserved"},
4551         { 4, "Verify all writes"},
4552         { 0, NULL}
4553 };
4554   proto_tree    *Flags_tree;
4555   proto_item    *ti;
4556   guint8        WordCount;
4557   guint8        ErrorFileFormat;
4558   guint16       TID2;
4559   guint16       OpenFunction;
4560   guint16       Flags;
4561   guint16       Count;
4562   guint16       ByteCount;
4563   const char    *ErrorFileName;
4564
4565   if (dirn == 1) { /* Request(s) dissect code */
4566
4567     /* Build display for: Word Count (WCT) */
4568
4569     WordCount = GBYTE(pd, offset);
4570
4571     if (tree) {
4572
4573       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4574
4575     }
4576
4577     offset += 1; /* Skip Word Count (WCT) */
4578
4579     /* Build display for: TID2 */
4580
4581     TID2 = GSHORT(pd, offset);
4582
4583     if (tree) {
4584
4585       proto_tree_add_text(tree, NullTVB, offset, 2, "TID2: %u", TID2);
4586
4587     }
4588
4589     offset += 2; /* Skip TID2 */
4590
4591     /* Build display for: Open Function */
4592
4593     OpenFunction = GSHORT(pd, offset);
4594
4595     if (tree) {
4596
4597       proto_tree_add_text(tree, NullTVB, offset, 2, "Open Function: %u", OpenFunction);
4598
4599     }
4600
4601     offset += 2; /* Skip Open Function */
4602
4603     /* Build display for: Flags */
4604
4605     Flags = GSHORT(pd, offset);
4606
4607     if (tree) {
4608
4609       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
4610       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
4611       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
4612                           decode_enumerated_bitfield(Flags, 0x03, 16, Flags_0x03, "%s"));
4613     
4614 }
4615
4616     offset += 2; /* Skip Flags */
4617
4618   }
4619
4620   if (dirn == 0) { /* Response(s) dissect code */
4621
4622     /* Build display for: Word Count (WCT) */
4623
4624     WordCount = GBYTE(pd, offset);
4625
4626     if (tree) {
4627
4628       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4629
4630     }
4631
4632     offset += 1; /* Skip Word Count (WCT) */
4633
4634     if (WordCount > 0) {
4635
4636       /* Build display for: Count */
4637
4638       Count = GSHORT(pd, offset);
4639
4640       if (tree) {
4641
4642         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
4643
4644       }
4645
4646       offset += 2; /* Skip Count */
4647
4648     }
4649
4650     /* Build display for: Byte Count */
4651
4652     ByteCount = GSHORT(pd, offset);
4653
4654     if (tree) {
4655
4656       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4657
4658     }
4659
4660     offset += 2; /* Skip Byte Count */
4661
4662     /* Build display for: Error File Format */
4663
4664     ErrorFileFormat = GBYTE(pd, offset);
4665
4666     if (tree) {
4667
4668       proto_tree_add_text(tree, NullTVB, offset, 1, "Error File Format: %u", ErrorFileFormat);
4669
4670     }
4671
4672     offset += 1; /* Skip Error File Format */
4673
4674     /* Build display for: Error File Name */
4675
4676     ErrorFileName = pd + offset;
4677
4678     if (tree) {
4679
4680       proto_tree_add_text(tree, NullTVB, offset, strlen(ErrorFileName) + 1, "Error File Name: %s", ErrorFileName);
4681
4682     }
4683
4684     offset += strlen(ErrorFileName) + 1; /* Skip Error File Name */
4685
4686   }
4687
4688 }
4689
4690 void
4691 dissect_rename_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4692
4693 {
4694   guint8        WordCount;
4695   guint8        BufferFormat2;
4696   guint8        BufferFormat1;
4697   guint16       SearchAttributes;
4698   guint16       ByteCount;
4699   const char    *OldFileName;
4700   const char    *NewFileName;
4701
4702   if (dirn == 1) { /* Request(s) dissect code */
4703
4704     /* Build display for: Word Count (WCT) */
4705
4706     WordCount = GBYTE(pd, offset);
4707
4708     if (tree) {
4709
4710       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4711
4712     }
4713
4714     offset += 1; /* Skip Word Count (WCT) */
4715
4716     /* Build display for: Search Attributes */
4717
4718     SearchAttributes = GSHORT(pd, offset);
4719
4720     if (tree) {
4721
4722       proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
4723
4724     }
4725
4726     offset += 2; /* Skip Search Attributes */
4727
4728     /* Build display for: Byte Count */
4729
4730     ByteCount = GSHORT(pd, offset);
4731
4732     if (tree) {
4733
4734       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
4735
4736     }
4737
4738     offset += 2; /* Skip Byte Count */
4739
4740     /* Build display for: Buffer Format 1 */
4741
4742     BufferFormat1 = GBYTE(pd, offset);
4743
4744     if (tree) {
4745
4746       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %u", BufferFormat1);
4747
4748     }
4749
4750     offset += 1; /* Skip Buffer Format 1 */
4751
4752     /* Build display for: Old File Name */
4753
4754     OldFileName = pd + offset;
4755
4756     if (tree) {
4757
4758       proto_tree_add_text(tree, NullTVB, offset, strlen(OldFileName) + 1, "Old File Name: %s", OldFileName);
4759
4760     }
4761
4762     offset += strlen(OldFileName) + 1; /* Skip Old File Name */
4763
4764     /* Build display for: Buffer Format 2 */
4765
4766     BufferFormat2 = GBYTE(pd, offset);
4767
4768     if (tree) {
4769
4770       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %u", BufferFormat2);
4771
4772     }
4773
4774     offset += 1; /* Skip Buffer Format 2 */
4775
4776     /* Build display for: New File Name */
4777
4778     NewFileName = pd + offset;
4779
4780     if (tree) {
4781
4782       proto_tree_add_text(tree, NullTVB, offset, strlen(NewFileName) + 1, "New File Name: %s", NewFileName);
4783
4784     }
4785
4786     offset += strlen(NewFileName) + 1; /* Skip New File Name */
4787
4788   }
4789
4790   if (dirn == 0) { /* Response(s) dissect code */
4791
4792     /* Build display for: Word Count (WCT) */
4793
4794     WordCount = GBYTE(pd, offset);
4795
4796     if (tree) {
4797
4798       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4799
4800     }
4801
4802     offset += 1; /* Skip Word Count (WCT) */
4803
4804     /* Build display for: Byte Count (BCC) */
4805
4806     ByteCount = GSHORT(pd, offset);
4807
4808     if (tree) {
4809
4810       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4811
4812     }
4813
4814     offset += 2; /* Skip Byte Count (BCC) */
4815
4816   }
4817
4818 }
4819
4820 void
4821 dissect_open_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4822
4823 {
4824   static const value_string Mode_0x03[] = {
4825         { 0, "Text mode (DOS expands TABs)"},
4826         { 1, "Graphics mode"},
4827         { 0, NULL}
4828 };
4829   proto_tree    *Mode_tree;
4830   proto_item    *ti;
4831   guint8        WordCount;
4832   guint8        BufferFormat;
4833   guint16       SetupLength;
4834   guint16       Mode;
4835   guint16       FID;
4836   guint16       ByteCount;
4837   const char    *IdentifierString;
4838
4839   if (dirn == 1) { /* Request(s) dissect code */
4840
4841     /* Build display for: Word Count (WCT) */
4842
4843     WordCount = GBYTE(pd, offset);
4844
4845     if (tree) {
4846
4847       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4848
4849     }
4850
4851     offset += 1; /* Skip Word Count (WCT) */
4852
4853     /* Build display for: Setup Length */
4854
4855     SetupLength = GSHORT(pd, offset);
4856
4857     if (tree) {
4858
4859       proto_tree_add_text(tree, NullTVB, offset, 2, "Setup Length: %u", SetupLength);
4860
4861     }
4862
4863     offset += 2; /* Skip Setup Length */
4864
4865     /* Build display for: Mode */
4866
4867     Mode = GSHORT(pd, offset);
4868
4869     if (tree) {
4870
4871       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
4872       Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
4873       proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
4874                           decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
4875     
4876 }
4877
4878     offset += 2; /* Skip Mode */
4879
4880     /* Build display for: Byte Count (BCC) */
4881
4882     ByteCount = GSHORT(pd, offset);
4883
4884     if (tree) {
4885
4886       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4887
4888     }
4889
4890     offset += 2; /* Skip Byte Count (BCC) */
4891
4892     /* Build display for: Buffer Format */
4893
4894     BufferFormat = GBYTE(pd, offset);
4895
4896     if (tree) {
4897
4898       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
4899
4900     }
4901
4902     offset += 1; /* Skip Buffer Format */
4903
4904     /* Build display for: Identifier String */
4905
4906     IdentifierString = pd + offset;
4907
4908     if (tree) {
4909
4910       proto_tree_add_text(tree, NullTVB, offset, strlen(IdentifierString) + 1, "Identifier String: %s", IdentifierString);
4911
4912     }
4913
4914     offset += strlen(IdentifierString) + 1; /* Skip Identifier String */
4915
4916   }
4917
4918   if (dirn == 0) { /* Response(s) dissect code */
4919
4920     /* Build display for: Word Count (WCT) */
4921
4922     WordCount = GBYTE(pd, offset);
4923
4924     if (tree) {
4925
4926       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4927
4928     }
4929
4930     offset += 1; /* Skip Word Count (WCT) */
4931
4932     /* Build display for: FID */
4933
4934     FID = GSHORT(pd, offset);
4935
4936     if (tree) {
4937
4938       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4939
4940     }
4941
4942     offset += 2; /* Skip FID */
4943
4944     /* Build display for: Byte Count (BCC) */
4945
4946     ByteCount = GSHORT(pd, offset);
4947
4948     if (tree) {
4949
4950       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
4951
4952     }
4953
4954     offset += 2; /* Skip Byte Count (BCC) */
4955
4956   }
4957
4958 }
4959
4960 void
4961 dissect_close_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
4962
4963 {
4964   guint8        WordCount;
4965   guint16       FID;
4966   guint16       ByteCount;
4967
4968   if (dirn == 1) { /* Request(s) dissect code */
4969
4970     /* Build display for: Word Count (WCT) */
4971
4972     WordCount = GBYTE(pd, offset);
4973
4974     if (tree) {
4975
4976       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
4977
4978     }
4979
4980     offset += 1; /* Skip Word Count (WCT) */
4981
4982     /* Build display for: FID */
4983
4984     FID = GSHORT(pd, offset);
4985
4986     if (tree) {
4987
4988       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
4989
4990     }
4991
4992     offset += 2; /* Skip FID */
4993
4994     /* Build display for: Byte Count (BCC) */
4995
4996     ByteCount = GSHORT(pd, offset);
4997
4998     if (tree) {
4999
5000       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5001
5002     }
5003
5004     offset += 2; /* Skip Byte Count (BCC) */
5005
5006   }
5007
5008   if (dirn == 0) { /* Response(s) dissect code */
5009
5010     /* Build display for: Word Count */
5011
5012     WordCount = GBYTE(pd, offset);
5013
5014     if (tree) {
5015
5016       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
5017
5018     }
5019
5020     offset += 1; /* Skip Word Count */
5021
5022     /* Build display for: Byte Count (BCC) */
5023
5024     ByteCount = GSHORT(pd, offset);
5025
5026     if (tree) {
5027
5028       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5029
5030     }
5031
5032     offset += 2; /* Skip Byte Count (BCC) */
5033
5034   }
5035
5036 }
5037
5038 void
5039 dissect_read_raw_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5040
5041 {
5042   guint8        WordCount;
5043   guint32       Timeout;
5044   guint32       OffsetHigh;
5045   guint32       Offset;
5046   guint16       Reserved;
5047   guint16       MinCount;
5048   guint16       MaxCount;
5049   guint16       FID;
5050   guint16       ByteCount;
5051
5052   if (dirn == 1) { /* Request(s) dissect code */
5053
5054     WordCount = GBYTE(pd, offset);
5055
5056     switch (WordCount) {
5057
5058     case 8:
5059
5060       /* Build display for: Word Count (WCT) */
5061
5062       WordCount = GBYTE(pd, offset);
5063
5064       if (tree) {
5065
5066         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5067
5068       }
5069
5070       offset += 1; /* Skip Word Count (WCT) */
5071
5072       /* Build display for: FID */
5073
5074       FID = GSHORT(pd, offset);
5075
5076       if (tree) {
5077
5078         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5079
5080       }
5081
5082       offset += 2; /* Skip FID */
5083
5084       /* Build display for: Offset */
5085
5086       Offset = GWORD(pd, offset);
5087
5088       if (tree) {
5089
5090         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5091
5092       }
5093
5094       offset += 4; /* Skip Offset */
5095
5096       /* Build display for: Max Count */
5097
5098       MaxCount = GSHORT(pd, offset);
5099
5100       if (tree) {
5101
5102         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
5103
5104       }
5105
5106       offset += 2; /* Skip Max Count */
5107
5108       /* Build display for: Min Count */
5109
5110       MinCount = GSHORT(pd, offset);
5111
5112       if (tree) {
5113
5114         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
5115
5116       }
5117
5118       offset += 2; /* Skip Min Count */
5119
5120       /* Build display for: Timeout */
5121
5122       Timeout = GWORD(pd, offset);
5123
5124       if (tree) {
5125
5126         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
5127
5128       }
5129
5130       offset += 4; /* Skip Timeout */
5131
5132       /* Build display for: Reserved */
5133
5134       Reserved = GSHORT(pd, offset);
5135
5136       if (tree) {
5137
5138         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
5139
5140       }
5141
5142       offset += 2; /* Skip Reserved */
5143
5144       /* Build display for: Byte Count (BCC) */
5145
5146       ByteCount = GSHORT(pd, offset);
5147
5148       if (tree) {
5149
5150         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5151
5152       }
5153
5154       offset += 2; /* Skip Byte Count (BCC) */
5155
5156     break;
5157
5158     case 10:
5159
5160       /* Build display for: Word Count (WCT) */
5161
5162       WordCount = GBYTE(pd, offset);
5163
5164       if (tree) {
5165
5166         proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5167
5168       }
5169
5170       offset += 1; /* Skip Word Count (WCT) */
5171
5172       /* Build display for: FID */
5173
5174       FID = GSHORT(pd, offset);
5175
5176       if (tree) {
5177
5178         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5179
5180       }
5181
5182       offset += 2; /* Skip FID */
5183
5184       /* Build display for: Offset */
5185
5186       Offset = GWORD(pd, offset);
5187
5188       if (tree) {
5189
5190         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5191
5192       }
5193
5194       offset += 4; /* Skip Offset */
5195
5196       /* Build display for: Max Count */
5197
5198       MaxCount = GSHORT(pd, offset);
5199
5200       if (tree) {
5201
5202         proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
5203
5204       }
5205
5206       offset += 2; /* Skip Max Count */
5207
5208       /* Build display for: Min Count */
5209
5210       MinCount = GSHORT(pd, offset);
5211
5212       if (tree) {
5213
5214         proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
5215
5216       }
5217
5218       offset += 2; /* Skip Min Count */
5219
5220       /* Build display for: Timeout */
5221
5222       Timeout = GWORD(pd, offset);
5223
5224       if (tree) {
5225
5226         proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
5227
5228       }
5229
5230       offset += 4; /* Skip Timeout */
5231
5232       /* Build display for: Reserved */
5233
5234       Reserved = GSHORT(pd, offset);
5235
5236       if (tree) {
5237
5238         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
5239
5240       }
5241
5242       offset += 2; /* Skip Reserved */
5243
5244       /* Build display for: Offset High */
5245
5246       OffsetHigh = GWORD(pd, offset);
5247
5248       if (tree) {
5249
5250         proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
5251
5252       }
5253
5254       offset += 4; /* Skip Offset High */
5255
5256       /* Build display for: Byte Count (BCC) */
5257
5258       ByteCount = GSHORT(pd, offset);
5259
5260       if (tree) {
5261
5262         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5263
5264       }
5265
5266       offset += 2; /* Skip Byte Count (BCC) */
5267
5268     break;
5269
5270     }
5271
5272   }
5273
5274   if (dirn == 0) { /* Response(s) dissect code */
5275
5276   }
5277
5278 }
5279
5280 void
5281 dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5282
5283 {
5284   guint8        WordCount;
5285   guint8        AndXReserved;
5286   guint8        AndXCommand = 0xFF;
5287   guint16       ByteCount;
5288   guint16       AndXOffset = 0;
5289
5290   if (dirn == 1) { /* Request(s) dissect code */
5291
5292     /* Build display for: Word Count (WCT) */
5293
5294     WordCount = GBYTE(pd, offset);
5295
5296     if (tree) {
5297
5298       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5299
5300     }
5301
5302     offset += 1; /* Skip Word Count (WCT) */
5303
5304     /* Build display for: AndXCommand */
5305
5306     AndXCommand = GBYTE(pd, offset);
5307
5308     if (tree) {
5309
5310       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
5311
5312     }
5313
5314     offset += 1; /* Skip AndXCommand */
5315
5316     /* Build display for: AndXReserved */
5317
5318     AndXReserved = GBYTE(pd, offset);
5319
5320     if (tree) {
5321
5322       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
5323
5324     }
5325
5326     offset += 1; /* Skip AndXReserved */
5327
5328     /* Build display for: AndXOffset */
5329
5330     AndXOffset = GSHORT(pd, offset);
5331
5332     if (tree) {
5333
5334       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
5335
5336     }
5337
5338     offset += 2; /* Skip AndXOffset */
5339
5340     /* Build display for: Byte Count (BCC) */
5341
5342     ByteCount = GSHORT(pd, offset);
5343
5344     if (tree) {
5345
5346       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5347
5348     }
5349
5350     offset += 2; /* Skip Byte Count (BCC) */
5351
5352
5353     if (AndXCommand != 0xFF) {
5354
5355       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
5356
5357     }
5358
5359   }
5360
5361   if (dirn == 0) { /* Response(s) dissect code */
5362
5363     /* Build display for: Word Count (WCT) */
5364
5365     WordCount = GBYTE(pd, offset);
5366
5367     if (tree) {
5368
5369       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5370
5371     }
5372
5373     offset += 1; /* Skip Word Count (WCT) */
5374
5375     /* Build display for: AndXCommand */
5376
5377     AndXCommand = GBYTE(pd, offset);
5378
5379     if (tree) {
5380
5381       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
5382
5383     }
5384
5385     offset += 1; /* Skip AndXCommand */
5386
5387     /* Build display for: AndXReserved */
5388
5389     AndXReserved = GBYTE(pd, offset);
5390
5391     if (tree) {
5392
5393       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
5394
5395     }
5396
5397     offset += 1; /* Skip AndXReserved */
5398
5399     /* Build display for: AndXOffset */
5400
5401     AndXOffset = GSHORT(pd, offset);
5402
5403     if (tree) {
5404
5405       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
5406
5407     }
5408
5409     offset += 2; /* Skip AndXOffset */
5410
5411     /* Build display for: Byte Count (BCC) */
5412
5413     ByteCount = GSHORT(pd, offset);
5414
5415     if (tree) {
5416
5417       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5418
5419     }
5420
5421     offset += 2; /* Skip Byte Count (BCC) */
5422
5423
5424     if (AndXCommand != 0xFF) {
5425
5426       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
5427
5428     }
5429
5430   }
5431
5432 }
5433
5434 void
5435 dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5436
5437 {
5438   static const value_string Mode_0x03[] = {
5439         { 0, "Seek from start of file"},
5440         { 1, "Seek from current position"},
5441         { 2, "Seek from end of file"},
5442         { 0, NULL}
5443 };
5444   proto_tree    *Mode_tree;
5445   proto_item    *ti;
5446   guint8        WordCount;
5447   guint32       Offset;
5448   guint16       Mode;
5449   guint16       FID;
5450   guint16       ByteCount;
5451
5452   if (dirn == 1) { /* Request(s) dissect code */
5453
5454     /* Build display for: Word Count (WCT) */
5455
5456     WordCount = GBYTE(pd, offset);
5457
5458     if (tree) {
5459
5460       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5461
5462     }
5463
5464     offset += 1; /* Skip Word Count (WCT) */
5465
5466     /* Build display for: FID */
5467
5468     FID = GSHORT(pd, offset);
5469
5470     if (tree) {
5471
5472       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5473
5474     }
5475
5476     offset += 2; /* Skip FID */
5477
5478     /* Build display for: Mode */
5479
5480     Mode = GSHORT(pd, offset);
5481
5482     if (tree) {
5483
5484       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
5485       Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
5486       proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
5487                           decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
5488     
5489 }
5490
5491     offset += 2; /* Skip Mode */
5492
5493     /* Build display for: Offset */
5494
5495     Offset = GWORD(pd, offset);
5496
5497     if (tree) {
5498
5499       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5500
5501     }
5502
5503     offset += 4; /* Skip Offset */
5504
5505     /* Build display for: Byte Count (BCC) */
5506
5507     ByteCount = GSHORT(pd, offset);
5508
5509     if (tree) {
5510
5511       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5512
5513     }
5514
5515     offset += 2; /* Skip Byte Count (BCC) */
5516
5517   }
5518
5519   if (dirn == 0) { /* Response(s) dissect code */
5520
5521     /* Build display for: Word Count (WCT) */
5522
5523     WordCount = GBYTE(pd, offset);
5524
5525     if (tree) {
5526
5527       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5528
5529     }
5530
5531     offset += 1; /* Skip Word Count (WCT) */
5532
5533     /* Build display for: Offset */
5534
5535     Offset = GWORD(pd, offset);
5536
5537     if (tree) {
5538
5539       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5540
5541     }
5542
5543     offset += 4; /* Skip Offset */
5544
5545     /* Build display for: Byte Count (BCC) */
5546
5547     ByteCount = GSHORT(pd, offset);
5548
5549     if (tree) {
5550
5551       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5552
5553     }
5554
5555     offset += 2; /* Skip Byte Count (BCC) */
5556
5557   }
5558
5559 }
5560
5561 void
5562 dissect_write_and_unlock_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5563
5564 {
5565   guint8        WordCount;
5566   guint8        BufferFormat;
5567   guint32       Offset;
5568   guint16       Remaining;
5569   guint16       FID;
5570   guint16       DataLength;
5571   guint16       Count;
5572   guint16       ByteCount;
5573
5574   if (dirn == 1) { /* Request(s) dissect code */
5575
5576     /* Build display for: Word Count (WCT) */
5577
5578     WordCount = GBYTE(pd, offset);
5579
5580     if (tree) {
5581
5582       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5583
5584     }
5585
5586     offset += 1; /* Skip Word Count (WCT) */
5587
5588     /* Build display for: FID */
5589
5590     FID = GSHORT(pd, offset);
5591
5592     if (tree) {
5593
5594       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5595
5596     }
5597
5598     offset += 2; /* Skip FID */
5599
5600     /* Build display for: Count */
5601
5602     Count = GSHORT(pd, offset);
5603
5604     if (tree) {
5605
5606       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
5607
5608     }
5609
5610     offset += 2; /* Skip Count */
5611
5612     /* Build display for: Offset */
5613
5614     Offset = GWORD(pd, offset);
5615
5616     if (tree) {
5617
5618       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5619
5620     }
5621
5622     offset += 4; /* Skip Offset */
5623
5624     /* Build display for: Remaining */
5625
5626     Remaining = GSHORT(pd, offset);
5627
5628     if (tree) {
5629
5630       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
5631
5632     }
5633
5634     offset += 2; /* Skip Remaining */
5635
5636     /* Build display for: Byte Count (BCC) */
5637
5638     ByteCount = GSHORT(pd, offset);
5639
5640     if (tree) {
5641
5642       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5643
5644     }
5645
5646     offset += 2; /* Skip Byte Count (BCC) */
5647
5648     /* Build display for: Buffer Format */
5649
5650     BufferFormat = GBYTE(pd, offset);
5651
5652     if (tree) {
5653
5654       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
5655
5656     }
5657
5658     offset += 1; /* Skip Buffer Format */
5659
5660     /* Build display for: Data Length */
5661
5662     DataLength = GSHORT(pd, offset);
5663
5664     if (tree) {
5665
5666       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
5667
5668     }
5669
5670     offset += 2; /* Skip Data Length */
5671
5672   }
5673
5674   if (dirn == 0) { /* Response(s) dissect code */
5675
5676     /* Build display for: Word Count (WCT) */
5677
5678     WordCount = GBYTE(pd, offset);
5679
5680     if (tree) {
5681
5682       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5683
5684     }
5685
5686     offset += 1; /* Skip Word Count (WCT) */
5687
5688     /* Build display for: Count */
5689
5690     Count = GSHORT(pd, offset);
5691
5692     if (tree) {
5693
5694       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
5695
5696     }
5697
5698     offset += 2; /* Skip Count */
5699
5700     /* Build display for: Byte Count (BCC) */
5701
5702     ByteCount = GSHORT(pd, offset);
5703
5704     if (tree) {
5705
5706       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5707
5708     }
5709
5710     offset += 2; /* Skip Byte Count (BCC) */
5711
5712   }
5713
5714 }
5715
5716 void
5717 dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5718
5719 {
5720   guint8        WordCount;
5721   guint16       LastWriteTime;
5722   guint16       LastWriteDate;
5723   guint16       LastAccessTime;
5724   guint16       LastAccessDate;
5725   guint16       FID;
5726   guint16       CreationTime;
5727   guint16       CreationDate;
5728   guint16       ByteCount;
5729
5730   if (dirn == 1) { /* Request(s) dissect code */
5731
5732     /* Build display for: Word Count */
5733
5734     WordCount = GBYTE(pd, offset);
5735
5736     if (tree) {
5737
5738       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
5739
5740     }
5741
5742     offset += 1; /* Skip Word Count */
5743
5744     /* Build display for: FID */
5745
5746     FID = GSHORT(pd, offset);
5747
5748     if (tree) {
5749
5750       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5751
5752     }
5753
5754     offset += 2; /* Skip FID */
5755
5756     /* Build display for: Creation Date */
5757
5758     CreationDate = GSHORT(pd, offset);
5759
5760     if (tree) {
5761
5762       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
5763
5764     }
5765
5766     offset += 2; /* Skip Creation Date */
5767
5768     /* Build display for: Creation Time */
5769
5770     CreationTime = GSHORT(pd, offset);
5771
5772     if (tree) {
5773
5774       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
5775
5776     }
5777
5778     offset += 2; /* Skip Creation Time */
5779
5780     /* Build display for: Last Access Date */
5781
5782     LastAccessDate = GSHORT(pd, offset);
5783
5784     if (tree) {
5785
5786       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
5787
5788     }
5789
5790     offset += 2; /* Skip Last Access Date */
5791
5792     /* Build display for: Last Access Time */
5793
5794     LastAccessTime = GSHORT(pd, offset);
5795
5796     if (tree) {
5797
5798       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
5799
5800     }
5801
5802     offset += 2; /* Skip Last Access Time */
5803
5804     /* Build display for: Last Write Date */
5805
5806     LastWriteDate = GSHORT(pd, offset);
5807
5808     if (tree) {
5809
5810       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
5811
5812     }
5813
5814     offset += 2; /* Skip Last Write Date */
5815
5816     /* Build display for: Last Write Time */
5817
5818     LastWriteTime = GSHORT(pd, offset);
5819
5820     if (tree) {
5821
5822       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
5823
5824     }
5825
5826     offset += 2; /* Skip Last Write Time */
5827
5828     /* Build display for: Byte Count (BCC) */
5829
5830     ByteCount = GSHORT(pd, offset);
5831
5832     if (tree) {
5833
5834       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5835
5836     }
5837
5838     offset += 2; /* Skip Byte Count (BCC) */
5839
5840   }
5841
5842   if (dirn == 0) { /* Response(s) dissect code */
5843
5844     /* Build display for: Word Count (WCC) */
5845
5846     WordCount = GBYTE(pd, offset);
5847
5848     if (tree) {
5849
5850       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);
5851
5852     }
5853
5854     offset += 1; /* Skip Word Count (WCC) */
5855
5856     /* Build display for: Byte Count (BCC) */
5857
5858     ByteCount = GSHORT(pd, offset);
5859
5860     if (tree) {
5861
5862       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5863
5864     }
5865
5866     offset += 2; /* Skip Byte Count (BCC) */
5867
5868   }
5869
5870 }
5871
5872 void
5873 dissect_lock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5874
5875 {
5876   guint8        WordCount;
5877   guint32       Offset;
5878   guint32       Count;
5879   guint16       FID;
5880   guint16       ByteCount;
5881
5882   if (dirn == 1) { /* Request(s) dissect code */
5883
5884     /* Build display for: Word Count (WCT) */
5885
5886     WordCount = GBYTE(pd, offset);
5887
5888     if (tree) {
5889
5890       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5891
5892     }
5893
5894     offset += 1; /* Skip Word Count (WCT) */
5895
5896     /* Build display for: FID */
5897
5898     FID = GSHORT(pd, offset);
5899
5900     if (tree) {
5901
5902       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
5903
5904     }
5905
5906     offset += 2; /* Skip FID */
5907
5908     /* Build display for: Count */
5909
5910     Count = GWORD(pd, offset);
5911
5912     if (tree) {
5913
5914       proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
5915
5916     }
5917
5918     offset += 4; /* Skip Count */
5919
5920     /* Build display for: Offset */
5921
5922     Offset = GWORD(pd, offset);
5923
5924     if (tree) {
5925
5926       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
5927
5928     }
5929
5930     offset += 4; /* Skip Offset */
5931
5932     /* Build display for: Byte Count (BCC) */
5933
5934     ByteCount = GSHORT(pd, offset);
5935
5936     if (tree) {
5937
5938       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5939
5940     }
5941
5942     offset += 2; /* Skip Byte Count (BCC) */
5943
5944   }
5945
5946   if (dirn == 0) { /* Response(s) dissect code */
5947
5948     /* Build display for: Word Count (WCT) */
5949
5950     WordCount = GBYTE(pd, offset);
5951
5952     if (tree) {
5953
5954       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
5955
5956     }
5957
5958     offset += 1; /* Skip Word Count (WCT) */
5959
5960     /* Build display for: Byte Count (BCC) */
5961
5962     ByteCount = GSHORT(pd, offset);
5963
5964     if (tree) {
5965
5966       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
5967
5968     }
5969
5970     offset += 2; /* Skip Byte Count (BCC) */
5971
5972   }
5973
5974 }
5975
5976 void
5977 dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
5978
5979 {
5980   guint8        WordCount;
5981   guint8        BufferFormat;
5982   guint16       StartIndex;
5983   guint16       RestartIndex;
5984   guint16       MaxCount;
5985   guint16       DataLength;
5986   guint16       Count;
5987   guint16       ByteCount;
5988
5989   if (dirn == 1) { /* Request(s) dissect code */
5990
5991     /* Build display for: Word Count */
5992
5993     WordCount = GBYTE(pd, offset);
5994
5995     if (tree) {
5996
5997       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);
5998
5999     }
6000
6001     offset += 1; /* Skip Word Count */
6002
6003     /* Build display for: Max Count */
6004
6005     MaxCount = GSHORT(pd, offset);
6006
6007     if (tree) {
6008
6009       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
6010
6011     }
6012
6013     offset += 2; /* Skip Max Count */
6014
6015     /* Build display for: Start Index */
6016
6017     StartIndex = GSHORT(pd, offset);
6018
6019     if (tree) {
6020
6021       proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex);
6022
6023     }
6024
6025     offset += 2; /* Skip Start Index */
6026
6027     /* Build display for: Byte Count (BCC) */
6028
6029     ByteCount = GSHORT(pd, offset);
6030
6031     if (tree) {
6032
6033       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6034
6035     }
6036
6037     offset += 2; /* Skip Byte Count (BCC) */
6038
6039   }
6040
6041   if (dirn == 0) { /* Response(s) dissect code */
6042
6043     /* Build display for: Word Count (WCT) */
6044
6045     WordCount = GBYTE(pd, offset);
6046
6047     if (tree) {
6048
6049       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6050
6051     }
6052
6053     offset += 1; /* Skip Word Count (WCT) */
6054
6055     if (WordCount > 0) {
6056
6057       /* Build display for: Count */
6058
6059       Count = GSHORT(pd, offset);
6060
6061       if (tree) {
6062
6063         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
6064
6065       }
6066
6067       offset += 2; /* Skip Count */
6068
6069       /* Build display for: Restart Index */
6070
6071       RestartIndex = GSHORT(pd, offset);
6072
6073       if (tree) {
6074
6075         proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);
6076
6077       }
6078
6079       offset += 2; /* Skip Restart Index */
6080
6081       /* Build display for: Byte Count (BCC) */
6082
6083     }
6084
6085     ByteCount = GSHORT(pd, offset);
6086
6087     if (tree) {
6088
6089       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6090
6091     }
6092
6093     offset += 2; /* Skip Byte Count (BCC) */
6094
6095     /* Build display for: Buffer Format */
6096
6097     BufferFormat = GBYTE(pd, offset);
6098
6099     if (tree) {
6100
6101       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6102
6103     }
6104
6105     offset += 1; /* Skip Buffer Format */
6106
6107     /* Build display for: Data Length */
6108
6109     DataLength = GSHORT(pd, offset);
6110
6111     if (tree) {
6112
6113       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
6114
6115     }
6116
6117     offset += 2; /* Skip Data Length */
6118
6119   }
6120
6121 }
6122
6123 void
6124 dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6125
6126 {
6127   proto_tree    *LockType_tree;
6128   proto_item    *ti;
6129   guint8        LockType;
6130   guint8        WordCount;
6131   guint8        OplockLevel;
6132   guint8        AndXReserved;
6133   guint8        AndXCommand = 0xFF;
6134   guint32       Timeout;
6135   guint16       NumberofLocks;
6136   guint16       NumberOfUnlocks;
6137   guint16       FID;
6138   guint16       ByteCount;
6139   guint16       AndXoffset;
6140   guint16       AndXOffset = 0;
6141
6142   if (dirn == 1) { /* Request(s) dissect code */
6143
6144     /* Build display for: Word Count (WCT) */
6145
6146     WordCount = GBYTE(pd, offset);
6147
6148     if (tree) {
6149
6150       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6151
6152     }
6153
6154     offset += 1; /* Skip Word Count (WCT) */
6155
6156     /* Build display for: AndXCommand */
6157
6158     AndXCommand = GBYTE(pd, offset);
6159
6160     if (tree) {
6161
6162       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
6163
6164     }
6165
6166     offset += 1; /* Skip AndXCommand */
6167
6168     /* Build display for: AndXReserved */
6169
6170     AndXReserved = GBYTE(pd, offset);
6171
6172     if (tree) {
6173
6174       proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6175
6176     }
6177
6178     offset += 1; /* Skip AndXReserved */
6179
6180     /* Build display for: AndXOffset */
6181
6182     AndXOffset = GSHORT(pd, offset);
6183
6184     if (tree) {
6185
6186       proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
6187
6188     }
6189
6190     offset += 2; /* Skip AndXOffset */
6191
6192     /* Build display for: FID */
6193
6194     FID = GSHORT(pd, offset);
6195
6196     if (tree) {
6197
6198       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6199
6200     }
6201
6202     offset += 2; /* Skip FID */
6203
6204     /* Build display for: Lock Type */
6205
6206     LockType = GBYTE(pd, offset);
6207
6208     if (tree) {
6209
6210       ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
6211       LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
6212       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6213                           decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
6214       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6215                           decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
6216       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6217                           decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
6218       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6219                           decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
6220       proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
6221                           decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
6222     
6223 }
6224
6225     offset += 1; /* Skip Lock Type */
6226
6227     /* Build display for: OplockLevel */
6228
6229     OplockLevel = GBYTE(pd, offset);
6230
6231     if (tree) {
6232
6233       proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel);
6234
6235     }
6236
6237     offset += 1; /* Skip OplockLevel */
6238
6239     /* Build display for: Timeout */
6240
6241     Timeout = GWORD(pd, offset);
6242
6243     if (tree) {
6244
6245       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
6246
6247     }
6248
6249     offset += 4; /* Skip Timeout */
6250
6251     /* Build display for: Number Of Unlocks */
6252
6253     NumberOfUnlocks = GSHORT(pd, offset);
6254
6255     if (tree) {
6256
6257       proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);
6258
6259     }
6260
6261     offset += 2; /* Skip Number Of Unlocks */
6262
6263     /* Build display for: Number of Locks */
6264
6265     NumberofLocks = GSHORT(pd, offset);
6266
6267     if (tree) {
6268
6269       proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);
6270
6271     }
6272
6273     offset += 2; /* Skip Number of Locks */
6274
6275     /* Build display for: Byte Count (BCC) */
6276
6277     ByteCount = GSHORT(pd, offset);
6278
6279     if (tree) {
6280
6281       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6282
6283     }
6284
6285     offset += 2; /* Skip Byte Count (BCC) */
6286
6287
6288     if (AndXCommand != 0xFF) {
6289
6290       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
6291
6292     }
6293
6294   }
6295
6296   if (dirn == 0) { /* Response(s) dissect code */
6297
6298     /* Build display for: Word Count (WCT) */
6299
6300     WordCount = GBYTE(pd, offset);
6301
6302     if (tree) {
6303
6304       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6305
6306     }
6307
6308     offset += 1; /* Skip Word Count (WCT) */
6309
6310     if (WordCount > 0) {
6311
6312       /* Build display for: AndXCommand */
6313
6314       AndXCommand = GBYTE(pd, offset);
6315
6316       if (tree) {
6317
6318         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s", 
6319                             (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
6320
6321       }
6322
6323       offset += 1; /* Skip AndXCommand */
6324
6325       /* Build display for: AndXReserved */
6326
6327       AndXReserved = GBYTE(pd, offset);
6328
6329       if (tree) {
6330
6331         proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
6332
6333       }
6334
6335       offset += 1; /* Skip AndXReserved */
6336
6337       /* Build display for: AndXoffset */
6338
6339       AndXoffset = GSHORT(pd, offset);
6340
6341       if (tree) {
6342
6343         proto_tree_add_text(tree, NullTVB, offset, 2, "AndXoffset: %u", AndXoffset);
6344
6345       }
6346
6347       offset += 2; /* Skip AndXoffset */
6348
6349     }
6350
6351     /* Build display for: Byte Count */
6352
6353     ByteCount = GSHORT(pd, offset);
6354
6355     if (tree) {
6356
6357       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
6358
6359     }
6360
6361     offset += 2; /* Skip Byte Count */
6362
6363
6364     if (AndXCommand != 0xFF) {
6365
6366       (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn);
6367
6368     }
6369
6370   }
6371
6372 }
6373
6374 void
6375 dissect_unlock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6376
6377 {
6378   guint8        WordCount;
6379   guint32       Offset;
6380   guint32       Count;
6381   guint16       FID;
6382   guint16       ByteCount;
6383
6384   if (dirn == 1) { /* Request(s) dissect code */
6385
6386     /* Build display for: Word Count (WCT) */
6387
6388     WordCount = GBYTE(pd, offset);
6389
6390     if (tree) {
6391
6392       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6393
6394     }
6395
6396     offset += 1; /* Skip Word Count (WCT) */
6397
6398     /* Build display for: FID */
6399
6400     FID = GSHORT(pd, offset);
6401
6402     if (tree) {
6403
6404       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6405
6406     }
6407
6408     offset += 2; /* Skip FID */
6409
6410     /* Build display for: Count */
6411
6412     Count = GWORD(pd, offset);
6413
6414     if (tree) {
6415
6416       proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
6417
6418     }
6419
6420     offset += 4; /* Skip Count */
6421
6422     /* Build display for: Offset */
6423
6424     Offset = GWORD(pd, offset);
6425
6426     if (tree) {
6427
6428       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
6429
6430     }
6431
6432     offset += 4; /* Skip Offset */
6433
6434     /* Build display for: Byte Count (BCC) */
6435
6436     ByteCount = GSHORT(pd, offset);
6437
6438     if (tree) {
6439
6440       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6441
6442     }
6443
6444     offset += 2; /* Skip Byte Count (BCC) */
6445
6446   }
6447
6448   if (dirn == 0) { /* Response(s) dissect code */
6449
6450     /* Build display for: Word Count (WCT) */
6451
6452     WordCount = GBYTE(pd, offset);
6453
6454     if (tree) {
6455
6456       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6457
6458     }
6459
6460     offset += 1; /* Skip Word Count (WCT) */
6461
6462     /* Build display for: Byte Count (BCC) */
6463
6464     ByteCount = GSHORT(pd, offset);
6465
6466     if (tree) {
6467
6468       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6469
6470     }
6471
6472     offset += 2; /* Skip Byte Count (BCC) */
6473
6474   }
6475
6476 }
6477
6478 void
6479 dissect_create_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6480
6481 {
6482   proto_tree    *Attributes_tree;
6483   proto_item    *ti;
6484   guint8        WordCount;
6485   guint8        BufferFormat;
6486   guint16       FID;
6487   guint16       CreationTime;
6488   guint16       ByteCount;
6489   guint16       Attributes;
6490   const char    *FileName;
6491
6492   if (dirn == 1) { /* Request(s) dissect code */
6493
6494     /* Build display for: Word Count (WCT) */
6495
6496     WordCount = GBYTE(pd, offset);
6497
6498     if (tree) {
6499
6500       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6501
6502     }
6503
6504     offset += 1; /* Skip Word Count (WCT) */
6505
6506     /* Build display for: Attributes */
6507
6508     Attributes = GSHORT(pd, offset);
6509
6510     if (tree) {
6511
6512       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
6513       Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
6514       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
6515                           decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
6516       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
6517                           decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
6518       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
6519                           decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
6520       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
6521                           decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
6522       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
6523                           decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
6524       proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
6525                           decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
6526     
6527 }
6528
6529     offset += 2; /* Skip Attributes */
6530
6531     /* Build display for: Creation Time */
6532
6533     CreationTime = GSHORT(pd, offset);
6534
6535     if (tree) {
6536
6537       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
6538
6539     }
6540
6541     offset += 2; /* Skip Creation Time */
6542
6543     /* Build display for: Byte Count (BCC) */
6544
6545     ByteCount = GSHORT(pd, offset);
6546
6547     if (tree) {
6548
6549       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6550
6551     }
6552
6553     offset += 2; /* Skip Byte Count (BCC) */
6554
6555     /* Build display for: Buffer Format */
6556
6557     BufferFormat = GBYTE(pd, offset);
6558
6559     if (tree) {
6560
6561       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6562
6563     }
6564
6565     offset += 1; /* Skip Buffer Format */
6566
6567     /* Build display for: File Name */
6568
6569     FileName = pd + offset;
6570
6571     if (tree) {
6572
6573       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
6574
6575     }
6576
6577     offset += strlen(FileName) + 1; /* Skip File Name */
6578
6579   }
6580
6581   if (dirn == 0) { /* Response(s) dissect code */
6582
6583     /* Build display for: Word Count (WCT) */
6584
6585     WordCount = GBYTE(pd, offset);
6586
6587     if (tree) {
6588
6589       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6590
6591     }
6592
6593     offset += 1; /* Skip Word Count (WCT) */
6594
6595     if (WordCount > 0) {
6596
6597       /* Build display for: FID */
6598
6599       FID = GSHORT(pd, offset);
6600
6601       if (tree) {
6602
6603         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6604
6605       }
6606
6607       offset += 2; /* Skip FID */
6608       
6609     }
6610     
6611     /* Build display for: Byte Count (BCC) */
6612
6613     ByteCount = GSHORT(pd, offset);
6614
6615     if (tree) {
6616
6617       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6618
6619     }
6620
6621     offset += 2; /* Skip Byte Count (BCC) */
6622
6623   }
6624
6625 }
6626
6627 void
6628 dissect_search_dir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6629
6630 {
6631   guint8        WordCount;
6632   guint8        BufferFormat2;
6633   guint8        BufferFormat1;
6634   guint8        BufferFormat;
6635   guint16       SearchAttributes;
6636   guint16       ResumeKeyLength;
6637   guint16       MaxCount;
6638   guint16       DataLength;
6639   guint16       Count;
6640   guint16       ByteCount;
6641   const char    *FileName;
6642
6643   if (dirn == 1) { /* Request(s) dissect code */
6644
6645     /* Build display for: Word Count (WCT) */
6646
6647     WordCount = GBYTE(pd, offset);
6648
6649     if (tree) {
6650
6651       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6652
6653     }
6654
6655     offset += 1; /* Skip Word Count (WCT) */
6656
6657     /* Build display for: Max Count */
6658
6659     MaxCount = GSHORT(pd, offset);
6660
6661     if (tree) {
6662
6663       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
6664
6665     }
6666
6667     offset += 2; /* Skip Max Count */
6668
6669     /* Build display for: Search Attributes */
6670
6671     SearchAttributes = GSHORT(pd, offset);
6672
6673     if (tree) {
6674
6675       proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
6676
6677     }
6678
6679     offset += 2; /* Skip Search Attributes */
6680
6681     /* Build display for: Byte Count (BCC) */
6682
6683     ByteCount = GSHORT(pd, offset);
6684
6685     if (tree) {
6686
6687       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6688
6689     }
6690
6691     offset += 2; /* Skip Byte Count (BCC) */
6692
6693     /* Build display for: Buffer Format 1 */
6694
6695     BufferFormat1 = GBYTE(pd, offset);
6696
6697     if (tree) {
6698
6699       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %u", BufferFormat1);
6700
6701     }
6702
6703     offset += 1; /* Skip Buffer Format 1 */
6704
6705     /* Build display for: File Name */
6706
6707     FileName = pd + offset;
6708
6709     if (tree) {
6710
6711       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
6712
6713     }
6714
6715     offset += strlen(FileName) + 1; /* Skip File Name */
6716
6717     /* Build display for: Buffer Format 2 */
6718
6719     BufferFormat2 = GBYTE(pd, offset);
6720
6721     if (tree) {
6722
6723       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %u", BufferFormat2);
6724
6725     }
6726
6727     offset += 1; /* Skip Buffer Format 2 */
6728
6729     /* Build display for: Resume Key Length */
6730
6731     ResumeKeyLength = GSHORT(pd, offset);
6732
6733     if (tree) {
6734
6735       proto_tree_add_text(tree, NullTVB, offset, 2, "Resume Key Length: %u", ResumeKeyLength);
6736
6737     }
6738
6739     offset += 2; /* Skip Resume Key Length */
6740
6741   }
6742
6743   if (dirn == 0) { /* Response(s) dissect code */
6744
6745     /* Build display for: Word Count (WCT) */
6746
6747     WordCount = GBYTE(pd, offset);
6748
6749     if (tree) {
6750
6751       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6752
6753     }
6754
6755     offset += 1; /* Skip Word Count (WCT) */
6756
6757     if (WordCount > 0) {
6758
6759       /* Build display for: Count */
6760
6761       Count = GSHORT(pd, offset);
6762
6763       if (tree) {
6764
6765         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
6766
6767       }
6768
6769       offset += 2; /* Skip Count */
6770
6771     }
6772
6773     /* Build display for: Byte Count (BCC) */
6774
6775     ByteCount = GSHORT(pd, offset);
6776
6777     if (tree) {
6778
6779       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6780
6781     }
6782
6783     offset += 2; /* Skip Byte Count (BCC) */
6784
6785     /* Build display for: Buffer Format */
6786
6787     BufferFormat = GBYTE(pd, offset);
6788
6789     if (tree) {
6790
6791       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6792
6793     }
6794
6795     offset += 1; /* Skip Buffer Format */
6796
6797     /* Build display for: Data Length */
6798
6799     DataLength = GSHORT(pd, offset);
6800
6801     if (tree) {
6802
6803       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
6804
6805     }
6806
6807     offset += 2; /* Skip Data Length */
6808
6809   }
6810
6811 }
6812
6813 void
6814 dissect_create_temporary_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6815
6816 {
6817   guint8        WordCount;
6818   guint8        BufferFormat;
6819   guint16       Reserved;
6820   guint16       FID;
6821   guint16       CreationTime;
6822   guint16       CreationDate;
6823   guint16       ByteCount;
6824   const char    *FileName;
6825   const char    *DirectoryName;
6826
6827   if (dirn == 1) { /* Request(s) dissect code */
6828
6829     /* Build display for: Word Count (WCT) */
6830
6831     WordCount = GBYTE(pd, offset);
6832
6833     if (tree) {
6834
6835       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6836
6837     }
6838
6839     offset += 1; /* Skip Word Count (WCT) */
6840
6841     /* Build display for: Reserved */
6842
6843     Reserved = GSHORT(pd, offset);
6844
6845     if (tree) {
6846
6847       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
6848
6849     }
6850
6851     offset += 2; /* Skip Reserved */
6852
6853     /* Build display for: Creation Time */
6854
6855     CreationTime = GSHORT(pd, offset);
6856
6857     if (tree) {
6858
6859       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
6860
6861     }
6862
6863     offset += 2; /* Skip Creation Time */
6864
6865     /* Build display for: Creation Date */
6866
6867     CreationDate = GSHORT(pd, offset);
6868
6869     if (tree) {
6870
6871       proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
6872
6873     }
6874
6875     offset += 2; /* Skip Creation Date */
6876
6877     /* Build display for: Byte Count (BCC) */
6878
6879     ByteCount = GSHORT(pd, offset);
6880
6881     if (tree) {
6882
6883       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6884
6885     }
6886
6887     offset += 2; /* Skip Byte Count (BCC) */
6888
6889     /* Build display for: Buffer Format */
6890
6891     BufferFormat = GBYTE(pd, offset);
6892
6893     if (tree) {
6894
6895       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6896
6897     }
6898
6899     offset += 1; /* Skip Buffer Format */
6900
6901     /* Build display for: Directory Name */
6902
6903     DirectoryName = pd + offset;
6904
6905     if (tree) {
6906
6907       proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
6908
6909     }
6910
6911     offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
6912
6913   }
6914
6915   if (dirn == 0) { /* Response(s) dissect code */
6916
6917     /* Build display for: Word Count (WCT) */
6918
6919     WordCount = GBYTE(pd, offset);
6920
6921     if (tree) {
6922
6923       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
6924
6925     }
6926
6927     offset += 1; /* Skip Word Count (WCT) */
6928
6929     if (WordCount > 0) {
6930
6931       /* Build display for: FID */
6932
6933       FID = GSHORT(pd, offset);
6934
6935       if (tree) {
6936
6937         proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
6938
6939       }
6940
6941       offset += 2; /* Skip FID */
6942
6943     }
6944
6945     /* Build display for: Byte Count (BCC) */
6946
6947     ByteCount = GSHORT(pd, offset);
6948
6949     if (tree) {
6950
6951       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
6952
6953     }
6954
6955     offset += 2; /* Skip Byte Count (BCC) */
6956
6957     /* Build display for: Buffer Format */
6958
6959     BufferFormat = GBYTE(pd, offset);
6960
6961     if (tree) {
6962
6963       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
6964
6965     }
6966
6967     offset += 1; /* Skip Buffer Format */
6968
6969     /* Build display for: File Name */
6970
6971     FileName = pd + offset;
6972
6973     if (tree) {
6974
6975       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
6976
6977     }
6978
6979     offset += strlen(FileName) + 1; /* Skip File Name */
6980
6981   }
6982
6983 }
6984
6985 void
6986 dissect_close_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
6987
6988 {
6989   guint8        WordCount;
6990   guint16       LastWriteTime;
6991   guint16       LastWriteDate;
6992   guint16       FID;
6993   guint16       ByteCount;
6994
6995   if (dirn == 1) { /* Request(s) dissect code */
6996
6997     /* Build display for: Word Count (WCT) */
6998
6999     WordCount = GBYTE(pd, offset);
7000
7001     if (tree) {
7002
7003       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7004
7005     }
7006
7007     offset += 1; /* Skip Word Count (WCT) */
7008
7009     /* Build display for: FID */
7010
7011     FID = GSHORT(pd, offset);
7012
7013     if (tree) {
7014
7015       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7016
7017     }
7018
7019     offset += 2; /* Skip FID */
7020
7021     /* Build display for: Last Write Time */
7022
7023     LastWriteTime = GSHORT(pd, offset);
7024
7025     if (tree) {
7026
7027       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
7028
7029     }
7030
7031     offset += 2; /* Skip Last Write Time */
7032
7033     /* Build display for: Last Write Date */
7034
7035     LastWriteDate = GSHORT(pd, offset);
7036
7037     if (tree) {
7038
7039       proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
7040
7041     }
7042
7043     offset += 2; /* Skip Last Write Date */
7044
7045     /* Build display for: Byte Count (BCC) */
7046
7047     ByteCount = GSHORT(pd, offset);
7048
7049     if (tree) {
7050
7051       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7052
7053     }
7054
7055     offset += 2; /* Skip Byte Count (BCC) */
7056
7057   }
7058
7059   if (dirn == 0) { /* Response(s) dissect code */
7060
7061     /* Build display for: Word Count (WCT) */
7062
7063     WordCount = GBYTE(pd, offset);
7064
7065     if (tree) {
7066
7067       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7068
7069     }
7070
7071     offset += 1; /* Skip Word Count (WCT) */
7072
7073     /* Build display for: Byte Count (BCC) */
7074
7075     ByteCount = GSHORT(pd, offset);
7076
7077     if (tree) {
7078
7079       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7080
7081     }
7082
7083     offset += 2; /* Skip Byte Count (BCC) */
7084
7085   }
7086
7087 }
7088
7089 void
7090 dissect_write_print_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7091
7092 {
7093   guint8        WordCount;
7094   guint8        BufferFormat;
7095   guint16       FID;
7096   guint16       DataLength;
7097   guint16       ByteCount;
7098
7099   if (dirn == 1) { /* Request(s) dissect code */
7100
7101     /* Build display for: Word Count (WCT) */
7102
7103     WordCount = GBYTE(pd, offset);
7104
7105     if (tree) {
7106
7107       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7108
7109     }
7110
7111     offset += 1; /* Skip Word Count (WCT) */
7112
7113     /* Build display for: FID */
7114
7115     FID = GSHORT(pd, offset);
7116
7117     if (tree) {
7118
7119       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7120
7121     }
7122
7123     offset += 2; /* Skip FID */
7124
7125     /* Build display for: Byte Count (BCC) */
7126
7127     ByteCount = GSHORT(pd, offset);
7128
7129     if (tree) {
7130
7131       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7132
7133     }
7134
7135     offset += 2; /* Skip Byte Count (BCC) */
7136
7137     /* Build display for: Buffer Format */
7138
7139     BufferFormat = GBYTE(pd, offset);
7140
7141     if (tree) {
7142
7143       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7144
7145     }
7146
7147     offset += 1; /* Skip Buffer Format */
7148
7149     /* Build display for: Data Length */
7150
7151     DataLength = GSHORT(pd, offset);
7152
7153     if (tree) {
7154
7155       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7156
7157     }
7158
7159     offset += 2; /* Skip Data Length */
7160
7161   }
7162
7163   if (dirn == 0) { /* Response(s) dissect code */
7164
7165     /* Build display for: Word Count (WCT) */
7166
7167     WordCount = GBYTE(pd, offset);
7168
7169     if (tree) {
7170
7171       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7172
7173     }
7174
7175     offset += 1; /* Skip Word Count (WCT) */
7176
7177     /* Build display for: Byte Count (BCC) */
7178
7179     ByteCount = GSHORT(pd, offset);
7180
7181     if (tree) {
7182
7183       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7184
7185     }
7186
7187     offset += 2; /* Skip Byte Count (BCC) */
7188
7189   }
7190
7191 }
7192
7193 void
7194 dissect_lock_and_read_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7195
7196 {
7197   guint8        WordCount;
7198   guint8        BufferFormat;
7199   guint32       Offset;
7200   guint16       Reserved4;
7201   guint16       Reserved3;
7202   guint16       Reserved2;
7203   guint16       Reserved1;
7204   guint16       Remaining;
7205   guint16       FID;
7206   guint16       DataLength;
7207   guint16       Count;
7208   guint16       ByteCount;
7209
7210   if (dirn == 1) { /* Request(s) dissect code */
7211
7212     /* Build display for: Word Count (WCT) */
7213
7214     WordCount = GBYTE(pd, offset);
7215
7216     if (tree) {
7217
7218       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7219
7220     }
7221
7222     offset += 1; /* Skip Word Count (WCT) */
7223
7224     /* Build display for: FID */
7225
7226     FID = GSHORT(pd, offset);
7227
7228     if (tree) {
7229
7230       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7231
7232     }
7233
7234     offset += 2; /* Skip FID */
7235
7236     /* Build display for: Count */
7237
7238     Count = GSHORT(pd, offset);
7239
7240     if (tree) {
7241
7242       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7243
7244     }
7245
7246     offset += 2; /* Skip Count */
7247
7248     /* Build display for: Offset */
7249
7250     Offset = GWORD(pd, offset);
7251
7252     if (tree) {
7253
7254       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
7255
7256     }
7257
7258     offset += 4; /* Skip Offset */
7259
7260     /* Build display for: Remaining */
7261
7262     Remaining = GSHORT(pd, offset);
7263
7264     if (tree) {
7265
7266       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
7267
7268     }
7269
7270     offset += 2; /* Skip Remaining */
7271
7272     /* Build display for: Byte Count (BCC) */
7273
7274     ByteCount = GSHORT(pd, offset);
7275
7276     if (tree) {
7277
7278       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7279
7280     }
7281
7282     offset += 2; /* Skip Byte Count (BCC) */
7283
7284   }
7285
7286   if (dirn == 0) { /* Response(s) dissect code */
7287
7288     /* Build display for: Word Count (WCT) */
7289
7290     WordCount = GBYTE(pd, offset);
7291
7292     if (tree) {
7293
7294       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7295
7296     }
7297
7298     offset += 1; /* Skip Word Count (WCT) */
7299
7300     if (WordCount > 0) {
7301
7302       /* Build display for: Count */
7303
7304       Count = GSHORT(pd, offset);
7305
7306       if (tree) {
7307
7308         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7309
7310       }
7311
7312       offset += 2; /* Skip Count */
7313
7314       /* Build display for: Reserved 1 */
7315
7316       Reserved1 = GSHORT(pd, offset);
7317
7318       if (tree) {
7319
7320         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
7321
7322       }
7323
7324       offset += 2; /* Skip Reserved 1 */
7325
7326       /* Build display for: Reserved 2 */
7327
7328       Reserved2 = GSHORT(pd, offset);
7329
7330       if (tree) {
7331
7332         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
7333
7334       }
7335
7336       offset += 2; /* Skip Reserved 2 */
7337
7338       /* Build display for: Reserved 3 */
7339
7340       Reserved3 = GSHORT(pd, offset);
7341
7342       if (tree) {
7343
7344         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
7345
7346       }
7347
7348       offset += 2; /* Skip Reserved 3 */
7349
7350       /* Build display for: Reserved 4 */
7351
7352       Reserved4 = GSHORT(pd, offset);
7353
7354       if (tree) {
7355
7356         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
7357
7358       }
7359
7360       offset += 2; /* Skip Reserved 4 */
7361
7362       /* Build display for: Byte Count (BCC) */
7363
7364       ByteCount = GSHORT(pd, offset);
7365
7366       if (tree) {
7367
7368         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7369
7370       }
7371
7372     }
7373
7374     offset += 2; /* Skip Byte Count (BCC) */
7375
7376     /* Build display for: Buffer Format */
7377
7378     BufferFormat = GBYTE(pd, offset);
7379
7380     if (tree) {
7381
7382       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7383
7384     }
7385
7386     offset += 1; /* Skip Buffer Format */
7387
7388     /* Build display for: Data Length */
7389
7390     DataLength = GSHORT(pd, offset);
7391
7392     if (tree) {
7393
7394       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7395
7396     }
7397
7398     offset += 2; /* Skip Data Length */
7399
7400   }
7401
7402 }
7403
7404 void
7405 dissect_process_exit_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7406
7407 {
7408   guint8        WordCount;
7409   guint16       ByteCount;
7410
7411   if (dirn == 1) { /* Request(s) dissect code */
7412
7413     /* Build display for: Word Count (WCT) */
7414
7415     WordCount = GBYTE(pd, offset);
7416
7417     if (tree) {
7418
7419       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7420
7421     }
7422
7423     offset += 1; /* Skip Word Count (WCT) */
7424
7425     /* Build display for: Byte Count (BCC) */
7426
7427     ByteCount = GSHORT(pd, offset);
7428
7429     if (tree) {
7430
7431       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7432
7433     }
7434
7435     offset += 2; /* Skip Byte Count (BCC) */
7436
7437   }
7438
7439   if (dirn == 0) { /* Response(s) dissect code */
7440
7441     /* Build display for: Word Count (WCT) */
7442
7443     WordCount = GBYTE(pd, offset);
7444
7445     if (tree) {
7446
7447       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7448
7449     }
7450
7451     offset += 1; /* Skip Word Count (WCT) */
7452
7453     /* Build display for: Byte Count (BCC) */
7454
7455     ByteCount = GSHORT(pd, offset);
7456
7457     if (tree) {
7458
7459       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7460
7461     }
7462
7463     offset += 2; /* Skip Byte Count (BCC) */
7464
7465   }
7466
7467 }
7468
7469 void
7470 dissect_get_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7471
7472 {
7473   proto_tree    *Attributes_tree;
7474   proto_item    *ti;
7475   guint8        WordCount;
7476   guint8        BufferFormat;
7477   guint32       FileSize;
7478   guint16       Reserved5;
7479   guint16       Reserved4;
7480   guint16       Reserved3;
7481   guint16       Reserved2;
7482   guint16       Reserved1;
7483   guint16       LastWriteTime;
7484   guint16       LastWriteDate;
7485   guint16       ByteCount;
7486   guint16       Attributes;
7487   const char    *FileName;
7488
7489   if (dirn == 1) { /* Request(s) dissect code */
7490
7491     /* Build display for: Word Count (WCT) */
7492
7493     WordCount = GBYTE(pd, offset);
7494
7495     if (tree) {
7496
7497       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7498
7499     }
7500
7501     offset += 1; /* Skip Word Count (WCT) */
7502
7503     /* Build display for: Byte Count (BCC) */
7504
7505     ByteCount = GSHORT(pd, offset);
7506
7507     if (tree) {
7508
7509       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7510
7511     }
7512
7513     offset += 2; /* Skip Byte Count (BCC) */
7514
7515     /* Build display for: Buffer Format */
7516
7517     BufferFormat = GBYTE(pd, offset);
7518
7519     if (tree) {
7520
7521       proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
7522
7523     }
7524
7525     offset += 1; /* Skip Buffer Format */
7526
7527     /* Build display for: File Name */
7528
7529     FileName = pd + offset;
7530
7531     if (tree) {
7532
7533       proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
7534
7535     }
7536
7537     offset += strlen(FileName) + 1; /* Skip File Name */
7538
7539   }
7540
7541   if (dirn == 0) { /* Response(s) dissect code */
7542
7543     /* Build display for: Word Count (WCT) */
7544
7545     WordCount = GBYTE(pd, offset);
7546
7547     if (tree) {
7548
7549       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7550
7551     }
7552
7553     offset += 1; /* Skip Word Count (WCT) */
7554
7555     if (WordCount > 0) {
7556
7557       /* Build display for: Attributes */
7558
7559       Attributes = GSHORT(pd, offset);
7560
7561       if (tree) {
7562
7563         ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
7564         Attributes_tree = proto_item_add_subtree(ti, ett_smb_fileattributes);
7565         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7566                             decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
7567         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7568                             decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
7569         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7570                             decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
7571         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7572                             decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
7573         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7574                             decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
7575         proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
7576                             decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
7577         
7578       }
7579
7580       offset += 2; /* Skip Attributes */
7581
7582       /* Build display for: Last Write Time */
7583
7584       LastWriteTime = GSHORT(pd, offset);
7585
7586       if (tree) {
7587
7588       }
7589
7590       offset += 2; /* Skip Last Write Time */
7591
7592       /* Build display for: Last Write Date */
7593
7594       LastWriteDate = GSHORT(pd, offset);
7595
7596       if (tree) {
7597
7598         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_smbu_date(LastWriteDate, LastWriteTime));
7599
7600         proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_smbu_time(LastWriteDate, LastWriteTime));
7601
7602       }
7603
7604       offset += 2; /* Skip Last Write Date */
7605
7606       /* Build display for: File Size */
7607
7608       FileSize = GWORD(pd, offset);
7609
7610       if (tree) {
7611
7612         proto_tree_add_text(tree, NullTVB, offset, 4, "File Size: %u", FileSize);
7613
7614       }
7615
7616       offset += 4; /* Skip File Size */
7617
7618       /* Build display for: Reserved 1 */
7619
7620       Reserved1 = GSHORT(pd, offset);
7621
7622       if (tree) {
7623
7624         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
7625
7626       }
7627
7628       offset += 2; /* Skip Reserved 1 */
7629
7630       /* Build display for: Reserved 2 */
7631
7632       Reserved2 = GSHORT(pd, offset);
7633
7634       if (tree) {
7635
7636         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
7637
7638       }
7639
7640       offset += 2; /* Skip Reserved 2 */
7641
7642       /* Build display for: Reserved 3 */
7643
7644       Reserved3 = GSHORT(pd, offset);
7645
7646       if (tree) {
7647
7648         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
7649
7650       }
7651
7652       offset += 2; /* Skip Reserved 3 */
7653
7654       /* Build display for: Reserved 4 */
7655
7656       Reserved4 = GSHORT(pd, offset);
7657
7658       if (tree) {
7659
7660         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
7661
7662       }
7663
7664       offset += 2; /* Skip Reserved 4 */
7665
7666       /* Build display for: Reserved 5 */
7667
7668       Reserved5 = GSHORT(pd, offset);
7669
7670       if (tree) {
7671
7672         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
7673
7674       }
7675
7676       offset += 2; /* Skip Reserved 5 */
7677
7678     }
7679
7680     /* Build display for: Byte Count (BCC) */
7681
7682     ByteCount = GSHORT(pd, offset);
7683
7684     if (tree) {
7685
7686       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7687
7688     }
7689
7690     offset += 2; /* Skip Byte Count (BCC) */
7691
7692   }
7693
7694 }
7695
7696 void
7697 dissect_read_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7698
7699 {
7700   guint8        WordCount;
7701   guint32       Offset;
7702   guint16       Reserved4;
7703   guint16       Reserved3;
7704   guint16       Reserved2;
7705   guint16       Reserved1;
7706   guint16       Remaining;
7707   guint16       FID;
7708   guint16       DataLength;
7709   guint16       Count;
7710   guint16       ByteCount;
7711   guint16       BufferFormat;
7712
7713   if (dirn == 1) { /* Request(s) dissect code */
7714
7715     /* Build display for: Word Count (WCT) */
7716
7717     WordCount = GBYTE(pd, offset);
7718
7719     if (tree) {
7720
7721       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7722
7723     }
7724
7725     offset += 1; /* Skip Word Count (WCT) */
7726
7727     /* Build display for: FID */
7728
7729     FID = GSHORT(pd, offset);
7730
7731     if (tree) {
7732
7733       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7734
7735     }
7736
7737     offset += 2; /* Skip FID */
7738
7739     /* Build display for: Count */
7740
7741     Count = GSHORT(pd, offset);
7742
7743     if (tree) {
7744
7745       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7746
7747     }
7748
7749     offset += 2; /* Skip Count */
7750
7751     /* Build display for: Offset */
7752
7753     Offset = GWORD(pd, offset);
7754
7755     if (tree) {
7756
7757       proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
7758
7759     }
7760
7761     offset += 4; /* Skip Offset */
7762
7763     /* Build display for: Remaining */
7764
7765     Remaining = GSHORT(pd, offset);
7766
7767     if (tree) {
7768
7769       proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
7770
7771     }
7772
7773     offset += 2; /* Skip Remaining */
7774
7775     /* Build display for: Byte Count (BCC) */
7776
7777     ByteCount = GSHORT(pd, offset);
7778
7779     if (tree) {
7780
7781       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7782
7783     }
7784
7785     offset += 2; /* Skip Byte Count (BCC) */
7786
7787   }
7788
7789   if (dirn == 0) { /* Response(s) dissect code */
7790
7791     /* Build display for: Word Count (WCT) */
7792
7793     WordCount = GBYTE(pd, offset);
7794
7795     if (tree) {
7796
7797       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7798
7799     }
7800
7801     offset += 1; /* Skip Word Count (WCT) */
7802
7803     if (WordCount > 0) {
7804
7805       /* Build display for: Count */
7806
7807       Count = GSHORT(pd, offset);
7808
7809       if (tree) {
7810
7811         proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7812
7813       }
7814
7815       offset += 2; /* Skip Count */
7816
7817       /* Build display for: Reserved 1 */
7818
7819       Reserved1 = GSHORT(pd, offset);
7820
7821       if (tree) {
7822
7823         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
7824
7825       }
7826
7827       offset += 2; /* Skip Reserved 1 */
7828
7829       /* Build display for: Reserved 2 */
7830
7831       Reserved2 = GSHORT(pd, offset);
7832
7833       if (tree) {
7834
7835         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
7836
7837       }
7838
7839       offset += 2; /* Skip Reserved 2 */
7840
7841       /* Build display for: Reserved 3 */
7842
7843       Reserved3 = GSHORT(pd, offset);
7844
7845       if (tree) {
7846
7847         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
7848
7849       }
7850
7851       offset += 2; /* Skip Reserved 3 */
7852
7853       /* Build display for: Reserved 4 */
7854
7855       Reserved4 = GSHORT(pd, offset);
7856
7857       if (tree) {
7858
7859         proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
7860
7861       }
7862
7863       offset += 2; /* Skip Reserved 4 */
7864
7865     }
7866     
7867     /* Build display for: Byte Count (BCC) */
7868     
7869     ByteCount = GSHORT(pd, offset);
7870       
7871     if (tree) {
7872
7873       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
7874
7875     }
7876
7877     offset += 2; /* Skip Byte Count (BCC) */
7878
7879     /* Build display for: Buffer Format */
7880
7881     BufferFormat = GSHORT(pd, offset);
7882
7883     if (tree) {
7884
7885       proto_tree_add_text(tree, NullTVB, offset, 2, "Buffer Format: %u", BufferFormat);
7886
7887     }
7888
7889     offset += 2; /* Skip Buffer Format */
7890
7891     /* Build display for: Data Length */
7892
7893     DataLength = GSHORT(pd, offset);
7894
7895     if (tree) {
7896
7897       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
7898
7899     }
7900
7901     offset += 2; /* Skip Data Length */
7902
7903   }
7904
7905 }
7906
7907 void
7908 dissect_write_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
7909
7910 {
7911   proto_tree    *WriteMode_tree;
7912   proto_item    *ti;
7913   guint8        WordCount;
7914   guint8        Pad;
7915   guint32       Timeout;
7916   guint32       ResponseMask;
7917   guint32       RequestMask;
7918   guint16       WriteMode;
7919   guint16       Reserved1;
7920   guint16       FID;
7921   guint16       DataOffset;
7922   guint16       DataLength;
7923   guint16       Count;
7924   guint16       ByteCount;
7925
7926   if (dirn == 1) { /* Request(s) dissect code */
7927
7928     /* Build display for: Word Count (WCT) */
7929
7930     WordCount = GBYTE(pd, offset);
7931
7932     if (tree) {
7933
7934       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
7935
7936     }
7937
7938     offset += 1; /* Skip Word Count (WCT) */
7939
7940     /* Build display for: FID */
7941
7942     FID = GSHORT(pd, offset);
7943
7944     if (tree) {
7945
7946       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
7947
7948     }
7949
7950     offset += 2; /* Skip FID */
7951
7952     /* Build display for: Count */
7953
7954     Count = GSHORT(pd, offset);
7955
7956     if (tree) {
7957
7958       proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
7959
7960     }
7961
7962     offset += 2; /* Skip Count */
7963
7964     /* Build display for: Reserved 1 */
7965
7966     Reserved1 = GSHORT(pd, offset);
7967
7968     if (tree) {
7969
7970       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
7971
7972     }
7973
7974     offset += 2; /* Skip Reserved 1 */
7975
7976     /* Build display for: Timeout */
7977
7978     Timeout = GWORD(pd, offset);
7979
7980     if (tree) {
7981
7982       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
7983
7984     }
7985
7986     offset += 4; /* Skip Timeout */
7987
7988     /* Build display for: WriteMode */
7989
7990     WriteMode = GSHORT(pd, offset);
7991
7992     if (tree) {
7993
7994       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "WriteMode: 0x%02x", WriteMode);
7995       WriteMode_tree = proto_item_add_subtree(ti, ett_smb_writemode);
7996       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
7997                           decode_boolean_bitfield(WriteMode, 0x01, 16, "Write through requested", "Write through not requested"));
7998       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
7999                           decode_boolean_bitfield(WriteMode, 0x02, 16, "Return Remaining", "Dont return Remaining"));
8000       proto_tree_add_text(WriteMode_tree, NullTVB, offset, 2, "%s",
8001                           decode_boolean_bitfield(WriteMode, 0x40, 16, "Connectionless mode requested", "Connectionless mode not requested"));
8002     
8003 }
8004
8005     offset += 2; /* Skip WriteMode */
8006
8007     /* Build display for: Request Mask */
8008
8009     RequestMask = GWORD(pd, offset);
8010
8011     if (tree) {
8012
8013       proto_tree_add_text(tree, NullTVB, offset, 4, "Request Mask: %u", RequestMask);
8014
8015     }
8016
8017     offset += 4; /* Skip Request Mask */
8018
8019     /* Build display for: Data Length */
8020
8021     DataLength = GSHORT(pd, offset);
8022
8023     if (tree) {
8024
8025       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
8026
8027     }
8028
8029     offset += 2; /* Skip Data Length */
8030
8031     /* Build display for: Data Offset */
8032
8033     DataOffset = GSHORT(pd, offset);
8034
8035     if (tree) {
8036
8037       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
8038
8039     }
8040
8041     offset += 2; /* Skip Data Offset */
8042
8043     /* Build display for: Byte Count (BCC) */
8044
8045     ByteCount = GSHORT(pd, offset);
8046
8047     if (tree) {
8048
8049       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8050
8051     }
8052
8053     offset += 2; /* Skip Byte Count (BCC) */
8054
8055     /* Build display for: Pad */
8056
8057     Pad = GBYTE(pd, offset);
8058
8059     if (tree) {
8060
8061       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
8062
8063     }
8064
8065     offset += 1; /* Skip Pad */
8066
8067   }
8068
8069   if (dirn == 0) { /* Response(s) dissect code */
8070
8071     /* Build display for: Word Count (WCT) */
8072
8073     WordCount = GBYTE(pd, offset);
8074
8075     if (tree) {
8076
8077       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8078
8079     }
8080
8081     offset += 1; /* Skip Word Count (WCT) */
8082
8083     if (WordCount > 0) {
8084
8085       /* Build display for: Response Mask */
8086
8087       ResponseMask = GWORD(pd, offset);
8088
8089       if (tree) {
8090
8091         proto_tree_add_text(tree, NullTVB, offset, 4, "Response Mask: %u", ResponseMask);
8092
8093       }
8094
8095       offset += 4; /* Skip Response Mask */
8096
8097       /* Build display for: Byte Count (BCC) */
8098
8099       ByteCount = GSHORT(pd, offset);
8100
8101       if (tree) {
8102
8103         proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8104
8105       }
8106
8107     }
8108
8109     offset += 2; /* Skip Byte Count (BCC) */
8110
8111   }
8112
8113 }
8114
8115 void
8116 dissect_find_close2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8117
8118 {
8119   guint8        WordCount;
8120   guint8        ByteCount;
8121   guint16       FID;
8122
8123   if (dirn == 1) { /* Request(s) dissect code */
8124
8125     /* Build display for: Word Count (WTC) */
8126
8127     WordCount = GBYTE(pd, offset);
8128
8129     if (tree) {
8130
8131       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WTC): %u", WordCount);
8132
8133     }
8134
8135     offset += 1; /* Skip Word Count (WTC) */
8136
8137     /* Build display for: FID */
8138
8139     FID = GSHORT(pd, offset);
8140
8141     if (tree) {
8142
8143       proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
8144
8145     }
8146
8147     offset += 2; /* Skip FID */
8148
8149     /* Build display for: Byte Count (BCC) */
8150
8151     ByteCount = GSHORT(pd, offset);
8152
8153     if (tree) {
8154
8155       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8156
8157     }
8158
8159     offset += 2; /* Skip Byte Count (BCC) */
8160
8161   }
8162
8163   if (dirn == 0) { /* Response(s) dissect code */
8164
8165     /* Build display for: Word Count (WCT) */
8166
8167     WordCount = GBYTE(pd, offset);
8168
8169     if (tree) {
8170
8171       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8172
8173     }
8174
8175     offset += 1; /* Skip Word Count (WCT) */
8176
8177     /* Build display for: Byte Count (BCC) */
8178
8179     ByteCount = GBYTE(pd, offset);
8180
8181     if (tree) {
8182
8183       proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
8184
8185     }
8186
8187     offset += 1; /* Skip Byte Count (BCC) */
8188
8189   }
8190
8191 }
8192
8193 char *trans2_cmd_names[] = {
8194   "TRANS2_OPEN",
8195   "TRANS2_FIND_FIRST2",
8196   "TRANS2_FIND_NEXT2",
8197   "TRANS2_QUERY_FS_INFORMATION",
8198   "TRANS2_QUERY_PATH_INFORMATION",
8199   "TRANS2_SET_PATH_INFORMATION",
8200   "TRANS2_QUERY_FILE_INFORMATION",
8201   "TRANS2_SET_FILE_INFORMATION",
8202   "TRANS2_FSCTL",
8203   "TRANS2_IOCTL2",
8204   "TRANS2_FIND_NOTIFY_FIRST",
8205   "TRANS2_FIND_NOTIFY_NEXT",
8206   "TRANS2_CREATE_DIRECTORY",
8207   "TRANS2_SESSION_SETUP",
8208   "TRANS2_GET_DFS_REFERRAL",
8209   "no such command",
8210   "TRANS2_REPORT_DFS_INCONSISTENCY"};
8211
8212 char *decode_trans2_name(int code)
8213 {
8214
8215   if (code > 17 || code < 0) {
8216
8217     return("no such command");
8218
8219   }
8220
8221   return trans2_cmd_names[code];
8222
8223 }
8224
8225
8226 void
8227 dissect_transact2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8228
8229 {
8230   proto_tree    *Flags_tree;
8231   proto_item    *ti;
8232   guint8        WordCount;
8233   guint8        SetupCount;
8234   guint8        Reserved3;
8235   guint8        Reserved1;
8236   guint8        Pad2;
8237   guint8        Pad1;
8238   guint8        MaxSetupCount;
8239   guint8        Data;
8240   guint32       Timeout;
8241   guint16       TotalParameterCount;
8242   guint16       TotalDataCount;
8243   guint16       Setup = 0;
8244   guint16       Reserved2;
8245   guint16       ParameterOffset;
8246   guint16       ParameterDisplacement;
8247   guint16       ParameterCount;
8248   guint16       MaxParameterCount;
8249   guint16       MaxDataCount;
8250   guint16       Flags;
8251   guint16       DataOffset;
8252   guint16       DataDisplacement;
8253   guint16       DataCount;
8254   guint16       ByteCount;
8255   conversation_t *conversation;
8256   struct smb_request_key      request_key, *new_request_key;
8257   struct smb_request_val      *request_val;
8258
8259   /*
8260    * Find out what conversation this packet is part of.
8261    * XXX - this should really be done by the transport-layer protocol,
8262    * although for connectionless transports, we may not want to do that
8263    * unless we know some higher-level protocol will want it - or we
8264    * may want to do it, so you can say e.g. "show only the packets in
8265    * this UDP 'connection'".
8266    *
8267    * Note that we don't have to worry about the direction this packet
8268    * was going - the conversation code handles that for us, treating
8269    * packets from A:X to B:Y as being part of the same conversation as
8270    * packets from B:Y to A:X.
8271    */
8272   conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
8273                                 pi.srcport, pi.destport);
8274   if (conversation == NULL) {
8275     /* It's not part of any conversation - create a new one. */
8276     conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
8277                                 pi.srcport, pi.destport, NULL);
8278   }
8279
8280   si.conversation = conversation;  /* Save this for later */
8281
8282   /*
8283    * Check for and insert entry in request hash table if does not exist
8284    */
8285   request_key.conversation = conversation->index;
8286   request_key.mid          = si.mid;
8287
8288   request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
8289
8290   if (!request_val) { /* Create one */
8291
8292     new_request_key = g_mem_chunk_alloc(smb_request_keys);
8293     new_request_key -> conversation = conversation->index;
8294     new_request_key -> mid          = si.mid;
8295
8296     request_val = g_mem_chunk_alloc(smb_request_vals);
8297     request_val -> mid = si.mid;
8298     request_val -> last_transact2_command = 0xFFFF;
8299
8300     g_hash_table_insert(smb_request_hash, new_request_key, request_val);
8301     
8302   }
8303   else { /* Update the transact request */
8304
8305     request_val -> mid = si.mid;
8306
8307   }
8308
8309   si.request_val = request_val;  /* Save this for later */
8310
8311
8312   if (dirn == 1) { /* Request(s) dissect code */
8313   
8314     /* Build display for: Word Count (WCT) */
8315
8316     WordCount = GBYTE(pd, offset);
8317
8318     if (tree) {
8319
8320       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8321
8322     }
8323
8324     offset += 1; /* Skip Word Count (WCT) */
8325
8326     /* Build display for: Total Parameter Count */
8327
8328     TotalParameterCount = GSHORT(pd, offset);
8329
8330     if (tree) {
8331
8332       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
8333
8334     }
8335
8336     offset += 2; /* Skip Total Parameter Count */
8337
8338     /* Build display for: Total Data Count */
8339
8340     TotalDataCount = GSHORT(pd, offset);
8341
8342     if (tree) {
8343
8344       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
8345
8346     }
8347
8348     offset += 2; /* Skip Total Data Count */
8349
8350     /* Build display for: Max Parameter Count */
8351
8352     MaxParameterCount = GSHORT(pd, offset);
8353
8354     if (tree) {
8355
8356       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Parameter Count: %u", MaxParameterCount);
8357
8358     }
8359
8360     offset += 2; /* Skip Max Parameter Count */
8361
8362     /* Build display for: Max Data Count */
8363
8364     MaxDataCount = GSHORT(pd, offset);
8365
8366     if (tree) {
8367
8368       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Data Count: %u", MaxDataCount);
8369
8370     }
8371
8372     offset += 2; /* Skip Max Data Count */
8373
8374     /* Build display for: Max Setup Count */
8375
8376     MaxSetupCount = GBYTE(pd, offset);
8377
8378     if (tree) {
8379
8380       proto_tree_add_text(tree, NullTVB, offset, 1, "Max Setup Count: %u", MaxSetupCount);
8381
8382     }
8383
8384     offset += 1; /* Skip Max Setup Count */
8385
8386     /* Build display for: Reserved1 */
8387
8388     Reserved1 = GBYTE(pd, offset);
8389
8390     if (tree) {
8391
8392       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved1: %u", Reserved1);
8393
8394     }
8395
8396     offset += 1; /* Skip Reserved1 */
8397
8398     /* Build display for: Flags */
8399
8400     Flags = GSHORT(pd, offset);
8401
8402     if (tree) {
8403
8404       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
8405       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
8406       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
8407                           decode_boolean_bitfield(Flags, 0x01, 16, "Also disconnect TID", "Dont disconnect TID"));
8408       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
8409                           decode_boolean_bitfield(Flags, 0x02, 16, "One way transaction", "Two way transaction"));
8410     
8411 }
8412
8413     offset += 2; /* Skip Flags */
8414
8415     /* Build display for: Timeout */
8416
8417     Timeout = GWORD(pd, offset);
8418
8419     if (tree) {
8420
8421       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
8422
8423     }
8424
8425     offset += 4; /* Skip Timeout */
8426
8427     /* Build display for: Reserved2 */
8428
8429     Reserved2 = GSHORT(pd, offset);
8430
8431     if (tree) {
8432
8433       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
8434
8435     }
8436
8437     offset += 2; /* Skip Reserved2 */
8438
8439     /* Build display for: Parameter Count */
8440
8441     ParameterCount = GSHORT(pd, offset);
8442
8443     if (tree) {
8444
8445       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
8446
8447     }
8448
8449     offset += 2; /* Skip Parameter Count */
8450
8451     /* Build display for: Parameter Offset */
8452
8453     ParameterOffset = GSHORT(pd, offset);
8454
8455     if (tree) {
8456
8457       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
8458
8459     }
8460
8461     offset += 2; /* Skip Parameter Offset */
8462
8463     /* Build display for: Data Count */
8464
8465     DataCount = GSHORT(pd, offset);
8466
8467     if (tree) {
8468
8469       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
8470
8471     }
8472
8473     offset += 2; /* Skip Data Count */
8474
8475     /* Build display for: Data Offset */
8476
8477     DataOffset = GSHORT(pd, offset);
8478
8479     if (tree) {
8480
8481       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
8482
8483     }
8484
8485     offset += 2; /* Skip Data Offset */
8486
8487     /* Build display for: Setup Count */
8488
8489     SetupCount = GBYTE(pd, offset);
8490
8491     if (tree) {
8492
8493       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
8494
8495     }
8496
8497     offset += 1; /* Skip Setup Count */
8498
8499     /* Build display for: Reserved3 */
8500
8501     Reserved3 = GBYTE(pd, offset);
8502
8503     if (tree) {
8504
8505       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
8506
8507     }
8508
8509     offset += 1; /* Skip Reserved3 */
8510
8511     /* Build display for: Setup */
8512
8513     if (SetupCount > 0) {
8514
8515       int i = SetupCount;
8516
8517       Setup = GSHORT(pd, offset);
8518
8519       request_val -> last_transact2_command = Setup;  /* Save for later */
8520
8521       if (check_col(fd, COL_INFO)) {
8522
8523         col_add_fstr(fd, COL_INFO, "%s %s", decode_trans2_name(Setup), (dirn ? "Request" : "Response"));
8524
8525       }
8526
8527       for (i = 1; i <= SetupCount; i++) {
8528         int Setup1;
8529
8530         Setup1 = GSHORT(pd, offset);
8531
8532         if (tree) {
8533
8534           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup1);
8535
8536         }
8537
8538         offset += 2; /* Skip Setup */
8539
8540       }
8541
8542     }
8543
8544     /* Build display for: Byte Count (BCC) */
8545
8546     ByteCount = GSHORT(pd, offset);
8547
8548     if (tree) {
8549
8550       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8551
8552     }
8553
8554     offset += 2; /* Skip Byte Count (BCC) */
8555
8556     /* Build display for: Transact Name */
8557
8558     if (tree) {
8559
8560       proto_tree_add_text(tree, NullTVB, offset, 2, "Transact Name: %s", decode_trans2_name(Setup));
8561
8562     }
8563
8564     if (offset % 2) {
8565
8566       /* Build display for: Pad1 */
8567
8568       Pad1 = GBYTE(pd, offset);
8569
8570       if (tree) {
8571
8572         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad1: %u", Pad1);
8573
8574       }
8575     
8576       offset += 1; /* Skip Pad1 */
8577
8578     }
8579
8580     if (ParameterCount > 0) {
8581
8582       /* Build display for: Parameters */
8583
8584       if (tree) {
8585
8586         proto_tree_add_text(tree, NullTVB, SMB_offset + ParameterOffset, ParameterCount, "Parameters: %s", format_text(pd + SMB_offset + ParameterOffset, ParameterCount));
8587
8588       }
8589
8590       offset += ParameterCount; /* Skip Parameters */
8591
8592     }
8593
8594     if (offset % 2) {
8595         
8596       /* Build display for: Pad2 */
8597
8598       Pad2 = GBYTE(pd, offset);
8599
8600       if (tree) {
8601
8602         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad2: %u", Pad2);
8603
8604       }
8605
8606       offset += 1; /* Skip Pad2 */
8607
8608     }
8609
8610     if (DataCount > 0) {
8611
8612       /* Build display for: Data */
8613
8614       Data = GBYTE(pd, offset);
8615
8616       if (tree) {
8617
8618         proto_tree_add_text(tree, NullTVB, SMB_offset + DataOffset, DataCount, "Data: %s", format_text(&pd[offset], DataCount));
8619
8620       }
8621
8622       offset += DataCount; /* Skip Data */
8623
8624     }
8625   }
8626
8627   if (dirn == 0) { /* Response(s) dissect code */
8628
8629     /* Pick up the last transact2 command and put it in the right places */
8630
8631     if (check_col(fd, COL_INFO)) {
8632
8633       col_add_fstr(fd, COL_INFO, "%s %s", decode_trans2_name(request_val -> last_transact2_command), "response");
8634
8635     }
8636
8637     /* Build display for: Word Count (WCT) */
8638
8639     WordCount = GBYTE(pd, offset);
8640
8641     if (tree) {
8642
8643       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
8644
8645     }
8646
8647     offset += 1; /* Skip Word Count (WCT) */
8648
8649     /* Build display for: Total Parameter Count */
8650
8651     TotalParameterCount = GSHORT(pd, offset);
8652
8653     if (tree) {
8654
8655       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
8656
8657     }
8658
8659     offset += 2; /* Skip Total Parameter Count */
8660
8661     /* Build display for: Total Data Count */
8662
8663     TotalDataCount = GSHORT(pd, offset);
8664
8665     if (tree) {
8666
8667       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
8668
8669     }
8670
8671     offset += 2; /* Skip Total Data Count */
8672
8673     /* Build display for: Reserved2 */
8674
8675     Reserved2 = GSHORT(pd, offset);
8676
8677     if (tree) {
8678
8679       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
8680
8681     }
8682
8683     offset += 2; /* Skip Reserved2 */
8684
8685     /* Build display for: Parameter Count */
8686
8687     ParameterCount = GSHORT(pd, offset);
8688
8689     if (tree) {
8690
8691       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
8692
8693     }
8694
8695     offset += 2; /* Skip Parameter Count */
8696
8697     /* Build display for: Parameter Offset */
8698
8699     ParameterOffset = GSHORT(pd, offset);
8700
8701     if (tree) {
8702
8703       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
8704
8705     }
8706
8707     offset += 2; /* Skip Parameter Offset */
8708
8709     /* Build display for: Parameter Displacement */
8710
8711     ParameterDisplacement = GSHORT(pd, offset);
8712
8713     if (tree) {
8714
8715       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Displacement: %u", ParameterDisplacement);
8716
8717     }
8718
8719     offset += 2; /* Skip Parameter Displacement */
8720
8721     /* Build display for: Data Count */
8722
8723     DataCount = GSHORT(pd, offset);
8724
8725     if (tree) {
8726
8727       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
8728
8729     }
8730
8731     offset += 2; /* Skip Data Count */
8732
8733     /* Build display for: Data Offset */
8734
8735     DataOffset = GSHORT(pd, offset);
8736
8737     if (tree) {
8738
8739       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
8740
8741     }
8742
8743     offset += 2; /* Skip Data Offset */
8744
8745     /* Build display for: Data Displacement */
8746
8747     DataDisplacement = GSHORT(pd, offset);
8748
8749     if (tree) {
8750
8751       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Displacement: %u", DataDisplacement);
8752
8753     }
8754
8755     offset += 2; /* Skip Data Displacement */
8756
8757     /* Build display for: Setup Count */
8758
8759     SetupCount = GBYTE(pd, offset);
8760
8761     if (tree) {
8762
8763       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
8764
8765     }
8766
8767     offset += 1; /* Skip Setup Count */
8768
8769     /* Build display for: Reserved3 */
8770
8771     Reserved3 = GBYTE(pd, offset);
8772
8773     if (tree) {
8774
8775       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
8776
8777     }
8778
8779     offset += 1; /* Skip Reserved3 */
8780
8781     /* Build display for: Setup */
8782
8783     Setup = GSHORT(pd, offset);
8784
8785     if (tree) {
8786
8787       proto_tree_add_text(tree, NullTVB, offset, 2, "Setup: %u", Setup);
8788
8789     }
8790
8791     offset += 2; /* Skip Setup */
8792
8793     /* Build display for: Byte Count (BCC) */
8794
8795     ByteCount = GSHORT(pd, offset);
8796
8797     if (tree) {
8798
8799       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
8800
8801     }
8802
8803     offset += 2; /* Skip Byte Count (BCC) */
8804
8805     /* Build display for: Pad1 */
8806
8807     Pad1 = GBYTE(pd, offset);
8808
8809     if (tree) {
8810
8811       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad1: %u", Pad1);
8812
8813     }
8814
8815     offset += 1; /* Skip Pad1 */
8816
8817     /* Build display for: Parameter */
8818
8819     if (ParameterCount > 0) {
8820
8821       if (tree) {
8822
8823         proto_tree_add_text(tree, NullTVB, offset, ParameterCount, "Parameter: %s", format_text(pd + SMB_offset + ParameterOffset, ParameterCount));
8824
8825       }
8826
8827       offset += ParameterCount; /* Skip Parameter */
8828
8829     }
8830
8831     /* Build display for: Pad2 */
8832
8833     Pad2 = GBYTE(pd, offset);
8834
8835     if (tree) {
8836
8837       proto_tree_add_text(tree, NullTVB, offset, 1, "Pad2: %u", Pad2);
8838
8839     }
8840
8841     offset += 1; /* Skip Pad2 */
8842
8843     /* Build display for: Data */
8844
8845     if (DataCount > 0) {
8846
8847       if (tree) {
8848
8849         proto_tree_add_text(tree, NullTVB, offset, DataCount, "Data: %s", format_text(pd + SMB_offset + DataOffset, DataCount));
8850
8851       }
8852
8853       offset += DataCount; /* Skip Data */
8854
8855     }
8856
8857   }
8858
8859 }
8860
8861
8862 void 
8863 dissect_transact_params(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn, int DataOffset, int DataCount, int ParameterOffset, int ParameterCount, int SetupAreaOffset, int SetupCount, const char *TransactName)
8864 {
8865   char             *TransactNameCopy;
8866   char             *trans_type = NULL, *trans_cmd, *loc_of_slash = NULL;
8867   int              index;
8868   guint8           Pad2;
8869   const gchar      *Data;
8870
8871   if (!TransactName)
8872           return;
8873
8874   TransactNameCopy = g_malloc(strlen(TransactName) + 1);
8875
8876   /* Should check for error here ... */
8877
8878   strcpy(TransactNameCopy, TransactName);
8879   if (TransactNameCopy[0] == '\\') {
8880     trans_type = TransactNameCopy + 1;  /* Skip the slash */
8881     loc_of_slash = strchr(trans_type, '\\');
8882   }
8883
8884   if (loc_of_slash) {
8885     index = loc_of_slash - trans_type;  /* Make it a real index */
8886     trans_cmd = trans_type + index + 1;
8887     trans_type[index] = '\0';
8888   }
8889   else
8890     trans_cmd = NULL;
8891
8892   if ((trans_cmd == NULL) ||
8893       (((strcmp(trans_type, "MAILSLOT") != 0) ||
8894        !dissect_mailslot_smb(pd, SetupAreaOffset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, trans_cmd, SMB_offset + DataOffset, DataCount, SMB_offset + ParameterOffset, ParameterCount)) &&
8895       ((strcmp(trans_type, "PIPE") != 0) ||
8896        !dissect_pipe_smb(pd, offset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, trans_cmd, DataOffset, DataCount, ParameterOffset, ParameterCount)))) {
8897     
8898     if (ParameterCount > 0) {
8899
8900       /* Build display for: Parameters */
8901       
8902       if (tree) {
8903
8904         proto_tree_add_text(tree, NullTVB, SMB_offset + ParameterOffset, ParameterCount, "Parameters: %s", format_text(pd + SMB_offset + ParameterOffset, ParameterCount));
8905           
8906       }
8907         
8908       offset = SMB_offset + ParameterOffset + ParameterCount; /* Skip Parameters */
8909
8910     }
8911
8912     if (offset % 2) {
8913         
8914       /* Build display for: Pad2 */
8915
8916       Pad2 = GBYTE(pd, offset);
8917
8918       if (tree) {
8919
8920         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad2: %u: %u", Pad2, offset);
8921
8922       }
8923
8924       offset += 1; /* Skip Pad2 */
8925
8926     }
8927
8928     if (DataCount > 0) {
8929
8930       /* Build display for: Data */
8931
8932       Data = pd + SMB_offset + DataOffset;
8933
8934       if (tree) {
8935
8936         proto_tree_add_text(tree, NullTVB, SMB_offset + DataOffset, DataCount, "Data: %s", format_text(pd + SMB_offset + DataOffset, DataCount));
8937
8938       }
8939
8940       offset += DataCount; /* Skip Data */
8941
8942     }
8943   }
8944
8945 }
8946
8947 void
8948 dissect_transact_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn)
8949
8950 {
8951   proto_tree    *Flags_tree;
8952   proto_item    *ti;
8953   guint8        WordCount;
8954   guint8        SetupCount;
8955   guint8        Reserved3;
8956   guint8        Reserved1;
8957   guint8        Pad1;
8958   guint8        MaxSetupCount;
8959   guint32       Timeout;
8960   guint16       TotalParameterCount;
8961   guint16       TotalDataCount;
8962   guint16       Setup = 0;
8963   guint16       Reserved2;
8964   guint16       ParameterOffset;
8965   guint16       ParameterDisplacement;
8966   guint16       ParameterCount;
8967   guint16       MaxParameterCount;
8968   guint16       MaxDataCount;
8969   guint16       Flags;
8970   guint16       DataOffset;
8971   guint16       DataDisplacement;
8972   guint16       DataCount;
8973   guint16       ByteCount;
8974   int           TNlen;
8975   const char    *TransactName;
8976   conversation_t *conversation;
8977   struct smb_request_key   request_key, *new_request_key;
8978   struct smb_request_val   *request_val;
8979  
8980   guint16       SetupAreaOffset;
8981
8982
8983   /*
8984    * Find out what conversation this packet is part of
8985    */
8986
8987   conversation = find_conversation(&pi.src, &pi.dst, pi.ptype,
8988                                    pi.srcport, pi.destport);
8989
8990   if (conversation == NULL) {  /* Create a new conversation */
8991
8992     conversation = conversation_new(&pi.src, &pi.dst, pi.ptype,
8993                                     pi.srcport, pi.destport, NULL);
8994
8995   }
8996
8997   si.conversation = conversation;  /* Save this */
8998
8999   /*
9000    * Check for and insert entry in request hash table if does not exist
9001    */
9002   request_key.conversation = conversation->index;
9003   request_key.mid          = si.mid;
9004
9005   request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key);
9006
9007   if (!request_val) { /* Create one */
9008
9009     new_request_key = g_mem_chunk_alloc(smb_request_keys);
9010     new_request_key -> conversation = conversation -> index;
9011     new_request_key -> mid          = si.mid;
9012
9013     request_val = g_mem_chunk_alloc(smb_request_vals);
9014     request_val -> mid = si.mid;
9015     request_val -> last_transact_command = NULL;
9016     request_val -> last_param_descrip = NULL;
9017     request_val -> last_data_descrip = NULL;
9018
9019     g_hash_table_insert(smb_request_hash, new_request_key, request_val);
9020
9021   }
9022
9023   si.request_val = request_val;  /* Save this for later */
9024
9025   if (dirn == 1) { /* Request(s) dissect code */
9026
9027     /* Build display for: Word Count (WCT) */
9028
9029     WordCount = GBYTE(pd, offset);
9030
9031     if (tree) {
9032
9033       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9034
9035     }
9036
9037     offset += 1; /* Skip Word Count (WCT) */
9038
9039     /* Build display for: Total Parameter Count */
9040
9041     TotalParameterCount = GSHORT(pd, offset);
9042
9043     if (tree) {
9044
9045       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
9046
9047     }
9048
9049     offset += 2; /* Skip Total Parameter Count */
9050
9051     /* Build display for: Total Data Count */
9052
9053     TotalDataCount = GSHORT(pd, offset);
9054
9055     if (tree) {
9056
9057       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
9058
9059     }
9060
9061     offset += 2; /* Skip Total Data Count */
9062
9063     /* Build display for: Max Parameter Count */
9064
9065     MaxParameterCount = GSHORT(pd, offset);
9066
9067     if (tree) {
9068
9069       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Parameter Count: %u", MaxParameterCount);
9070
9071     }
9072
9073     offset += 2; /* Skip Max Parameter Count */
9074
9075     /* Build display for: Max Data Count */
9076
9077     MaxDataCount = GSHORT(pd, offset);
9078
9079     if (tree) {
9080
9081       proto_tree_add_text(tree, NullTVB, offset, 2, "Max Data Count: %u", MaxDataCount);
9082
9083     }
9084
9085     offset += 2; /* Skip Max Data Count */
9086
9087     /* Build display for: Max Setup Count */
9088
9089     MaxSetupCount = GBYTE(pd, offset);
9090
9091     if (tree) {
9092
9093       proto_tree_add_text(tree, NullTVB, offset, 1, "Max Setup Count: %u", MaxSetupCount);
9094
9095     }
9096
9097     offset += 1; /* Skip Max Setup Count */
9098
9099     /* Build display for: Reserved1 */
9100
9101     Reserved1 = GBYTE(pd, offset);
9102
9103     if (tree) {
9104
9105       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved1: %u", Reserved1);
9106
9107     }
9108
9109     offset += 1; /* Skip Reserved1 */
9110
9111     /* Build display for: Flags */
9112
9113     Flags = GSHORT(pd, offset);
9114
9115     if (tree) {
9116
9117       ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Flags: 0x%02x", Flags);
9118       Flags_tree = proto_item_add_subtree(ti, ett_smb_flags);
9119       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9120                           decode_boolean_bitfield(Flags, 0x01, 16, "Also disconnect TID", "Dont disconnect TID"));
9121       proto_tree_add_text(Flags_tree, NullTVB, offset, 2, "%s",
9122                           decode_boolean_bitfield(Flags, 0x02, 16, "One way transaction", "Two way transaction"));
9123     
9124 }
9125
9126     offset += 2; /* Skip Flags */
9127
9128     /* Build display for: Timeout */
9129
9130     Timeout = GWORD(pd, offset);
9131
9132     if (tree) {
9133
9134       proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
9135
9136     }
9137
9138     offset += 4; /* Skip Timeout */
9139
9140     /* Build display for: Reserved2 */
9141
9142     Reserved2 = GSHORT(pd, offset);
9143
9144     if (tree) {
9145
9146       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
9147
9148     }
9149
9150     offset += 2; /* Skip Reserved2 */
9151
9152     /* Build display for: Parameter Count */
9153
9154     ParameterCount = GSHORT(pd, offset);
9155
9156     if (tree) {
9157
9158       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
9159
9160     }
9161
9162     offset += 2; /* Skip Parameter Count */
9163
9164     /* Build display for: Parameter Offset */
9165
9166     ParameterOffset = GSHORT(pd, offset);
9167
9168     if (tree) {
9169
9170       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
9171
9172     }
9173
9174     offset += 2; /* Skip Parameter Offset */
9175
9176     /* Build display for: Data Count */
9177
9178     DataCount = GSHORT(pd, offset);
9179
9180     if (tree) {
9181
9182       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
9183
9184     }
9185
9186     offset += 2; /* Skip Data Count */
9187
9188     /* Build display for: Data Offset */
9189
9190     DataOffset = GSHORT(pd, offset);
9191
9192     if (tree) {
9193
9194       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9195
9196     }
9197
9198     offset += 2; /* Skip Data Offset */
9199
9200     /* Build display for: Setup Count */
9201
9202     SetupCount = GBYTE(pd, offset);
9203
9204     if (tree) {
9205
9206       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
9207
9208     }
9209
9210     offset += 1; /* Skip Setup Count */
9211
9212     /* Build display for: Reserved3 */
9213
9214     Reserved3 = GBYTE(pd, offset);
9215
9216     if (tree) {
9217
9218       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
9219     }
9220
9221     offset += 1; /* Skip Reserved3 */
9222  
9223     SetupAreaOffset = offset;
9224
9225     /* Build display for: Setup */
9226
9227     if (SetupCount > 0) {
9228
9229       int i = SetupCount;
9230
9231       Setup = GSHORT(pd, offset);
9232
9233       for (i = 1; i <= SetupCount; i++) {
9234         
9235         Setup = GSHORT(pd, offset);
9236
9237         if (tree) {
9238
9239           proto_tree_add_text(tree, NullTVB, offset, 2, "Setup%i: %u", i, Setup);
9240
9241         }
9242
9243         offset += 2; /* Skip Setup */
9244
9245       }
9246
9247     }
9248
9249     /* Build display for: Byte Count (BCC) */
9250
9251     ByteCount = GSHORT(pd, offset);
9252
9253     if (tree) {
9254
9255       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9256
9257     }
9258
9259     offset += 2; /* Skip Byte Count (BCC) */
9260
9261     /* Build display for: Transact Name */
9262
9263     /* Watch out for Unicode names */
9264
9265     if (si.unicode) {
9266
9267       if (offset % 2) offset++;   /* Looks like a pad byte there sometimes */
9268
9269       TransactName = unicode_to_str(pd + offset, &TNlen);
9270       TNlen += 2;
9271
9272     }
9273     else { 
9274       TransactName = pd + offset;
9275       TNlen = strlen(TransactName) + 1;
9276     }
9277
9278     if (request_val -> last_transact_command) g_free(request_val -> last_transact_command);
9279
9280     request_val -> last_transact_command = g_malloc(strlen(TransactName) + 1);
9281
9282     if (request_val -> last_transact_command) 
9283       strcpy(request_val -> last_transact_command, TransactName);
9284
9285     if (check_col(fd, COL_INFO)) {
9286
9287       col_add_fstr(fd, COL_INFO, "%s %s", TransactName, (dirn ? "Request" : "Response"));
9288
9289     }
9290
9291     if (tree) {
9292
9293       proto_tree_add_text(tree, NullTVB, offset, TNlen, "Transact Name: %s", TransactName);
9294
9295     }
9296
9297     offset += TNlen; /* Skip Transact Name */
9298     if (si.unicode) offset += 2;   /* There are two more extraneous bytes there*/
9299
9300     if (offset % 2) {
9301
9302       /* Build display for: Pad1 */
9303
9304       Pad1 = GBYTE(pd, offset);
9305
9306       if (tree) {
9307
9308         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad1: %u", Pad1);
9309
9310       }
9311     
9312       offset += 1; /* Skip Pad1 */
9313
9314     }
9315
9316     /* Let's see if we can decode this */
9317
9318     dissect_transact_params(pd, offset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, DataOffset, DataCount, ParameterOffset, ParameterCount, SetupAreaOffset, SetupCount, TransactName);
9319
9320   }
9321
9322   if (dirn == 0) { /* Response(s) dissect code */
9323
9324     if (check_col(fd, COL_INFO)) {
9325       if ( request_val -> last_transact_command )
9326         col_add_fstr(fd, COL_INFO, "%s %s", request_val -> last_transact_command, "Response");
9327       else col_add_fstr(fd, COL_INFO, "Response to unknown message");
9328
9329     }
9330
9331     /* Build display for: Word Count (WCT) */
9332
9333     WordCount = GBYTE(pd, offset);
9334
9335     if (tree) {
9336
9337       proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
9338
9339     }
9340
9341     offset += 1; /* Skip Word Count (WCT) */
9342
9343     /* Build display for: Total Parameter Count */
9344
9345     TotalParameterCount = GSHORT(pd, offset);
9346
9347     if (tree) {
9348
9349       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Parameter Count: %u", TotalParameterCount);
9350
9351     }
9352
9353     offset += 2; /* Skip Total Parameter Count */
9354
9355     /* Build display for: Total Data Count */
9356
9357     TotalDataCount = GSHORT(pd, offset);
9358
9359     if (tree) {
9360
9361       proto_tree_add_text(tree, NullTVB, offset, 2, "Total Data Count: %u", TotalDataCount);
9362
9363     }
9364
9365     offset += 2; /* Skip Total Data Count */
9366
9367     /* Build display for: Reserved2 */
9368
9369     Reserved2 = GSHORT(pd, offset);
9370
9371     if (tree) {
9372
9373       proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved2: %u", Reserved2);
9374
9375     }
9376
9377     offset += 2; /* Skip Reserved2 */
9378
9379     /* Build display for: Parameter Count */
9380
9381     ParameterCount = GSHORT(pd, offset);
9382
9383     if (tree) {
9384
9385       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Count: %u", ParameterCount);
9386
9387     }
9388
9389     offset += 2; /* Skip Parameter Count */
9390
9391     /* Build display for: Parameter Offset */
9392
9393     ParameterOffset = GSHORT(pd, offset);
9394
9395     if (tree) {
9396
9397       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Offset: %u", ParameterOffset);
9398
9399     }
9400
9401     offset += 2; /* Skip Parameter Offset */
9402
9403     /* Build display for: Parameter Displacement */
9404
9405     ParameterDisplacement = GSHORT(pd, offset);
9406
9407     if (tree) {
9408
9409       proto_tree_add_text(tree, NullTVB, offset, 2, "Parameter Displacement: %u", ParameterDisplacement);
9410
9411     }
9412
9413     offset += 2; /* Skip Parameter Displacement */
9414
9415     /* Build display for: Data Count */
9416
9417     DataCount = GSHORT(pd, offset);
9418
9419     if (tree) {
9420
9421       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Count: %u", DataCount);
9422
9423     }
9424
9425     offset += 2; /* Skip Data Count */
9426
9427     /* Build display for: Data Offset */
9428
9429     DataOffset = GSHORT(pd, offset);
9430
9431     if (tree) {
9432
9433       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
9434
9435     }
9436
9437     offset += 2; /* Skip Data Offset */
9438
9439     /* Build display for: Data Displacement */
9440
9441     DataDisplacement = GSHORT(pd, offset);
9442
9443     if (tree) {
9444
9445       proto_tree_add_text(tree, NullTVB, offset, 2, "Data Displacement: %u", DataDisplacement);
9446
9447     }
9448
9449     offset += 2; /* Skip Data Displacement */
9450
9451     /* Build display for: Setup Count */
9452
9453     SetupCount = GBYTE(pd, offset);
9454
9455     if (tree) {
9456
9457       proto_tree_add_text(tree, NullTVB, offset, 1, "Setup Count: %u", SetupCount);
9458
9459     }
9460
9461     offset += 1; /* Skip Setup Count */
9462
9463  
9464     /* Build display for: Reserved3 */
9465
9466     Reserved3 = GBYTE(pd, offset);
9467
9468     if (tree) {
9469
9470       proto_tree_add_text(tree, NullTVB, offset, 1, "Reserved3: %u", Reserved3);
9471
9472     }
9473
9474  
9475     offset += 1; /* Skip Reserved3 */
9476  
9477     SetupAreaOffset = offset;   
9478
9479     /* Build display for: Setup */
9480
9481     if (SetupCount > 0) {
9482
9483       /* Hmmm, should code for all setup words ... */
9484
9485       Setup = GSHORT(pd, offset);
9486
9487       if (tree) {
9488
9489         proto_tree_add_text(tree, NullTVB, offset, 2, "Setup: %u", Setup);
9490
9491       }
9492
9493     offset += 2; /* Skip Setup */
9494
9495     }
9496
9497     /* Build display for: Byte Count (BCC) */
9498
9499     ByteCount = GSHORT(pd, offset);
9500
9501     if (tree) {
9502
9503       proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
9504
9505     }
9506
9507     offset += 2; /* Skip Byte Count (BCC) */
9508
9509     /* Build display for: Pad1 */
9510
9511     if (offset % 2) {
9512
9513       Pad1 = GBYTE(pd, offset);
9514
9515       if (tree) {
9516
9517         proto_tree_add_text(tree, NullTVB, offset, 1, "Pad1: %u", Pad1);
9518
9519       }
9520
9521       offset += 1; /* Skip Pad1 */
9522
9523     }
9524
9525     dissect_transact_params(pd, offset, fd, parent, tree, si, max_data, SMB_offset, errcode, dirn, DataOffset, DataCount, ParameterOffset, ParameterCount, SetupAreaOffset, SetupCount, si.request_val -> last_transact_command);
9526
9527   }
9528
9529 }
9530
9531
9532
9533
9534
9535 void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int, int) = {
9536
9537   dissect_unknown_smb,      /* unknown SMB 0x00 */
9538   dissect_unknown_smb,      /* unknown SMB 0x01 */
9539   dissect_unknown_smb,      /* SMBopen open a file */
9540   dissect_create_file_smb,  /* SMBcreate create a file */
9541   dissect_close_smb,        /* SMBclose close a file */
9542   dissect_flush_file_smb,   /* SMBflush flush a file */
9543   dissect_delete_file_smb,  /* SMBunlink delete a file */
9544   dissect_rename_file_smb,  /* SMBmv rename a file */
9545   dissect_get_file_attr_smb,/* SMBgetatr get file attributes */
9546   dissect_set_file_attr_smb,/* SMBsetatr set file attributes */
9547   dissect_read_file_smb,    /* SMBread read from a file */
9548   dissect_write_file_smb,   /* SMBwrite write to a file */
9549   dissect_lock_bytes_smb,   /* SMBlock lock a byte range */
9550   dissect_unlock_bytes_smb, /* SMBunlock unlock a byte range */
9551   dissect_create_temporary_file_smb,/* SMBctemp create a temporary file */
9552   dissect_unknown_smb,      /* SMBmknew make a new file */
9553   dissect_checkdir_smb,     /* SMBchkpth check a directory path */
9554   dissect_process_exit_smb,      /* SMBexit process exit */
9555   dissect_unknown_smb,      /* SMBlseek seek */
9556   dissect_lock_and_read_smb,/* SMBlockread Lock a range and read it */
9557   dissect_write_and_unlock_smb,/* SMBwriteunlock Unlock a range and then write */
9558   dissect_unknown_smb,      /* unknown SMB 0x15 */
9559   dissect_unknown_smb,      /* unknown SMB 0x16 */
9560   dissect_unknown_smb,      /* unknown SMB 0x17 */
9561   dissect_unknown_smb,      /* unknown SMB 0x18 */
9562   dissect_unknown_smb,      /* unknown SMB 0x19 */
9563   dissect_read_raw_smb,     /* SMBreadBraw read block raw */
9564   dissect_read_mpx_smb,     /* SMBreadBmpx read block multiplexed */
9565   dissect_unknown_smb,      /* SMBreadBs read block (secondary response) */
9566   dissect_write_raw_smb,    /* SMBwriteBraw write block raw */
9567   dissect_write_mpx_smb,    /* SMBwriteBmpx write block multiplexed */
9568   dissect_unknown_smb,      /* SMBwriteBs write block (secondary request) */
9569   dissect_unknown_smb,      /* SMBwriteC write complete response */
9570   dissect_unknown_smb,      /* unknown SMB 0x21 */
9571   dissect_set_info2_smb,    /* SMBsetattrE set file attributes expanded */
9572   dissect_query_info2_smb,  /* SMBgetattrE get file attributes expanded */
9573   dissect_locking_andx_smb, /* SMBlockingX lock/unlock byte ranges and X */
9574   dissect_transact_smb,      /* SMBtrans transaction - name, bytes in/out */
9575   dissect_unknown_smb,      /* SMBtranss transaction (secondary request/response) */
9576   dissect_unknown_smb,      /* SMBioctl IOCTL */
9577   dissect_unknown_smb,      /* SMBioctls IOCTL (secondary request/response) */
9578   dissect_unknown_smb,      /* SMBcopy copy */
9579   dissect_move_smb,      /* SMBmove move */
9580   dissect_unknown_smb,      /* SMBecho echo */
9581   dissect_unknown_smb,      /* SMBwriteclose write a file and then close it */
9582   dissect_open_andx_smb,      /* SMBopenX open and X */
9583   dissect_unknown_smb,      /* SMBreadX read and X */
9584   dissect_unknown_smb,      /* SMBwriteX write and X */
9585   dissect_unknown_smb,      /* unknown SMB 0x30 */
9586   dissect_unknown_smb,      /* unknown SMB 0x31 */
9587   dissect_transact2_smb,    /* unknown SMB 0x32 */
9588   dissect_unknown_smb,      /* unknown SMB 0x33 */
9589   dissect_find_close2_smb,  /* unknown SMB 0x34 */
9590   dissect_unknown_smb,      /* unknown SMB 0x35 */
9591   dissect_unknown_smb,      /* unknown SMB 0x36 */
9592   dissect_unknown_smb,      /* unknown SMB 0x37 */
9593   dissect_unknown_smb,      /* unknown SMB 0x38 */
9594   dissect_unknown_smb,      /* unknown SMB 0x39 */
9595   dissect_unknown_smb,      /* unknown SMB 0x3a */
9596   dissect_unknown_smb,      /* unknown SMB 0x3b */
9597   dissect_unknown_smb,      /* unknown SMB 0x3c */
9598   dissect_unknown_smb,      /* unknown SMB 0x3d */
9599   dissect_unknown_smb,      /* unknown SMB 0x3e */
9600   dissect_unknown_smb,      /* unknown SMB 0x3f */
9601   dissect_unknown_smb,      /* unknown SMB 0x40 */
9602   dissect_unknown_smb,      /* unknown SMB 0x41 */
9603   dissect_unknown_smb,      /* unknown SMB 0x42 */
9604   dissect_unknown_smb,      /* unknown SMB 0x43 */
9605   dissect_unknown_smb,      /* unknown SMB 0x44 */
9606   dissect_unknown_smb,      /* unknown SMB 0x45 */
9607   dissect_unknown_smb,      /* unknown SMB 0x46 */
9608   dissect_unknown_smb,      /* unknown SMB 0x47 */
9609   dissect_unknown_smb,      /* unknown SMB 0x48 */
9610   dissect_unknown_smb,      /* unknown SMB 0x49 */
9611   dissect_unknown_smb,      /* unknown SMB 0x4a */
9612   dissect_unknown_smb,      /* unknown SMB 0x4b */
9613   dissect_unknown_smb,      /* unknown SMB 0x4c */
9614   dissect_unknown_smb,      /* unknown SMB 0x4d */
9615   dissect_unknown_smb,      /* unknown SMB 0x4e */
9616   dissect_unknown_smb,      /* unknown SMB 0x4f */
9617   dissect_unknown_smb,      /* unknown SMB 0x50 */
9618   dissect_unknown_smb,      /* unknown SMB 0x51 */
9619   dissect_unknown_smb,      /* unknown SMB 0x52 */
9620   dissect_unknown_smb,      /* unknown SMB 0x53 */
9621   dissect_unknown_smb,      /* unknown SMB 0x54 */
9622   dissect_unknown_smb,      /* unknown SMB 0x55 */
9623   dissect_unknown_smb,      /* unknown SMB 0x56 */
9624   dissect_unknown_smb,      /* unknown SMB 0x57 */
9625   dissect_unknown_smb,      /* unknown SMB 0x58 */
9626   dissect_unknown_smb,      /* unknown SMB 0x59 */
9627   dissect_unknown_smb,      /* unknown SMB 0x5a */
9628   dissect_unknown_smb,      /* unknown SMB 0x5b */
9629   dissect_unknown_smb,      /* unknown SMB 0x5c */
9630   dissect_unknown_smb,      /* unknown SMB 0x5d */
9631   dissect_unknown_smb,      /* unknown SMB 0x5e */
9632   dissect_unknown_smb,      /* unknown SMB 0x5f */
9633   dissect_unknown_smb,      /* unknown SMB 0x60 */
9634   dissect_unknown_smb,      /* unknown SMB 0x61 */
9635   dissect_unknown_smb,      /* unknown SMB 0x62 */
9636   dissect_unknown_smb,      /* unknown SMB 0x63 */
9637   dissect_unknown_smb,      /* unknown SMB 0x64 */
9638   dissect_unknown_smb,      /* unknown SMB 0x65 */
9639   dissect_unknown_smb,      /* unknown SMB 0x66 */
9640   dissect_unknown_smb,      /* unknown SMB 0x67 */
9641   dissect_unknown_smb,      /* unknown SMB 0x68 */
9642   dissect_unknown_smb,      /* unknown SMB 0x69 */
9643   dissect_unknown_smb,      /* unknown SMB 0x6a */
9644   dissect_unknown_smb,      /* unknown SMB 0x6b */
9645   dissect_unknown_smb,      /* unknown SMB 0x6c */
9646   dissect_unknown_smb,      /* unknown SMB 0x6d */
9647   dissect_unknown_smb,      /* unknown SMB 0x6e */
9648   dissect_unknown_smb,      /* unknown SMB 0x6f */
9649   dissect_treecon_smb,      /* SMBtcon tree connect */
9650   dissect_tdis_smb,         /* SMBtdis tree disconnect */
9651   dissect_negprot_smb,      /* SMBnegprot negotiate a protocol */
9652   dissect_ssetup_andx_smb,  /* SMBsesssetupX Session Set Up & X (including User Logon) */
9653   dissect_logoff_andx_smb,  /* SMBlogof Logoff & X */
9654   dissect_tcon_andx_smb,    /* SMBtconX tree connect and X */
9655   dissect_unknown_smb,      /* unknown SMB 0x76 */
9656   dissect_unknown_smb,      /* unknown SMB 0x77 */
9657   dissect_unknown_smb,      /* unknown SMB 0x78 */
9658   dissect_unknown_smb,      /* unknown SMB 0x79 */
9659   dissect_unknown_smb,      /* unknown SMB 0x7a */
9660   dissect_unknown_smb,      /* unknown SMB 0x7b */
9661   dissect_unknown_smb,      /* unknown SMB 0x7c */
9662   dissect_unknown_smb,      /* unknown SMB 0x7d */
9663   dissect_unknown_smb,      /* unknown SMB 0x7e */
9664   dissect_unknown_smb,      /* unknown SMB 0x7f */
9665   dissect_get_disk_attr_smb,/* SMBdskattr get disk attributes */
9666   dissect_search_dir_smb,   /* SMBsearch search a directory */
9667   dissect_unknown_smb,      /* SMBffirst find first */
9668   dissect_unknown_smb,      /* SMBfunique find unique */
9669   dissect_unknown_smb,      /* SMBfclose find close */
9670   dissect_unknown_smb,      /* unknown SMB 0x85 */
9671   dissect_unknown_smb,      /* unknown SMB 0x86 */
9672   dissect_unknown_smb,      /* unknown SMB 0x87 */
9673   dissect_unknown_smb,      /* unknown SMB 0x88 */
9674   dissect_unknown_smb,      /* unknown SMB 0x89 */
9675   dissect_unknown_smb,      /* unknown SMB 0x8a */
9676   dissect_unknown_smb,      /* unknown SMB 0x8b */
9677   dissect_unknown_smb,      /* unknown SMB 0x8c */
9678   dissect_unknown_smb,      /* unknown SMB 0x8d */
9679   dissect_unknown_smb,      /* unknown SMB 0x8e */
9680   dissect_unknown_smb,      /* unknown SMB 0x8f */
9681   dissect_unknown_smb,      /* unknown SMB 0x90 */
9682   dissect_unknown_smb,      /* unknown SMB 0x91 */
9683   dissect_unknown_smb,      /* unknown SMB 0x92 */
9684   dissect_unknown_smb,      /* unknown SMB 0x93 */
9685   dissect_unknown_smb,      /* unknown SMB 0x94 */
9686   dissect_unknown_smb,      /* unknown SMB 0x95 */
9687   dissect_unknown_smb,      /* unknown SMB 0x96 */
9688   dissect_unknown_smb,      /* unknown SMB 0x97 */
9689   dissect_unknown_smb,      /* unknown SMB 0x98 */
9690   dissect_unknown_smb,      /* unknown SMB 0x99 */
9691   dissect_unknown_smb,      /* unknown SMB 0x9a */
9692   dissect_unknown_smb,      /* unknown SMB 0x9b */
9693   dissect_unknown_smb,      /* unknown SMB 0x9c */
9694   dissect_unknown_smb,      /* unknown SMB 0x9d */
9695   dissect_unknown_smb,      /* unknown SMB 0x9e */
9696   dissect_unknown_smb,      /* unknown SMB 0x9f */
9697   dissect_unknown_smb,      /* unknown SMB 0xa0 */
9698   dissect_unknown_smb,      /* unknown SMB 0xa1 */
9699   dissect_unknown_smb,      /* unknown SMB 0xa2 */
9700   dissect_unknown_smb,      /* unknown SMB 0xa3 */
9701   dissect_unknown_smb,      /* unknown SMB 0xa4 */
9702   dissect_unknown_smb,      /* unknown SMB 0xa5 */
9703   dissect_unknown_smb,      /* unknown SMB 0xa6 */
9704   dissect_unknown_smb,      /* unknown SMB 0xa7 */
9705   dissect_unknown_smb,      /* unknown SMB 0xa8 */
9706   dissect_unknown_smb,      /* unknown SMB 0xa9 */
9707   dissect_unknown_smb,      /* unknown SMB 0xaa */
9708   dissect_unknown_smb,      /* unknown SMB 0xab */
9709   dissect_unknown_smb,      /* unknown SMB 0xac */
9710   dissect_unknown_smb,      /* unknown SMB 0xad */
9711   dissect_unknown_smb,      /* unknown SMB 0xae */
9712   dissect_unknown_smb,      /* unknown SMB 0xaf */
9713   dissect_unknown_smb,      /* unknown SMB 0xb0 */
9714   dissect_unknown_smb,      /* unknown SMB 0xb1 */
9715   dissect_unknown_smb,      /* unknown SMB 0xb2 */
9716   dissect_unknown_smb,      /* unknown SMB 0xb3 */
9717   dissect_unknown_smb,      /* unknown SMB 0xb4 */
9718   dissect_unknown_smb,      /* unknown SMB 0xb5 */
9719   dissect_unknown_smb,      /* unknown SMB 0xb6 */
9720   dissect_unknown_smb,      /* unknown SMB 0xb7 */
9721   dissect_unknown_smb,      /* unknown SMB 0xb8 */
9722   dissect_unknown_smb,      /* unknown SMB 0xb9 */
9723   dissect_unknown_smb,      /* unknown SMB 0xba */
9724   dissect_unknown_smb,      /* unknown SMB 0xbb */
9725   dissect_unknown_smb,      /* unknown SMB 0xbc */
9726   dissect_unknown_smb,      /* unknown SMB 0xbd */
9727   dissect_unknown_smb,      /* unknown SMB 0xbe */
9728   dissect_unknown_smb,      /* unknown SMB 0xbf */
9729   dissect_unknown_smb,      /* SMBsplopen open a print spool file */
9730   dissect_write_print_file_smb,/* SMBsplwr write to a print spool file */
9731   dissect_close_print_file_smb,/* SMBsplclose close a print spool file */
9732   dissect_get_print_queue_smb, /* SMBsplretq return print queue */
9733   dissect_unknown_smb,      /* unknown SMB 0xc4 */
9734   dissect_unknown_smb,      /* unknown SMB 0xc5 */
9735   dissect_unknown_smb,      /* unknown SMB 0xc6 */
9736   dissect_unknown_smb,      /* unknown SMB 0xc7 */
9737   dissect_unknown_smb,      /* unknown SMB 0xc8 */
9738   dissect_unknown_smb,      /* unknown SMB 0xc9 */
9739   dissect_unknown_smb,      /* unknown SMB 0xca */
9740   dissect_unknown_smb,      /* unknown SMB 0xcb */
9741   dissect_unknown_smb,      /* unknown SMB 0xcc */
9742   dissect_unknown_smb,      /* unknown SMB 0xcd */
9743   dissect_unknown_smb,      /* unknown SMB 0xce */
9744   dissect_unknown_smb,      /* unknown SMB 0xcf */
9745   dissect_unknown_smb,      /* SMBsends send a single block message */
9746   dissect_unknown_smb,      /* SMBsendb send a broadcast message */
9747   dissect_unknown_smb,      /* SMBfwdname forward user name */
9748   dissect_unknown_smb,      /* SMBcancelf cancel forward */
9749   dissect_unknown_smb,      /* SMBgetmac get a machine name */
9750   dissect_unknown_smb,      /* SMBsendstrt send start of multi-block message */
9751   dissect_unknown_smb,      /* SMBsendend send end of multi-block message */
9752   dissect_unknown_smb,      /* SMBsendtxt send text of multi-block message */
9753   dissect_unknown_smb,      /* unknown SMB 0xd8 */
9754   dissect_unknown_smb,      /* unknown SMB 0xd9 */
9755   dissect_unknown_smb,      /* unknown SMB 0xda */
9756   dissect_unknown_smb,      /* unknown SMB 0xdb */
9757   dissect_unknown_smb,      /* unknown SMB 0xdc */
9758   dissect_unknown_smb,      /* unknown SMB 0xdd */
9759   dissect_unknown_smb,      /* unknown SMB 0xde */
9760   dissect_unknown_smb,      /* unknown SMB 0xdf */
9761   dissect_unknown_smb,      /* unknown SMB 0xe0 */
9762   dissect_unknown_smb,      /* unknown SMB 0xe1 */
9763   dissect_unknown_smb,      /* unknown SMB 0xe2 */
9764   dissect_unknown_smb,      /* unknown SMB 0xe3 */
9765   dissect_unknown_smb,      /* unknown SMB 0xe4 */
9766   dissect_unknown_smb,      /* unknown SMB 0xe5 */
9767   dissect_unknown_smb,      /* unknown SMB 0xe6 */
9768   dissect_unknown_smb,      /* unknown SMB 0xe7 */
9769   dissect_unknown_smb,      /* unknown SMB 0xe8 */
9770   dissect_unknown_smb,      /* unknown SMB 0xe9 */
9771   dissect_unknown_smb,      /* unknown SMB 0xea */
9772   dissect_unknown_smb,      /* unknown SMB 0xeb */
9773   dissect_unknown_smb,      /* unknown SMB 0xec */
9774   dissect_unknown_smb,      /* unknown SMB 0xed */
9775   dissect_unknown_smb,      /* unknown SMB 0xee */
9776   dissect_unknown_smb,      /* unknown SMB 0xef */
9777   dissect_unknown_smb,      /* unknown SMB 0xf0 */
9778   dissect_unknown_smb,      /* unknown SMB 0xf1 */
9779   dissect_unknown_smb,      /* unknown SMB 0xf2 */
9780   dissect_unknown_smb,      /* unknown SMB 0xf3 */
9781   dissect_unknown_smb,      /* unknown SMB 0xf4 */
9782   dissect_unknown_smb,      /* unknown SMB 0xf5 */
9783   dissect_unknown_smb,      /* unknown SMB 0xf6 */
9784   dissect_unknown_smb,      /* unknown SMB 0xf7 */
9785   dissect_unknown_smb,      /* unknown SMB 0xf8 */
9786   dissect_unknown_smb,      /* unknown SMB 0xf9 */
9787   dissect_unknown_smb,      /* unknown SMB 0xfa */
9788   dissect_unknown_smb,      /* unknown SMB 0xfb */
9789   dissect_unknown_smb,      /* unknown SMB 0xfc */
9790   dissect_unknown_smb,      /* unknown SMB 0xfd */
9791   dissect_unknown_smb,      /* SMBinvalid invalid command */
9792   dissect_unknown_smb       /* unknown SMB 0xff */
9793
9794 };
9795
9796 static const value_string errcls_types[] = {
9797   { SMB_SUCCESS, "Success"},
9798   { SMB_ERRDOS, "DOS Error"},
9799   { SMB_ERRSRV, "Server Error"},
9800   { SMB_ERRHRD, "Hardware Error"},
9801   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
9802   { 0, 0}
9803 };
9804
9805 char *decode_smb_name(unsigned char cmd)
9806 {
9807
9808   return(SMB_names[cmd]);
9809
9810 }
9811
9812 static const value_string DOS_errors[] = {
9813   {SMBE_badfunc, "Invalid function (or system call)"},
9814   {SMBE_badfile, "File not found (pathname error)"},
9815   {SMBE_badpath, "Directory not found"},
9816   {SMBE_nofids, "Too many open files"},
9817   {SMBE_noaccess, "Access denied"},
9818   {SMBE_badfid, "Invalid fid"},
9819   {SMBE_nomem,  "Out of memory"},
9820   {SMBE_badmem, "Invalid memory block address"},
9821   {SMBE_badenv, "Invalid environment"},
9822   {SMBE_badaccess, "Invalid open mode"},
9823   {SMBE_baddata, "Invalid data (only from ioctl call)"},
9824   {SMBE_res, "Reserved error code?"}, 
9825   {SMBE_baddrive, "Invalid drive"},
9826   {SMBE_remcd, "Attempt to delete current directory"},
9827   {SMBE_diffdevice, "Rename/move across different filesystems"},
9828   {SMBE_nofiles, "no more files found in file search"},
9829   {SMBE_badshare, "Share mode on file conflict with open mode"},
9830   {SMBE_lock, "Lock request conflicts with existing lock"},
9831   {SMBE_unsup, "Request unsupported, returned by Win 95"},
9832   {SMBE_filexists, "File in operation already exists"},
9833   {SMBE_cannotopen, "Cannot open the file specified"},
9834   {SMBE_unknownlevel, "Unknown level??"},
9835   {SMBE_badpipe, "Named pipe invalid"},
9836   {SMBE_pipebusy, "All instances of pipe are busy"},
9837   {SMBE_pipeclosing, "Named pipe close in progress"},
9838   {SMBE_notconnected, "No process on other end of named pipe"},
9839   {SMBE_moredata, "More data to be returned"},
9840   {SMBE_baddirectory,  "Invalid directory name in a path."},
9841   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
9842   {SMBE_eas_nsup, "Extended attributes not supported"},
9843   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
9844   {SMBE_unknownipc, "Unknown IPC Operation"},
9845   {SMBE_noipc, "Don't support ipc"},
9846   {0, 0}
9847   };
9848
9849 /* Error codes for the ERRSRV class */
9850
9851 static const value_string SRV_errors[] = {
9852   {SMBE_error, "Non specific error code"},
9853   {SMBE_badpw, "Bad password"},
9854   {SMBE_badtype, "Reserved"},
9855   {SMBE_access, "No permissions to perform the requested operation"},
9856   {SMBE_invnid, "TID invalid"},
9857   {SMBE_invnetname, "Invalid network name. Service not found"},
9858   {SMBE_invdevice, "Invalid device"},
9859   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
9860   {SMBE_qfull, "Print queue full"},
9861   {SMBE_qtoobig, "Queued item too big"},
9862   {SMBE_qeof, "EOF on print queue dump"},
9863   {SMBE_invpfid, "Invalid print file in smb_fid"},
9864   {SMBE_smbcmd, "Unrecognised command"},
9865   {SMBE_srverror, "SMB server internal error"},
9866   {SMBE_filespecs, "Fid and pathname invalid combination"},
9867   {SMBE_badlink, "Bad link in request ???"},
9868   {SMBE_badpermits, "Access specified for a file is not valid"},
9869   {SMBE_badpid, "Bad process id in request"},
9870   {SMBE_setattrmode, "Attribute mode invalid"},
9871   {SMBE_paused, "Message server paused"},
9872   {SMBE_msgoff, "Not receiving messages"},
9873   {SMBE_noroom, "No room for message"},
9874   {SMBE_rmuns, "Too many remote usernames"},
9875   {SMBE_timeout, "Operation timed out"},
9876   {SMBE_noresource, "No resources currently available for request."},
9877   {SMBE_toomanyuids, "Too many userids"},
9878   {SMBE_baduid, "Bad userid"},
9879   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
9880   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
9881   {SMBE_contMPX, "Resume MPX mode"},
9882   {SMBE_badPW, "Bad Password???"},
9883   {SMBE_nosupport, "Operation not supported???"},
9884   { 0, 0}
9885 };
9886
9887 /* Error codes for the ERRHRD class */
9888
9889 static const value_string HRD_errors[] = {
9890   {SMBE_nowrite, "read only media"},
9891   {SMBE_badunit, "Unknown device"},
9892   {SMBE_notready, "Drive not ready"},
9893   {SMBE_badcmd, "Unknown command"},
9894   {SMBE_data, "Data (CRC) error"},
9895   {SMBE_badreq, "Bad request structure length"},
9896   {SMBE_seek, "Seek error???"},
9897   {SMBE_badmedia, "Bad media???"},
9898   {SMBE_badsector, "Bad sector???"},
9899   {SMBE_nopaper, "No paper in printer???"},
9900   {SMBE_write, "Write error???"},
9901   {SMBE_read, "Read error???"},
9902   {SMBE_general, "General error???"},
9903   {SMBE_badshare, "A open conflicts with an existing open"},
9904   {SMBE_lock, "Lock/unlock error"},
9905   {SMBE_wrongdisk,  "Wrong disk???"},
9906   {SMBE_FCBunavail, "FCB unavailable???"},
9907   {SMBE_sharebufexc, "Share buffer excluded???"},
9908   {SMBE_diskfull, "Disk full???"},
9909   {0, 0}
9910 };
9911
9912 char *decode_smb_error(guint8 errcls, guint8 errcode)
9913 {
9914
9915   switch (errcls) {
9916
9917   case SMB_SUCCESS:
9918
9919     return("No Error");   /* No error ??? */
9920     break;
9921
9922   case SMB_ERRDOS:
9923
9924     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
9925     break;
9926
9927   case SMB_ERRSRV:
9928
9929     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
9930     break;
9931
9932   case SMB_ERRHRD:
9933
9934     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
9935     break;
9936
9937   default:
9938
9939     return("Unknown error class!");
9940
9941   }
9942
9943 }
9944
9945 #define SMB_FLAGS_DIRN 0x80
9946
9947 void
9948 dissect_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, int max_data)
9949 {
9950         proto_tree      *smb_tree = tree, *flags_tree, *flags2_tree;
9951         proto_item      *ti, *tf;
9952         guint8          cmd, errcls, errcode1, flags;
9953         guint16         flags2, errcode, tid, pid, uid, mid;
9954         int             SMB_offset = offset;
9955         struct smb_info si;
9956
9957         si.unicode = 0;
9958
9959         cmd = pd[offset + SMB_hdr_com_offset];
9960
9961         if (check_col(fd, COL_PROTOCOL))
9962                 col_add_str(fd, COL_PROTOCOL, "SMB");
9963
9964         /* Hmmm, poor coding here ... Also, should check the type */
9965
9966         if (check_col(fd, COL_INFO)) {
9967
9968           col_add_fstr(fd, COL_INFO, "%s %s", decode_smb_name(cmd), (pi.match_port == pi.destport)? "Request" : "Response");
9969
9970         }
9971
9972         if (tree) {
9973
9974           ti = proto_tree_add_item(tree, proto_smb, NullTVB, offset, END_OF_FRAME, NULL);
9975           smb_tree = proto_item_add_subtree(ti, ett_smb);
9976
9977           /* 0xFFSMB is actually a 1 byte msg type and 3 byte server
9978            * component ... SMB is only one used
9979            */
9980
9981           proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Message Type: 0xFF");
9982           proto_tree_add_text(smb_tree, NullTVB, offset+1, 3, "Server Component: SMB");
9983
9984         }
9985
9986         offset += 4;  /* Skip the marker */
9987
9988         if (tree) {
9989
9990           proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Command: %s", decode_smb_name(cmd));
9991
9992         }
9993
9994         offset += 1;
9995
9996         /* Next, look at the error class, SMB_RETCLASS */
9997
9998         errcls = pd[offset];
9999
10000         if (tree) {
10001
10002           proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Error Class: %s", 
10003                               val_to_str((guint8)pd[offset], errcls_types, "Unknown Error Class (%x)"));
10004         }
10005
10006         offset += 1;
10007
10008         /* Error code, SMB_HEINFO ... */
10009
10010         errcode1 = pd[offset];
10011
10012         if (tree) {
10013
10014           proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Reserved: %i", errcode1); 
10015
10016         }
10017
10018         offset += 1;
10019
10020         errcode = GSHORT(pd, offset); 
10021
10022         if (tree) {
10023
10024           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Error Code: %s",
10025                               decode_smb_error(errcls, errcode));
10026
10027         }
10028
10029         offset += 2;
10030
10031         /* Now for the flags: Bit 0 = 0 means cmd, 0 = 1 means resp */
10032
10033         flags = pd[offset];
10034
10035         if (tree) {
10036
10037           tf = proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Flags: 0x%02x", flags);
10038
10039           flags_tree = proto_item_add_subtree(tf, ett_smb_flags);
10040           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10041                               decode_boolean_bitfield(flags, 0x01, 8,
10042                                                       "Lock&Read, Write&Unlock supported",
10043                                                       "Lock&Read, Write&Unlock not supported"));
10044           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10045                               decode_boolean_bitfield(flags, 0x02, 8,
10046                                                       "Receive buffer posted",
10047                                                       "Receive buffer not posted"));
10048           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10049                               decode_boolean_bitfield(flags, 0x08, 8, 
10050                                                       "Path names caseless",
10051                                                       "Path names case sensitive"));
10052           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10053                               decode_boolean_bitfield(flags, 0x10, 8,
10054                                                       "Pathnames canonicalized",
10055                                                       "Pathnames not canonicalized"));
10056           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10057                               decode_boolean_bitfield(flags, 0x20, 8,
10058                                                       "OpLocks requested/granted",
10059                                                       "OpLocks not requested/granted"));
10060           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10061                               decode_boolean_bitfield(flags, 0x40, 8, 
10062                                                       "Notify all",
10063                                                       "Notify open only"));
10064
10065           proto_tree_add_text(flags_tree, NullTVB, offset, 1, "%s",
10066                               decode_boolean_bitfield(flags, SMB_FLAGS_DIRN,
10067                                                       8, "Response to client/redirector", "Request to server"));
10068
10069         }
10070
10071         offset += 1;
10072
10073         flags2 = GSHORT(pd, offset);
10074
10075         if (tree) {
10076
10077           tf = proto_tree_add_text(smb_tree, NullTVB, offset, 1, "Flags2: 0x%04x", flags2);
10078
10079           flags2_tree = proto_item_add_subtree(tf, ett_smb_flags2);
10080           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10081                               decode_boolean_bitfield(flags2, 0x0001, 16,
10082                                                       "Long file names supported",
10083                                                       "Long file names not supported"));
10084           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10085                               decode_boolean_bitfield(flags2, 0x0002, 16,
10086                                                       "Extended attributes supported",
10087                                                       "Extended attributes not supported"));
10088           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10089                               decode_boolean_bitfield(flags2, 0x0004, 16,
10090                                                       "Security signatures supported",
10091                                                       "Security signatures not supported"));
10092           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10093                               decode_boolean_bitfield(flags2, 0x0800, 16,
10094                                                       "Extended security negotiation supported",
10095                                                       "Extended security negotiation not supported"));
10096           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10097                               decode_boolean_bitfield(flags2, 0x1000, 16, 
10098                                                       "Resolve pathnames with DFS",
10099                                                       "Don't resolve pathnames with DFS"));
10100           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10101                               decode_boolean_bitfield(flags2, 0x2000, 16,
10102                                                       "Permit reads if execute-only",
10103                                                       "Don't permit reads if execute-only"));
10104           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10105                               decode_boolean_bitfield(flags2, 0x4000, 16,
10106                                                       "Error codes are NT error codes",
10107                                                       "Error codes are DOS error codes"));
10108           proto_tree_add_text(flags2_tree, NullTVB, offset, 1, "%s",
10109                               decode_boolean_bitfield(flags2, 0x8000, 16, 
10110                                                       "Strings are Unicode",
10111                                                       "Strings are ASCII"));
10112
10113         }
10114
10115         if (flags2 & 0x8000) si.unicode = 1; /* Mark them as Unicode */
10116
10117         offset += 2;
10118
10119         if (tree) {
10120
10121           proto_tree_add_text(smb_tree, NullTVB, offset, 12, "Reserved: 6 WORDS");
10122
10123         }
10124
10125         offset += 12;
10126
10127         /* Now the TID, tree ID */
10128
10129         tid = GSHORT(pd, offset);
10130         si.tid = tid;
10131
10132         if (tree) {
10133
10134           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Network Path/Tree ID (TID): %i (%04x)", tid, tid); 
10135
10136         }
10137
10138         offset += 2;
10139
10140         /* Now the PID, Process ID */
10141
10142         pid = GSHORT(pd, offset);
10143         si.pid = pid;
10144
10145         if (tree) {
10146
10147           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Process ID (PID): %i (%04x)", pid, pid); 
10148
10149         }
10150
10151         offset += 2;
10152
10153         /* Now the UID, User ID */
10154
10155         uid = GSHORT(pd, offset);
10156         si.uid = uid;
10157
10158         if (tree) {
10159
10160           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "User ID (UID): %i (%04x)", uid, uid); 
10161
10162         }
10163         
10164         offset += 2;
10165
10166         /* Now the MID, Multiplex ID */
10167
10168         mid = GSHORT(pd, offset);
10169         si.mid = mid;
10170
10171         if (tree) {
10172
10173           proto_tree_add_text(smb_tree, NullTVB, offset, 2, "Multiplex ID (MID): %i (%04x)", mid, mid); 
10174
10175         }
10176
10177         offset += 2;
10178
10179         /* Now vector through the table to dissect them */
10180
10181         (dissect[cmd])(pd, offset, fd, tree, smb_tree, si, max_data, SMB_offset, errcode,
10182                        ((flags & 0x80) == 0));
10183
10184
10185 }
10186
10187 /*** External routines called during the registration process */
10188
10189 extern void register_proto_smb_browse( void);
10190 extern void register_proto_smb_logon( void);
10191 extern void register_proto_smb_mailslot( void);
10192 extern void register_proto_smb_pipe( void);
10193 extern void register_proto_smb_mailslot( void);
10194
10195
10196 void
10197 proto_register_smb(void)
10198 {
10199         static gint *ett[] = {
10200                 &ett_smb,
10201                 &ett_smb_fileattributes,
10202                 &ett_smb_capabilities,
10203                 &ett_smb_aflags,
10204                 &ett_smb_dialects,
10205                 &ett_smb_mode,
10206                 &ett_smb_rawmode,
10207                 &ett_smb_flags,
10208                 &ett_smb_flags2,
10209                 &ett_smb_desiredaccess,
10210                 &ett_smb_search,
10211                 &ett_smb_file,
10212                 &ett_smb_openfunction,
10213                 &ett_smb_filetype,
10214                 &ett_smb_action,
10215                 &ett_smb_writemode,
10216                 &ett_smb_lock_type,
10217         };
10218
10219         proto_smb = proto_register_protocol("Server Message Block Protocol", "smb");
10220
10221         proto_register_subtree_array(ett, array_length(ett));
10222         register_init_routine(&smb_init_protocol);
10223         
10224         register_proto_smb_browse();
10225         register_proto_smb_logon( );
10226         register_proto_smb_mailslot();
10227         register_proto_smb_pipe();
10228
10229 }
10230
10231