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