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