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