Fix various typos and spelling errors.
[obnox/wireshark/wip.git] / epan / dissectors / packet-smb.c
index 9b6f804c5bb2ba07c7714e5ff67e380084f371d0..f106e5565df49fd4c3942e801068f6ab3d24da1a 100644 (file)
@@ -30,8 +30,6 @@
 # include "config.h"
 #endif
 
-#include <stdio.h>
-
 #include <time.h>
 #include <string.h>
 #include <glib.h>
  *
  * Beware - these specs may have errors.
  */
+
+/* DFS referral entry flags */
+#define REFENT_FLAGS_NAME_LIST_REFERRAL  0x0002
+#define REFENT_FLAGS_TARGET_SET_BOUNDARY 0x0004
+
+
 static int proto_smb = -1;
 static int hf_smb_cmd = -1;
 static int hf_smb_mapped_in = -1;
@@ -361,8 +365,13 @@ static int hf_smb_lanman = -1;
 static int hf_smb_setup_action_guest = -1;
 static int hf_smb_fs = -1;
 static int hf_smb_connect_flags_dtid = -1;
+static int hf_smb_connect_flags_ext_sig = -1;
+static int hf_smb_connect_flags_ext_resp = -1;
 static int hf_smb_connect_support_search = -1;
 static int hf_smb_connect_support_in_dfs = -1;
+static int hf_smb_connect_support_csc_mask_vals = -1;
+static int hf_smb_connect_support_uniquefilename = -1;
+static int hf_smb_connect_support_extended_signature = -1;
 static int hf_smb_max_setup_count = -1;
 static int hf_smb_total_param_count = -1;
 static int hf_smb_total_data_count = -1;
@@ -559,7 +568,8 @@ static int hf_smb_get_dfs_fielding = -1;
 static int hf_smb_dfs_referral_version = -1;
 static int hf_smb_dfs_referral_size = -1;
 static int hf_smb_dfs_referral_server_type = -1;
-static int hf_smb_dfs_referral_flags_strip = -1;
+static int hf_smb_dfs_referral_flags_name_list_referral = -1;
+static int hf_smb_dfs_referral_flags_target_set_boundary = -1;
 static int hf_smb_dfs_referral_node_offset = -1;
 static int hf_smb_dfs_referral_node = -1;
 static int hf_smb_dfs_referral_proximity = -1;
@@ -568,6 +578,12 @@ static int hf_smb_dfs_referral_path_offset = -1;
 static int hf_smb_dfs_referral_path = -1;
 static int hf_smb_dfs_referral_alt_path_offset = -1;
 static int hf_smb_dfs_referral_alt_path = -1;
+static int hf_smb_dfs_referral_domain_offset = -1;
+static int hf_smb_dfs_referral_number_of_expnames = -1;
+static int hf_smb_dfs_referral_expnames_offset = -1;
+static int hf_smb_dfs_referral_domain_name = -1;
+static int hf_smb_dfs_referral_expname = -1;
+static int hf_smb_dfs_referral_server_guid = -1;
 static int hf_smb_end_of_search = -1;
 static int hf_smb_last_name_offset = -1;
 static int hf_smb_fn_information_level = -1;
@@ -629,6 +645,7 @@ static int hf_smb_segment_overlap_conflict = -1;
 static int hf_smb_segment_multiple_tails = -1;
 static int hf_smb_segment_too_long_fragment = -1;
 static int hf_smb_segment_error = -1;
+static int hf_smb_reassembled_length = -1;
 static int hf_smb_pipe_write_len = -1;
 static int hf_smb_unix_major_version = -1;
 static int hf_smb_unix_minor_version = -1;
@@ -737,6 +754,7 @@ static gint ett_smb_stream_info = -1;
 static gint ett_smb_dfs_referrals = -1;
 static gint ett_smb_dfs_referral = -1;
 static gint ett_smb_dfs_referral_flags = -1;
+static gint ett_smb_dfs_referral_expnames = -1;
 static gint ett_smb_get_dfs_flags = -1;
 static gint ett_smb_ff2_data = -1;
 static gint ett_smb_device_characteristics = -1;
@@ -752,9 +770,10 @@ static gint ett_smb_posic_ace = -1;
 static gint ett_smb_posix_ace_perms = -1;
 
 static int smb_tap = -1;
+static int smb_eo_tap = -1;
 
-static dissector_handle_t gssapi_handle = NULL;
-static dissector_handle_t ntlmssp_handle = NULL;
+static dissector_handle_t gssapi_handle;
+static dissector_handle_t ntlmssp_handle;
 
 static const fragment_items smb_frag_items = {
        &ett_smb_segment,
@@ -768,11 +787,11 @@ static const fragment_items smb_frag_items = {
        &hf_smb_segment_too_long_fragment,
        &hf_smb_segment_error,
        NULL,
-
+       &hf_smb_reassembled_length,
        "segments"
 };
 
-static proto_tree *top_tree=NULL;     /* ugly */
+static proto_tree *top_tree_global=NULL;     /* ugly */
 
 static const char *decode_smb_name(guint8);
 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
@@ -868,9 +887,17 @@ static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
        offset += len;                  \
        *bcp -= len;
 
-
+gboolean sid_display_hex = FALSE;
 gboolean sid_name_snooping = FALSE;
 
+/* Compare funtion to maintain the GSL_fid_info ordered
+   Order criteria: packet where the fid was opened */
+static gint
+fid_cmp(smb_fid_info_t *fida, smb_fid_info_t *fidb)
+{
+        return (fida->opened_in - fidb->opened_in);
+}
+
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
@@ -1217,8 +1244,7 @@ TimeZoneFaster(time_t t)
                else
                        tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
                if (tdt == NULL) {
-                       if (dst_table)
-                               g_free(dst_table);
+                       g_free(dst_table);
                        table_size = 0;
                } else {
                        dst_table = tdt;
@@ -1564,75 +1590,47 @@ static const true_false_string tfs_file_attribute_encrypted = {
 };
 
 /*
- * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are
- * listed as USHORT, and seem to be in packets in the wild, while in other
- * places they are listed as ULONG, and also seem to be.
- *
- * So, I (Richard Sharpe), added a parameter to allow us to specify how many
- * bytes to consume.
+ * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
+ * section 2.2.1.2.4 of [MS-CIFS], in cases where it's just file attributes,
+ * not search attributes.
  */
-
-int
-dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
-                       int bytes)
+static int
+dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item;
        proto_tree *tree;
 
-       if (bytes != 2 && bytes != 4) {
-               THROW(ReportedBoundsError);
-       }
-
-       /*
-        * The actual bits of interest appear to only be a USHORT
-        */
-       /* FIXME if this ever changes! */
        mask = tvb_get_letohs(tvb, offset);
 
        if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
-                       "File Attributes: 0x%08x", mask);
+               item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+                       "File Attributes: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_file_attributes);
 
-               proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
-                                      tvb, offset, bytes, mask);
-               proto_tree_add_boolean(tree, hf_smb_file_attr_device,
-                                      tvb, offset, bytes, mask);
                proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
-                               tvb, offset, bytes, mask);
+                               tvb, offset, 2, mask);
                proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
-                               tvb, offset, bytes, mask);
+                               tvb, offset, 2, mask);
                proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
-                               tvb, offset, bytes, mask);
+                               tvb, offset, 2, mask);
                proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
-                               tvb, offset, bytes, mask);
+                               tvb, offset, 2, mask);
                proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
-                               tvb, offset, bytes, mask);
+                               tvb, offset, 2, mask);
                proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
-                               tvb, offset, bytes, mask);
+                               tvb, offset, 2, mask);
        }
 
-       offset += bytes;
+       offset += 2;
 
        return offset;
 }
 
-/* 3.11 */
+/*
+ * 3.11 in the SNIA CIFS spec
+ * SMB_EXT_FILE_ATTR, section 2.2.1.2.3 in the [MS-CIFS] spec
+ */
 static int
 dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
     int len, guint32 mask)
@@ -1692,7 +1690,7 @@ dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
 }
 
 /* 3.11 */
-static int
+int
 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
@@ -1762,6 +1760,10 @@ static const true_false_string tfs_search_attribute_archive = {
        "Do NOT include archive files in search results"
 };
 
+/*
+ * Dissects an SMB_FILE_ATTRIBUTES, to use the term given to it by
+ * section 2.2.1.2.4 of [MS-CIFS], in cases where it's search attributes.
+ */
 static int
 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
@@ -2092,6 +2094,12 @@ dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset
        return offset;
 }
 
+#define MAX_DIALECTS 20
+struct negprot_dialects {
+       int num;
+       char *name[MAX_DIALECTS+1];
+};
+
 static int
 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -2099,6 +2107,11 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        proto_tree *tr = NULL;
        guint16 bc;
        guint8 wc;
+       struct negprot_dialects *dialects = NULL;
+       smb_info_t *si;
+
+       si = (smb_info_t *)pinfo->private_data;
+       DISSECTOR_ASSERT(si);
 
        WORD_COUNT;
 
@@ -2111,6 +2124,13 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
                tr = proto_item_add_subtree(it, ett_smb_dialects);
        }
 
+       if (!pinfo->fd->flags.visited && si->sip) {
+               dialects = se_alloc(sizeof(struct negprot_dialects));
+               dialects->num = 0;
+               si->sip->extra_info_type = SMB_EI_DIALECTS;
+               si->sip->extra_info = dialects;
+       }
+
        while(bc){
                int len;
                const guint8 *str;
@@ -2139,8 +2159,13 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
                proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
                        len, str);
                COUNT_BYTES(len);
+
+               if (!pinfo->fd->flags.visited && dialects && dialects->num<MAX_DIALECTS) {
+                       dialects->name[dialects->num++] = se_strdup(str);
+               }
        }
 
+
        END_OF_SMB
 
        return offset;
@@ -2158,6 +2183,8 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
        guint16 ekl=0;
        guint32 caps=0;
        gint16 tz;
+       struct negprot_dialects *dialects = NULL;
+       const char *dialect_name = NULL;
 
        DISSECTOR_ASSERT(si);
 
@@ -2165,12 +2192,23 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
        /* Dialect Index */
        dialect = tvb_get_letohs(tvb, offset);
+
+       if (si->sip && si->sip->extra_info_type==SMB_EI_DIALECTS) {
+               dialects = si->sip->extra_info;
+               if (dialect < dialects->num) {
+                       dialect_name = dialects->name[dialect];
+               }
+       }
+       if (!dialect_name) {
+               dialect_name = "unknown";
+       }
+
        switch(wc){
        case 1:
                if(dialect==0xffff){
                        proto_tree_add_uint_format(tree, hf_smb_dialect_index,
                                tvb, offset, 2, dialect,
-                               "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
+                               "Selected Index: -1, PC NETWORK PROGRAM 1.0 chosen");
                } else {
                        proto_tree_add_uint(tree, hf_smb_dialect_index,
                                tvb, offset, 2, dialect);
@@ -2184,7 +2222,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
        case 17:
                proto_tree_add_uint_format(tree, hf_smb_dialect_index,
                        tvb, offset, 2, dialect,
-                       "Dialect Index: %u, greater than LANMAN2.1", dialect);
+                       "Dialect Index: %u: %s", dialect, dialect_name);
                break;
        default:
                tvb_ensure_bytes_exist(tvb, offset, wc*2);
@@ -2454,7 +2492,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
 
 static int
-dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        smb_info_t *si = pinfo->private_data;
        int dn_len;
@@ -2477,7 +2515,7 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
                FALSE, FALSE, &bc);
 
-       if(si->sip){
+       if((!pinfo->fd->flags.visited) && si->sip){
                si->sip->extra_info_type=SMB_EI_FILENAME;
                si->sip->extra_info=se_strdup(dn);
        }
@@ -3396,6 +3434,10 @@ dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
        proto_item *it;
        proto_tree *tr;
        smb_fid_info_t *fid_info=NULL;
+        smb_fid_info_t *suspect_fid_info=NULL;
+        /* We need this to use an array-accessed tree */
+        GSList          *GSL_iterator;
+        int             found=0;
 
        DISSECTOR_ASSERT(si);
 
@@ -3412,17 +3454,38 @@ dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
                fid_info->opened_in=pinfo->fd->num;
                fid_info->closed_in=0;
                fid_info->type=SMB_FID_TYPE_UNKNOWN;
+                fid_info->fid=fid;
+                fid_info->tid=si->tid;
                if(si->sip && (si->sip->extra_info_type==SMB_EI_FILEDATA)){
                        fid_info->fsi=si->sip->extra_info;
                } else {
                        fid_info->fsi=NULL;
                }
-
-               se_tree_insert32(si->ct->fid_tree, fid, fid_info);
+                /* We don't use the fid_tree anymore to access and
+                   maintain the fid information of analized files.
+                   (was se_tree_insert32(si->ct->fid_tree, fid, fid_info);)
+                   We'll use a single list instead to keep track of the
+                   files (fid) opened.
+                   Note that the insert_sorted function allows to insert duplicates
+                   but being inside this if section should prevent it */
+                si->ct->GSL_fid_info=g_slist_insert_sorted(
+                                        si->ct->GSL_fid_info,
+                                        fid_info,
+                                        (GCompareFunc)fid_cmp);
        }
 
        if(!fid_info){
-               fid_info=se_tree_lookup32(si->ct->fid_tree, fid);
+                /* we use the single linked list to access this fid_info
+                   (was fid_info=se_tree_lookup32(si->ct->fid_tree, fid);) */
+                GSL_iterator = si->ct->GSL_fid_info;
+                while (GSL_iterator) {
+                        suspect_fid_info=GSL_iterator->data;
+                        if(suspect_fid_info->opened_in > pinfo->fd->num) break;
+                        if(suspect_fid_info->tid==si->tid && suspect_fid_info->fid==fid)
+                                fid_info=suspect_fid_info;
+                        GSL_iterator=g_slist_next(GSL_iterator);
+                        found+=1;
+                }
        }
        if(!fid_info){
                return NULL;
@@ -3488,7 +3551,7 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* last write time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
@@ -3647,7 +3710,7 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* creation time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
@@ -3728,7 +3791,7 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
 
-       if(si->sip){
+       if((!pinfo->fd->flags.visited) && si->sip){
                si->sip->extra_info_type=SMB_EI_FILENAME;
                si->sip->extra_info=se_strdup(fn);
        }
@@ -3939,7 +4002,7 @@ dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
        WORD_COUNT;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* Last Write Time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
@@ -3973,7 +4036,7 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* last write time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
@@ -4160,7 +4223,7 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        /* file data, might be DCERPC on a pipe */
        if(bc){
                offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
-                   top_tree, offset, bc, bc, 0, (guint16) fid);
+                   top_tree_global, offset, bc, bc, 0, (guint16) fid);
                bc = 0;
        }
 
@@ -4204,7 +4267,7 @@ dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 }
 
 typedef struct _rw_info_t {
-       guint32 offset;
+       guint64 offset;
        guint32 len;
        guint16 fid;
 } rw_info_t;
@@ -4259,7 +4322,7 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        if(rwi){
                proto_item *it;
 
-               it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
+               it=proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
 
                PROTO_ITEM_SET_GENERATED(it);
                it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
@@ -4285,7 +4348,7 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        /* file data, might be DCERPC on a pipe */
        if (bc != 0) {
                offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
-                   top_tree, offset, bc, bc, ofs, fid);
+                   top_tree_global, offset, bc, bc, ofs, fid);
                bc = 0;
        }
 
@@ -4321,7 +4384,7 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        if(rwi){
                proto_item *it;
 
-               it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
+               it=proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
 
                PROTO_ITEM_SET_GENERATED(it);
                it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
@@ -4569,7 +4632,7 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto
        offset += 4;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -4648,26 +4711,26 @@ dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
    available at http://us1.samba.org/samba/ftp/SMB-info/DOSEXTP.TXT
 */
 static gchar *
-smbext20_timeout_msecs_to_str(gint32 time)
+smbext20_timeout_msecs_to_str(gint32 timeout)
 {
         gchar *buf;
 #define SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN 60
 
-       if (time <= 0) {
+       if (timeout <= 0) {
                buf=ep_alloc(SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1);
-               if (time == 0) {
+               if (timeout == 0) {
                        g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Return immediately (0)");
-               } else if (time == -1) {
+               } else if (timeout == -1) {
                        g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Wait indefinitely (-1)");
-               } else if (time == -2) {
+               } else if (timeout == -2) {
                        g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Use default timeout (-2)");
                } else {
-                       g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", time);
+                       g_snprintf(buf, SMBEXT20_TIMEOUT_MSECS_TO_STR_MAXLEN+1, "Unknown reserved value (%d)", timeout);
                }
                return buf;
        }
 
-       return time_msecs_to_str(time);
+       return time_msecs_to_str(timeout);
 }
 
 static int
@@ -5521,8 +5584,8 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                        "Unlocks");
                tr = proto_item_add_subtree(it, ett_smb_unlocks);
                while(un--){
-                       proto_item *litem = NULL;
-                       proto_tree *ltree = NULL;
+                       proto_item *litem_2 = NULL;
+                       proto_tree *ltree_2 = NULL;
                        if(lt&0x10){
                                guint64 val;
                                guint16 lock_pid;
@@ -5530,19 +5593,19 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                guint64 lock_length;
 
                                /* large lock format */
-                               litem = proto_tree_add_text(tr, tvb, offset, 20,
+                               litem_2 = proto_tree_add_text(tr, tvb, offset, 20,
                                        "Unlock");
-                               ltree = proto_item_add_subtree(litem, ett_smb_unlock);
+                               ltree_2 = proto_item_add_subtree(litem_2, ett_smb_unlock);
 
                                /* PID */
                                CHECK_BYTE_COUNT(2);
                                lock_pid=tvb_get_letohs(tvb, offset);
-                               proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, TRUE);
                                COUNT_BYTES(2);
 
                                /* 2 reserved bytes */
                                CHECK_BYTE_COUNT(2);
-                               proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, TRUE);
                                COUNT_BYTES(2);
 
                                /* offset */
@@ -5550,7 +5613,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
                                lock_offset=val;
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
+                               proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
                                COUNT_BYTES(8);
 
                                /* length */
@@ -5558,7 +5621,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
                                lock_length=val;
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
+                               proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
                                COUNT_BYTES(8);
 
                                /* remember the unlock for the reply */
@@ -5573,23 +5636,23 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                }
                        } else {
                                /* normal lock format */
-                               litem = proto_tree_add_text(tr, tvb, offset, 10,
+                               litem_2 = proto_tree_add_text(tr, tvb, offset, 10,
                                        "Unlock");
-                               ltree = proto_item_add_subtree(litem, ett_smb_unlock);
+                               ltree_2 = proto_item_add_subtree(litem_2, ett_smb_unlock);
 
                                /* PID */
                                CHECK_BYTE_COUNT(2);
-                               proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, TRUE);
                                COUNT_BYTES(2);
 
                                /* offset */
                                CHECK_BYTE_COUNT(4);
-                               proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, TRUE);
                                COUNT_BYTES(4);
 
                                /* lock count */
                                CHECK_BYTE_COUNT(4);
-                               proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, TRUE);
                                COUNT_BYTES(4);
                        }
                }
@@ -5605,8 +5668,8 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                        "Locks");
                tr = proto_item_add_subtree(it, ett_smb_locks);
                while(ln--){
-                       proto_item *litem = NULL;
-                       proto_tree *ltree = NULL;
+                       proto_item *litem_2 = NULL;
+                       proto_tree *ltree_2 = NULL;
                        if(lt&0x10){
                                guint64 val;
                                guint16 lock_pid;
@@ -5614,19 +5677,19 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                guint64 lock_length;
 
                                /* large lock format */
-                               litem = proto_tree_add_text(tr, tvb, offset, 20,
+                               litem_2 = proto_tree_add_text(tr, tvb, offset, 20,
                                        "Lock");
-                               ltree = proto_item_add_subtree(litem, ett_smb_lock);
+                               ltree_2 = proto_item_add_subtree(litem_2, ett_smb_lock);
 
                                /* PID */
                                CHECK_BYTE_COUNT(2);
                                lock_pid=tvb_get_letohs(tvb, offset);
-                               proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, TRUE);
                                COUNT_BYTES(2);
 
                                /* 2 reserved bytes */
                                CHECK_BYTE_COUNT(2);
-                               proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_reserved, tvb, offset, 2, TRUE);
                                COUNT_BYTES(2);
 
                                /* offset */
@@ -5634,7 +5697,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
                                lock_offset=val;
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
+                               proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
                                COUNT_BYTES(8);
 
                                /* length */
@@ -5642,7 +5705,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
                                lock_length=val;
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
+                               proto_tree_add_uint64(ltree_2, hf_smb_lock_long_length, tvb, offset, 8, val);
                                COUNT_BYTES(8);
 
                                /* remember the lock for the reply */
@@ -5657,23 +5720,23 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                }
                        } else {
                                /* normal lock format */
-                               litem = proto_tree_add_text(tr, tvb, offset, 10,
+                               litem_2 = proto_tree_add_text(tr, tvb, offset, 10,
                                        "Lock");
-                               ltree = proto_item_add_subtree(litem, ett_smb_lock);
+                               ltree_2 = proto_item_add_subtree(litem_2, ett_smb_lock);
 
                                /* PID */
                                CHECK_BYTE_COUNT(2);
-                               proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_pid, tvb, offset, 2, TRUE);
                                COUNT_BYTES(2);
 
                                /* offset */
                                CHECK_BYTE_COUNT(4);
-                               proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_offset, tvb, offset, 4, TRUE);
                                COUNT_BYTES(4);
 
                                /* lock count */
                                CHECK_BYTE_COUNT(4);
-                               proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
+                               proto_tree_add_item(ltree_2, hf_smb_count, tvb, offset, 4, TRUE);
                                COUNT_BYTES(4);
                        }
                }
@@ -5934,7 +5997,7 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset = dissect_search_attributes(tvb, tree, offset);
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* creation time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
@@ -5966,6 +6029,18 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
                fn);
        COUNT_BYTES(fn_len);
 
+        /* Copied this portion of code from create_andx_request
+           to guarantee that fsi and si->sip are always correctly filled out */
+        if((!pinfo->fd->flags.visited) && si->sip && fn){
+                smb_fid_saved_info_t *fsi;
+
+                fsi=se_alloc(sizeof(smb_fid_saved_info_t));
+                fsi->filename=se_strdup(fn);
+
+                si->sip->extra_info_type=SMB_EI_FILEDATA;
+                si->sip->extra_info=fsi;
+        }
+
        if (check_col(pinfo->cinfo, COL_INFO)) {
                col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
                    format_text(fn, strlen(fn)));
@@ -6004,7 +6079,7 @@ static const value_string ipc_state_read_mode_vals[] = {
 
 int
 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
-    gboolean setstate)
+    gboolean setstate_flag)
 {
        guint16 mask;
        proto_item *item;
@@ -6019,7 +6094,7 @@ dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
 
                proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
                        tvb, offset, 2, mask);
-               if (!setstate) {
+               if (!setstate_flag) {
                        proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
                                tvb, offset, 2, mask);
                        proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
@@ -6027,7 +6102,7 @@ dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
                }
                proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
                        tvb, offset, 2, mask);
-               if (!setstate) {
+               if (!setstate_flag) {
                        proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
                                tvb, offset, 2, mask);
                }
@@ -6044,6 +6119,10 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc;
        guint16 fid;
+        guint16 ftype;
+        guint16 fattr;
+        smb_fid_info_t *fid_info=NULL;
+        gboolean        isdir=FALSE;
 
        WORD_COUNT;
 
@@ -6067,16 +6146,22 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
+        /* we add fid_info= to this call so that we save the result */
+        fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
+
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+        fattr = tvb_get_letohs(tvb, offset);
+        isdir = fattr & SMB_FILE_ATTRIBUTE_DIRECTORY;
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* last write time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
 
        /* File Size */
+        /* We store the file_size in the fid_info */
+        fid_info->end_of_file=(guint64) tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
        offset += 4;
 
@@ -6084,8 +6169,30 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset = dissect_access(tvb, tree, offset, "Granted");
 
        /* File Type */
+        ftype=tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
        offset += 2;
+        /* Copied from dissect_nt_create_andx_response
+           Try to remember the type of this fid so that we can dissect
+           any future security descriptor (access mask) properly
+         */
+        fid_info->type=SMB_FID_TYPE_UNKNOWN;
+        if(ftype==0){
+                if(isdir==0){
+                        if(fid_info){
+                                fid_info->type=SMB_FID_TYPE_FILE;
+                        }
+                } else {
+                        if(fid_info){
+                                fid_info->type=SMB_FID_TYPE_DIR;
+                        }
+                }
+        }
+        if(ftype==2 || ftype==1){
+                if(fid_info){
+                        fid_info->type=SMB_FID_TYPE_PIPE;
+                }
+        }
 
        /* IPC State */
        offset = dissect_ipc_state(tvb, tree, offset, FALSE);
@@ -6121,7 +6228,8 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        guint16 andxoffset=0, bc, maxcnt_low;
        guint32 maxcnt_high;
        guint32 maxcnt=0;
-       guint32 ofs = 0;
+       guint32 offsetlow, offsethigh=0;
+       guint64 ofs;
        smb_info_t *si= (smb_info_t *)pinfo->private_data;
        unsigned int fid;
        rw_info_t *rwi=NULL;
@@ -6155,7 +6263,7 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 2;
 
        /* offset */
-       ofs = tvb_get_letohl(tvb, offset);
+       offsetlow = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
@@ -6184,10 +6292,24 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
         * bits in max count, but it does show a 32-bit timeout
         * after the min count field.
         *
-        * Perhaps the 32-bit timeout field was hijacked as a 16-bit
-        * high count and a 16-bit reserved field.
+        * The Microsoft [MS-SMB] spec shows it as a ULONG named
+        * Timeout_or_MaxCountHigh, which is
+        *
+        *      ...extended to be treated as a union of a 32-bit
+        *      Timeout field and a 16-bit MaxCountHigh field.
+        *      When reading from a regular file, the field
+        *      MUST be interpreted as MaxCountHigh and the
+        *      two unused bytes MUST be zero.  When reading from
+        *      a name[sic] pipe or I/O device, the field MUST
+        *      be interpreted as Timeout.
         *
-        * We fetch and display it as 32 bits.
+        * Timeout is a timeout in milliseconds, with 0xffffffff
+        * and 0xfffffffe having special meaning.
+        *
+        * MaxCountHigh is 16 bits of the MaxCountHigh value
+        * followed by 16 bits of Reserved.
+        *
+        * We fetch and display it as 32 bits for now.
          *
          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
         * bytes and we just ignore it.
@@ -6204,10 +6326,24 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        maxcnt=maxcnt_high;
        maxcnt=(maxcnt<<16)|maxcnt_low;
 
+       /* remaining */
+       proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       if(wc==12){
+               /* high offset */
+               offsethigh=tvb_get_letohl(tvb, offset);
+               proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
+               offset += 4;
+       }
+
+       ofs=offsethigh;
+       ofs=(ofs<<32)|offsetlow;
+
        if (check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(pinfo->cinfo, COL_INFO,
-                               ", %u byte%s at offset %u", maxcnt,
-                               (maxcnt == 1) ? "" : "s", ofs);
+                               ", %u byte%s at offset %" G_GINT64_MODIFIER "u",
+                               maxcnt, (maxcnt == 1) ? "" : "s", ofs);
 
        /* save the offset/len for this transaction */
        if(si->sip && !pinfo->fd->flags.visited){
@@ -6225,23 +6361,13 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        if(rwi){
                proto_item *it;
 
-               it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
+               it=proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
 
                PROTO_ITEM_SET_GENERATED(it);
                it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
                PROTO_ITEM_SET_GENERATED(it);
        }
 
-       /* remaining */
-       proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
-       offset += 2;
-
-       if(wc==12){
-               /* high offset */
-               proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
-               offset += 4;
-       }
-
        BYTE_COUNT;
 
        END_OF_SMB
@@ -6255,6 +6381,15 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        return offset;
 }
 
+/* Strings that describes the SMB object type */
+const value_string smb_fid_types[] = {
+        {SMB_FID_TYPE_UNKNOWN,"UNKNOWN"},
+        {SMB_FID_TYPE_FILE,"FILE"},
+        {SMB_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"},
+        {SMB_FID_TYPE_PIPE,"PIPE (Not Implemented)"},
+       {0, NULL}
+};
+
 static int
 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
@@ -6262,8 +6397,18 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
        guint32 datalen=0, datalen_high;
        smb_info_t *si = (smb_info_t *)pinfo->private_data;
-       int fid=0;
        rw_info_t *rwi=NULL;
+        guint16 fid=0; /* was int fid=0; */
+
+        smb_eo_t        *eo_info; /* eo_info variable to pass info. to
+                                     export object and aux */
+        smb_tid_info_t  *tid_info=NULL;
+        smb_fid_info_t  *fid_info=NULL;
+        smb_fid_info_t  *suspect_fid_info=NULL;
+        guint32 tvblen,packet_number;
+        tvbuff_t        *data_tvb;
+        GSList          *GSL_iterator;
+        int             found=0;
 
        DISSECTOR_ASSERT(si);
 
@@ -6300,7 +6445,7 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        if(rwi){
                proto_item *it;
 
-               it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
+               it=proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
 
                PROTO_ITEM_SET_GENERATED(it);
                it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
@@ -6332,7 +6477,14 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
        offset += 2;
 
-       /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
+       /*
+        * XXX - the SNIA SMB spec says this is a USHORT, not a
+        * ULONG.
+        *
+        * XXX - we should really only do this in case we have seen
+        * LARGE FILE being negotiated.  Unfortunately, we might not
+        * have seen the negotiation phase in the capture....
+        */
        /* data length high */
        datalen_high = tvb_get_letohl(tvb, offset);
        if(datalen_high==0xffffffff){
@@ -6361,10 +6513,55 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* file data, might be DCERPC on a pipe */
        if(bc){
                offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
-                   top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
+                   top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid);
                bc = 0;
        }
 
+        /* feed the export object tap listener */
+        tvblen = tvb_length_remaining(tvb, dataoffset);
+        if(have_tap_listener(smb_eo_tap) && datalen==tvblen && rwi) {
+                packet_number=pinfo->fd->num;
+                /* Create a new tvb to point to the payload data */
+                data_tvb = tvb_new_subset(tvb, dataoffset, datalen, tvblen);
+                /* Create the eo_info to pass to the listener */
+                eo_info = ep_alloc(sizeof(smb_eo_t));
+
+                /* Try to get fid_info and tid_info */
+                if (fid_info==NULL) {
+                        GSL_iterator = si->ct->GSL_fid_info;
+                        while (GSL_iterator) {
+                                suspect_fid_info=GSL_iterator->data;
+                                if(suspect_fid_info->opened_in > pinfo->fd->num) break;
+                                if(suspect_fid_info->tid==si->tid && suspect_fid_info->fid==fid)
+                                        fid_info=suspect_fid_info;
+                                GSL_iterator=g_slist_next(GSL_iterator);
+                                found+=1;
+                        }
+                }
+                tid_info = se_tree_lookup32(si->ct->tid_tree, si->tid);
+
+                /* Construct the eo_info structure */
+                if (tid_info)   eo_info->hostname = tid_info->filename;
+                else            eo_info->hostname = ep_strdup_printf("\\\\TREEID_%i",si->tid);
+                if (fid_info) {
+                        eo_info->filename=NULL;
+                        if (fid_info->fsi)
+                                if (fid_info->fsi->filename)
+                                        eo_info->filename = (gchar *) fid_info->fsi->filename;
+                        if(!eo_info->filename) eo_info->filename = ep_strdup_printf("\\FILEID_%i",fid);
+                        eo_info->fid_type = fid_info->type;                                             eo_info->end_of_file = fid_info->end_of_file;
+                } else {                                                                                eo_info->fid_type=SMB_FID_TYPE_UNKNOWN;
+                        eo_info->filename = ep_strdup_printf("\\FILEID_%i",fid);                        eo_info->end_of_file = 0;
+                }                                                                               eo_info->fid=fid;
+                eo_info->tid=si->tid;                                                           eo_info->uid=si->uid;
+                eo_info->payload_len = datalen;                                                 eo_info->payload_data = data_tvb->real_data;
+                eo_info->smb_file_offset=rwi->offset;                                           eo_info->smb_chunk_len=rwi->len;
+                eo_info->cmd=SMB_COM_READ_ANDX;
+                /* Queue data to the listener */
+
+                tap_queue_packet(smb_eo_tap, pinfo, eo_info);
+        }
+
        END_OF_SMB
 
        if (cmd != 0xff) {      /* there is an andX command */
@@ -6379,15 +6576,25 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 static int
 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
-       guint32 ofs=0;
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
+       guint32 offsetlow, offsethigh=0;
+       guint64 ofs;
        guint32 datalen=0;
        smb_info_t *si = (smb_info_t *)pinfo->private_data;
-       unsigned int fid=0;
+        guint16 fid=0; /* was unsigned int fid=0; */
        guint16 mode = 0;
        rw_info_t *rwi=NULL;
-
+        /* eo_info variables to pass info. to export object and
+           other aux */
+        smb_eo_t        *eo_info;
+        smb_tid_info_t  *tid_info=NULL;
+        smb_fid_info_t  *fid_info=NULL;
+        smb_fid_info_t  *suspect_fid_info=NULL;
+        guint32 tvblen,packet_number;
+        tvbuff_t        *data_tvb;
+        GSList          *GSL_iterator;
+        int             found=0;
 
        DISSECTOR_ASSERT(si);
 
@@ -6417,7 +6624,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* offset */
-       ofs = tvb_get_letohl(tvb, offset);
+       offsetlow = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
@@ -6433,7 +6640,11 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
        offset += 2;
 
-       /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
+       /*
+        * XXX - we should really only do this in case we have seen
+        * LARGE FILE being negotiated.  Unfortunately, we might not
+        * have seen the negotiation phase in the capture....
+        */
        /* data length high */
        datalen_high = tvb_get_letohs(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
@@ -6452,11 +6663,20 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
        offset += 2;
 
-       /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
+       if(wc==14){
+               /* high offset */
+               offsethigh=tvb_get_letohl(tvb, offset);
+               proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
+               offset += 4;
+       }
+
+       ofs=offsethigh;
+       ofs=(ofs<<32)|offsetlow;
+
        if (check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(pinfo->cinfo, COL_INFO,
-                               ", %u byte%s at offset %u", datalen,
-                               (datalen == 1) ? "" : "s", ofs);
+                               ", %u byte%s at offset %" G_GINT64_MODIFIER "u",
+                               datalen, (datalen == 1) ? "" : "s", ofs);
 
        /* save the offset/len for this transaction */
        if(si->sip && !pinfo->fd->flags.visited){
@@ -6474,7 +6694,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        if(rwi){
                proto_item *it;
 
-               it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
+               it=proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
 
                PROTO_ITEM_SET_GENERATED(it);
                it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
@@ -6482,12 +6702,6 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
 
-       if(wc==14){
-               /* high offset */
-               proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
-               offset += 4;
-       }
-
        BYTE_COUNT;
 
        /* if both the MessageStart and the  WriteRawNamedPipe flags are set
@@ -6523,10 +6737,69 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* file data, might be DCERPC on a pipe */
        if (bc != 0) {
                offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
-                   top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
+                   top_tree_global, offset, bc, (guint16) datalen, 0, (guint16) fid);
                bc = 0;
        }
 
+        /* feed the export object tap listener */
+        tvblen = tvb_length_remaining(tvb, dataoffset);
+        if(have_tap_listener(smb_eo_tap) && datalen==tvblen && rwi) {
+                packet_number=pinfo->fd->num;
+                /* Create a new tvb to point to the payload data */
+                data_tvb = tvb_new_subset(tvb, dataoffset, datalen, tvblen);
+                /* Create the eo_info to pass to the listener */
+                eo_info = ep_alloc(sizeof(smb_eo_t));
+
+                /* Try to get fid_info and tid_info */
+                if (fid_info==NULL) {
+                        /* We'll use a GSL instead */
+                        /* (was fid_info = se_tree_lookup32(si->ct->fid_tree, fi
+d);) */
+                        GSL_iterator = si->ct->GSL_fid_info;
+                        while (GSL_iterator) {
+                                suspect_fid_info=GSL_iterator->data;
+                                if(suspect_fid_info->opened_in > pinfo->fd->num)
+ break;
+                                if(suspect_fid_info->tid==si->tid && suspect_fid_info->fid==fid)
+                                        fid_info=suspect_fid_info;
+                                GSL_iterator=g_slist_next(GSL_iterator);
+                                found+=1;
+                        }
+                }
+                tid_info = se_tree_lookup32(si->ct->tid_tree, si->tid);
+
+                /* Construct the eo_info structure */
+                if (tid_info)   eo_info->hostname = tid_info->filename;
+                else            eo_info->hostname = ep_strdup_printf("\\\\TREEID_%i",si->tid);
+                if (fid_info) {
+                        eo_info->filename=NULL;
+                        if (fid_info->fsi) {
+                                if (fid_info->fsi->filename) {
+                                        eo_info->filename = (gchar *) fid_info->fsi->filename;
+                                        }
+                                }
+                        if(!eo_info->filename) eo_info->filename = ep_strdup_printf("\\FILEID_%i",fid);
+                        eo_info->fid_type = fid_info->type;
+                        eo_info->end_of_file = fid_info->end_of_file;
+                } else {
+                        eo_info->fid_type=SMB_FID_TYPE_UNKNOWN;
+                        eo_info->filename = ep_strdup_printf("\\FILEID_%i",fid);
+                        eo_info->end_of_file = 0;
+                }
+                eo_info->fid=fid;
+                eo_info->tid=si->tid;
+                eo_info->uid=si->uid;
+                eo_info->payload_len = datalen;
+                eo_info->payload_data = data_tvb->real_data;
+                eo_info->smb_file_offset=rwi->offset;
+                eo_info->smb_chunk_len=rwi->len;
+                eo_info->cmd=SMB_COM_WRITE_ANDX;
+
+                /* Queue data to the listener */
+
+                tap_queue_packet(smb_eo_tap, pinfo, eo_info);
+        }
+
        END_OF_SMB
 
        if (cmd != 0xff) {      /* there is an andX command */
@@ -6576,7 +6849,7 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        if(rwi){
                proto_item *it;
 
-               it=proto_tree_add_uint(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
+               it=proto_tree_add_uint64(tree, hf_smb_file_rw_offset, tvb, 0, 0, rwi->offset);
 
                PROTO_ITEM_SET_GENERATED(it);
                it=proto_tree_add_uint(tree, hf_smb_file_rw_length, tvb, 0, 0, rwi->len);
@@ -6677,7 +6950,8 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                 * security blob has been fully dissected and before
                 * we exit from this dissector.
                 */
-               error_string=register_tap_listener("ntlmssp", NULL, NULL, NULL, NULL, NULL);
+               error_string=register_tap_listener("ntlmssp", NULL, NULL,
+                   0, NULL, NULL, NULL);
                if(!error_string){
                        ntlmssp_tap_id=find_tap_id("ntlmssp");
                }
@@ -7205,6 +7479,11 @@ dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs
        return offset;
 }
 
+       /*
+        * From [MS-SMB] - v20100711 Server Message Block (SMB) Protocol Specification
+        * http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-SMB%5D.pdf
+        * 2.2.4.7 SMB_COM_TREE_CONNECT_ANDX (0x75)
+        */
 
 static const true_false_string tfs_connect_support_search = {
        "Exclusive search bits supported",
@@ -7214,6 +7493,21 @@ static const true_false_string tfs_connect_support_in_dfs = {
        "Share is in Dfs",
        "Share isn't in Dfs"
 };
+static const value_string connect_support_csc_mask_vals[] = {
+       { 0,    "Automatic file-to-file reintegration NOT permitted"},
+       { 1,    "Automatic file-to-file reintegration permitted"},
+       { 2,    "Offline caching allow for the share"},
+       { 3,    "Offline caching NOT allow for the share"},
+       {0, NULL}
+};
+static const true_false_string tfs_connect_support_uniquefilename = {
+       "Client allow to cache share namespaces",
+       "Client NOT allow to cache share namespaces"
+};
+static const true_false_string tfs_connect_support_extended_signature = {
+       "Extended signature",
+       "NOT extended signature"
+};
 
 static int
 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
@@ -7233,6 +7527,12 @@ dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                        tvb, offset, 2, mask);
                proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
                        tvb, offset, 2, mask);
+               proto_tree_add_uint(tree, hf_smb_connect_support_csc_mask_vals,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_connect_support_uniquefilename,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_connect_support_extended_signature,
+                       tvb, offset, 2, mask);
        }
 
        offset += 2;
@@ -7245,6 +7545,16 @@ static const true_false_string tfs_disconnect_tid = {
        "Do NOT disconnect TID"
 };
 
+static const true_false_string tfs_extended_signature = {
+       "Extended Signature",
+       "NOT Extended Signature"
+};
+
+static const true_false_string tfs_extended_response = {
+       "Extended Response",
+       "NOT Extended Response"
+};
+
 static int
 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
@@ -7261,6 +7571,10 @@ dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 
                proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
                        tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_connect_flags_ext_sig,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_connect_flags_ext_resp,
+                       tvb, offset, 2, mask);
        }
 
        offset += 2;
@@ -7372,6 +7686,9 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        guint16 andxoffset=0;
        guint16 bc;
        int an_len;
+       int count = 0;
+       proto_item *it = NULL;
+       proto_tree *tr = NULL;
        const char *an;
        smb_info_t *si = pinfo->private_data;
 
@@ -7415,11 +7732,27 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
           contains connect support bits, which looks plausible
           from the values I've seen. */
 
+       /* MaximalShareAccessRights and GuestMaximalShareAccessRights */
        while (wleft != 0) {
-               proto_tree_add_text(tree, tvb, offset, 2,
-                   "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
-               offset += 2;
-               wleft--;
+               /*
+                * Refer to [MS-SMB] - v20100711
+                * When a server returns extended information, the response
+                * takes the following format, with WordCount = 7.
+                * MaximalShareAccessRights, and GuestMaximalShareAccessRights fields
+                * has added.
+                */
+               if (count == 0) {
+                       it = proto_tree_add_text(tree, tvb, offset, 4,
+                               "Maximal Share Access Rights");
+               } else {
+                       it = proto_tree_add_text(tree, tvb, offset, 4,
+                               "Guest Maximal Share Access Rights");
+               }
+               tr = proto_item_add_subtree(it, ett_smb_nt_access_mask);
+
+               offset = dissect_smb_access_mask(tvb, tr, offset);
+               wleft -= 2;
+               count++;
        }
 
        BYTE_COUNT;
@@ -7510,7 +7843,7 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 #define NT_TRANS_QSD           6
 #define NT_TRANS_GET_USER_QUOTA        7
 #define NT_TRANS_SET_USER_QUOTA 8
-const value_string nt_cmd_vals[] = {
+static const value_string nt_cmd_vals[] = {
        {NT_TRANS_CREATE,               "NT CREATE"},
        {NT_TRANS_IOCTL,                "NT IOCTL"},
        {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
@@ -7522,6 +7855,8 @@ const value_string nt_cmd_vals[] = {
        {0, NULL}
 };
 
+value_string_ext nt_cmd_vals_ext = VALUE_STRING_EXT_INIT(nt_cmd_vals);
+
 static const value_string nt_ioctl_isfsctl_vals[] = {
        {0,     "Device IOCTL"},
        {1,     "FS control : FSCTL"},
@@ -8150,7 +8485,7 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
                tvb_ensure_bytes_exist(tvb, offset, bc);
                item = proto_tree_add_text(parent_tree, tvb, offset, bc,
                                "%s Data",
-                               val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
+                               val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
                tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
        }
 
@@ -8173,8 +8508,9 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
        case NT_TRANS_IOCTL:
                /* ioctl data */
                ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
-               dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, TRUE);
-
+               if (nti){
+                       dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, TRUE);
+               }
 
                offset += bc;
 
@@ -8234,7 +8570,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
-       guint32 fn_len, create_flags, access_mask, file_attributes, share_access, create_options, create_disposition;
+       guint32 fn_len, create_flags, access_mask, share_access, create_options, create_disposition;
        const char *fn;
 
        si = (smb_info_t *)pinfo->private_data;
@@ -8244,7 +8580,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Parameters",
-                               val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
+                               val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
                tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
        }
 
@@ -8269,8 +8605,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(8);
 
                /* Extended File Attributes */
-               file_attributes=tvb_get_letohl(tvb, offset);
-               offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
+               offset = dissect_file_ext_attr(tvb, tree, offset);
                bc -= 4;
 
                /* share access */
@@ -8393,22 +8728,22 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
        proto_tree *tree = NULL;
        int old_offset = offset;
        smb_info_t *si;
-       smb_nt_transact_info_t *nti;
+       smb_nt_transact_info_t *nti = NULL;
        smb_saved_info_t *sip;
 
 
        si = (smb_info_t *)pinfo->private_data;
        DISSECTOR_ASSERT(si);
        sip = si->sip;
-       DISSECTOR_ASSERT(sip);
-       nti=sip->extra_info;
-
+       if (sip && sip->extra_info_type == SMB_EI_NTI) {
+               nti=sip->extra_info;
+       }
 
        if(parent_tree){
                tvb_ensure_bytes_exist(tvb, offset, len);
                item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Setup",
-                               val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
+                               val_to_str_ext(ntd->subcmd, &nt_cmd_vals_ext, "Unknown NT transaction (%u)"));
                tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
        }
 
@@ -8419,7 +8754,7 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                guint16 fid;
 
                /* function code */
-               offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, &nti->ioctl_function);
+               offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, nti ? &nti->ioctl_function : NULL);
 
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
@@ -8592,7 +8927,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
                proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
                if(check_col(pinfo->cinfo, COL_INFO)){
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
-                               val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
+                               val_to_str_ext(subcmd, &nt_cmd_vals_ext, "<unknown>"));
                }
                ntd.subcmd = subcmd;
                if (!si->unidir && sip) {
@@ -8614,9 +8949,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
                }
        } else {
                /* secondary request */
-               if(check_col(pinfo->cinfo, COL_INFO)){
-                       col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
-               }
+               col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
        }
        offset += 2;
 
@@ -8697,7 +9030,7 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
                if(nti != NULL){
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Data",
-                               val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
+                               val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
                } else {
                        /*
                         * We never saw the request to which this is a
@@ -8719,7 +9052,7 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
        case NT_TRANS_IOCTL:
                /* ioctl data */
                ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)len, tvb_length_remaining(tvb, offset)), len);
-               dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree, nti->ioctl_function, FALSE);
+               dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, FALSE);
 
                offset += len;
 
@@ -8789,7 +9122,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
                if(nti != NULL){
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Parameters",
-                               val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
+                               val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
                } else {
                        /*
                         * We never saw the request to which this is a
@@ -9001,7 +9334,7 @@ dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
                if(nti != NULL){
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Setup",
-                               val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
+                               val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "Unknown NT Transaction (%u)"));
                } else {
                        /*
                         * We never saw the request to which this is a
@@ -9070,14 +9403,12 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
                proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
                if(check_col(pinfo->cinfo, COL_INFO)){
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
-                               val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
+                               val_to_str_ext(nti->subcmd, &nt_cmd_vals_ext, "<unknown (%u)>"));
                }
        } else {
                proto_tree_add_text(tree, tvb, offset, 0,
                        "Function: <unknown function - could not find matching request>");
-               if(check_col(pinfo->cinfo, COL_INFO)){
-                       col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
-               }
+               col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
        }
 
        WORD_COUNT;
@@ -9864,6 +10195,8 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 8;
 
        /* end of file */
+        /* We store the end of file */
+        fid_info->end_of_file=tvb_get_letoh64(tvb, offset);
        proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
        offset += 8;
 
@@ -9939,7 +10272,7 @@ dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
 
-const value_string trans2_cmd_vals[] = {
+static const value_string trans2_cmd_vals[] = {
        { 0x00,         "OPEN2" },
        { 0x01,         "FIND_FIRST2" },
        { 0x02,         "FIND_NEXT2" },
@@ -9955,11 +10288,14 @@ const value_string trans2_cmd_vals[] = {
        { 0x0C,         "FIND_NOTIFY_NEXT" },
        { 0x0D,         "CREATE_DIRECTORY" },
        { 0x0E,         "SESSION_SETUP" },
+        { 0x0F,         "Unknown (0x0f)" },  /* dummy so val_to_str_ext can do indexed lookup */
        { 0x10,         "GET_DFS_REFERRAL" },
        { 0x11,         "REPORT_DFS_INCONSISTENCY" },
        { 0,    NULL }
 };
 
+value_string_ext trans2_cmd_vals_ext = VALUE_STRING_EXT_INIT(trans2_cmd_vals);
+
 static const true_false_string tfs_tf_dtid = {
        "Also DISCONNECT TID",
        "Do NOT disconnect TID"
@@ -10001,6 +10337,8 @@ static const value_string ff2_il_vals[] = {
        { 0x0102,       "Find File Full Directory Info"},
        { 0x0103,       "Find File Names Info"},
        { 0x0104,       "Find File Both Directory Info"},
+       { 0x0105,       "Find File Full Directory Info"},
+       { 0x0106,       "Find File Id Both Directory Info"},
        { 0x0202,       "Find File UNIX"},
        {0, NULL}
 };
@@ -10169,16 +10507,19 @@ static const true_false_string tfs_get_dfs_fielding = {
        "The server in referrals is NOT fielding capable"
 };
 
-static const true_false_string tfs_dfs_referral_flags_strip = {
-       "STRIP off pathconsumed characters before submitting",
-       "Do NOT strip off any characters"
+static const true_false_string tfs_dfs_referral_flags_name_list_referral = {
+       "A domain/DC referral response",
+       "NOT a domain/DC referral response"
+};
+
+static const true_false_string tfs_dfs_referral_flags_target_set_boundary = {
+       "The first target in the target set",
+       "NOT the first target in the target set"
 };
 
 static const value_string dfs_referral_server_type_vals[] = {
-       {0,     "Don't know"},
-       {1,     "SMB Server"},
-       {2,     "Netware Server"},
-       {3,     "Domain Server"},
+       {0,     "Non-root targets returned"},
+       {1,     "Root targets returns"},
        {0, NULL}
 };
 
@@ -10370,8 +10711,8 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                tvb_ensure_bytes_exist(tvb, offset, bc);
                item = proto_tree_add_text(parent_tree, tvb, offset, bc,
                                "%s Parameters",
-                               val_to_str(subcmd, trans2_cmd_vals,
-                                          "Unknown (0x%02x)"));
+                               val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
+                                              "Unknown (0x%02x)"));
                tree = proto_item_add_subtree(item, ett_smb_transaction_params);
        }
 
@@ -10394,7 +10735,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
 
                /* File Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_file_attributes(tvb, tree, offset, 2);
+               offset = dissect_file_attributes(tvb, tree, offset);
                bc -= 2;
 
                /* create time */
@@ -10873,7 +11214,9 @@ dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                        "Flags: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
 
-               proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
+               proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_name_list_referral,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_target_set_boundary,
                        tvb, offset, 2, mask);
        }
 
@@ -10926,102 +11269,307 @@ dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
        return offset;
 }
 
-/* get dfs referral data  (4.4.1)
-*/
 static int
-dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *tree, int offset, guint16 *bcp)
+dissect_dfs_referral_strings(tvbuff_t *tvb, proto_tree *tree, int hfindex,
+                            int nstring, int stroffset, int oldoffset, int offset,
+                            guint16 bc, gboolean unicode, int *end)
 {
-       smb_info_t *si = pinfo->private_data;
-       guint16 numref;
-       guint16 refsize;
+       int istring;
+       const char *str;
+       int str_len;       /* string length including the terminating NULL. */
+
+       if (stroffset <= oldoffset)
+               return oldoffset;
+
+       bc -= (stroffset - offset);
+       for (istring=0; istring<nstring; istring++) {
+               if ((gint16)bc > 0) {
+                       str = get_unicode_or_ascii_string(tvb, &stroffset, unicode, &str_len, FALSE, FALSE, &bc);
+                       CHECK_STRING_TRANS_SUBR(str);
+                       proto_tree_add_string(tree, hfindex, tvb, stroffset, str_len, str);
+                       stroffset += str_len;
+                       bc -= str_len;
+                       if (end && (*end < stroffset))
+                               *end = stroffset;
+               }
+       }
+
+       return offset;
+}
+
+
+static int
+dissect_dfs_referral_string(tvbuff_t *tvb, proto_tree *tree, int hfindex,
+                           int stroffset, int oldoffset, int offset,
+                           guint16 bc, gboolean unicode, int *end)
+{
+       return dissect_dfs_referral_strings(tvb, tree, hfindex,
+                                          1, stroffset, oldoffset, offset,
+                                          bc, unicode, end);
+}
+
+static int
+dissect_dfs_referral_entry_v2(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
+                             guint16 refflags _U_, guint16 *bcp, gboolean unicode, int *ucstring_end)
+{
+
        guint16 pathoffset;
        guint16 altpathoffset;
        guint16 nodeoffset;
-       int fn_len;
-       int stroffset;
-       int offsetoffset;
-       guint16 save_bc;
-       const char *fn;
-       int unklen;
-       int ucstring_end;
-       int ucstring_len;
 
-       DISSECTOR_ASSERT(si);
+       /* proximity */
+       CHECK_BYTE_COUNT_TRANS_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_dfs_referral_proximity, tvb, offset, 4, TRUE);
+       COUNT_BYTES_TRANS_SUBR(4);
 
-       /* path consumed */
-       CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
-       COUNT_BYTES_TRANS_SUBR(2);
+       /* ttl */
+       CHECK_BYTE_COUNT_TRANS_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, TRUE);
+       COUNT_BYTES_TRANS_SUBR(4);
 
-       /* num referrals */
+       /* path offset */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       numref = tvb_get_letohs(tvb, offset);
-       proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
+       pathoffset = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
        COUNT_BYTES_TRANS_SUBR(2);
 
-       /* get dfs flags */
+       /* alt path offset */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       offset = dissect_get_dfs_flags(tvb, tree, offset);
-       *bcp -= 2;
+       altpathoffset = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
+       COUNT_BYTES_TRANS_SUBR(2);
 
-       /* XXX - in at least one capture there appears to be 2 bytes
-          of stuff after the Dfs flags, perhaps so that the header
-          in front of the referral list is a multiple of 4 bytes long. */
+       /* node offset */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
+       nodeoffset = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
        COUNT_BYTES_TRANS_SUBR(2);
 
-       /* if there are any referrals */
-       if(numref){
-               proto_item *ref_item = NULL;
-               proto_tree *ref_tree = NULL;
-               int old_offset=offset;
-
-               if(tree){
-                       tvb_ensure_bytes_exist(tvb, offset, *bcp);
-                       ref_item = proto_tree_add_text(tree,
-                               tvb, offset, *bcp, "Referrals");
-                       ref_tree = proto_item_add_subtree(ref_item,
-                               ett_smb_dfs_referrals);
-               }
-               ucstring_end = -1;
+       /* path */
+       if (pathoffset) {
+               dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
+                                           pathoffset+oldoffset, oldoffset, offset,
+                                           *bcp, unicode, ucstring_end);
+       }
 
-               while(numref--){
-                       proto_item *ri = NULL;
-                       proto_tree *rt = NULL;
-                       int old_offset=offset;
-                       guint16 version;
+       /* alt path */
+       if (altpathoffset) {
+               dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
+                                           altpathoffset+oldoffset, oldoffset, offset,
+                                           *bcp, unicode, ucstring_end);
+       }
 
-                       if(tree){
-                               tvb_ensure_bytes_exist(tvb, offset, *bcp);
-                               ri = proto_tree_add_text(ref_tree,
-                                       tvb, offset, *bcp, "Referral");
-                               rt = proto_item_add_subtree(ri,
-                                       ett_smb_dfs_referral);
-                       }
+       /* node */
+       if (nodeoffset) {
+               dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
+                                           nodeoffset+oldoffset, oldoffset, offset,
+                                           *bcp, unicode, ucstring_end);
+       }
 
-                       /* referral version */
-                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                       version = tvb_get_letohs(tvb, offset);
-                       proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
-                               tvb, offset, 2, version);
-                       COUNT_BYTES_TRANS_SUBR(2);
+       return offset;
 
-                       /* referral size */
-                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                       refsize = tvb_get_letohs(tvb, offset);
-                       proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
-                       COUNT_BYTES_TRANS_SUBR(2);
+}
 
-                       /* referral server type */
-                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                       proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
-                       COUNT_BYTES_TRANS_SUBR(2);
 
-                       /* referral flags */
-                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                       offset = dissect_dfs_referral_flags(tvb, rt, offset);
+static int
+dissect_dfs_referral_entry_v3(tvbuff_t *tvb, proto_tree *tree, int oldoffset, int offset,
+                             guint16 refflags, guint16 *bcp, gboolean unicode, int *ucstring_end)
+{
+       guint16 domoffset;
+       guint16 nexpnames;
+       guint16 expoffset;
+       guint16 pathoffset;
+       guint16 altpathoffset;
+       guint16 nodeoffset;
+
+       /* ttl */
+       CHECK_BYTE_COUNT_TRANS_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_dfs_referral_ttl, tvb, offset, 4, TRUE);
+       COUNT_BYTES_TRANS_SUBR(4);
+
+       if (refflags & REFENT_FLAGS_NAME_LIST_REFERRAL) {
+               /* domain name offset */
+               CHECK_BYTE_COUNT_TRANS_SUBR(2);
+               domoffset = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_dfs_referral_domain_offset, tvb, offset, 2, domoffset);
+               COUNT_BYTES_TRANS_SUBR(2);
+
+               /* number of expanded names*/
+               CHECK_BYTE_COUNT_TRANS_SUBR(2);
+               nexpnames = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_dfs_referral_number_of_expnames, tvb, offset, 2, nexpnames);
+               COUNT_BYTES_TRANS_SUBR(2);
+
+               /* expanded names offset */
+               CHECK_BYTE_COUNT_TRANS_SUBR(2);
+               expoffset = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_dfs_referral_expnames_offset, tvb, offset, 2, expoffset);
+               COUNT_BYTES_TRANS_SUBR(2);
+
+               /* padding: zero or 16 bytes, which should be ignored by clients.
+                * we ignore them too.
+                */
+
+               /* domain name */
+               if (domoffset) {
+                       dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_domain_name,
+                                                   domoffset+oldoffset, oldoffset, offset,
+                                                   *bcp, unicode, ucstring_end);
+               }
+               /* expanded names */
+               if (expoffset) {
+                       proto_item *expitem = NULL;
+                       proto_tree *exptree = NULL;
+
+                       expitem = proto_tree_add_text(tree, tvb, offset, *bcp, "Expanded Names");
+                       exptree = proto_item_add_subtree(expitem, ett_smb_dfs_referral_expnames);
+
+                       dissect_dfs_referral_strings(tvb, exptree, hf_smb_dfs_referral_expname,
+                                                    nexpnames, expoffset+oldoffset, oldoffset, offset,
+                                                    *bcp, unicode, ucstring_end);
+               }
+       } else {
+               /* path offset */
+               CHECK_BYTE_COUNT_TRANS_SUBR(2);
+               pathoffset = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
+               COUNT_BYTES_TRANS_SUBR(2);
+
+               /* alt path offset */
+               CHECK_BYTE_COUNT_TRANS_SUBR(2);
+               altpathoffset = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
+               COUNT_BYTES_TRANS_SUBR(2);
+
+               /* node offset */
+               CHECK_BYTE_COUNT_TRANS_SUBR(2);
+               nodeoffset = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
+               COUNT_BYTES_TRANS_SUBR(2);
+
+               /* service site guid */
+               CHECK_BYTE_COUNT_TRANS_SUBR(16);
+               proto_tree_add_item(tree, hf_smb_dfs_referral_server_guid, tvb, offset, 16, TRUE);
+               COUNT_BYTES_TRANS_SUBR(16);
+
+               /* path */
+               if (pathoffset) {
+                       dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
+                                                   pathoffset+oldoffset, oldoffset, offset,
+                                                   *bcp, unicode, ucstring_end);
+               }
+
+               /* alt path */
+               if (altpathoffset) {
+                       dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
+                                                   altpathoffset+oldoffset, oldoffset, offset,
+                                                   *bcp, unicode, ucstring_end);
+               }
+
+               /* node */
+               if (nodeoffset) {
+                       dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
+                                                   nodeoffset+oldoffset, oldoffset, offset,
+                                                   *bcp, unicode, ucstring_end);
+               }
+       }
+
+       return offset;
+
+}
+
+/* get dfs referral data  (4.4.1)
+*/
+static int
+dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
+    proto_tree *tree, int offset, guint16 *bcp)
+{
+       smb_info_t *si = pinfo->private_data;
+       guint16 numref;
+       guint16 refsize;
+       guint16 refflags;
+       int fn_len;
+       const char *fn;
+       int unklen;
+       int ucstring_end;
+       int ucstring_len;
+
+       DISSECTOR_ASSERT(si);
+
+       /* path consumed */
+       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+       proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
+       COUNT_BYTES_TRANS_SUBR(2);
+
+       /* num referrals */
+       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+       numref = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
+       COUNT_BYTES_TRANS_SUBR(2);
+
+       /* get dfs flags */
+       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+       offset = dissect_get_dfs_flags(tvb, tree, offset);
+       *bcp -= 2;
+
+       /* XXX - in at least one capture there appears to be 2 bytes
+          of stuff after the Dfs flags, perhaps so that the header
+          in front of the referral list is a multiple of 4 bytes long. */
+       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+       proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
+       COUNT_BYTES_TRANS_SUBR(2);
+
+       /* if there are any referrals */
+       if(numref){
+               proto_item *ref_item = NULL;
+               proto_tree *ref_tree = NULL;
+               int old_offset=offset;
+
+               if(tree){
+                       tvb_ensure_bytes_exist(tvb, offset, *bcp);
+                       ref_item = proto_tree_add_text(tree,
+                               tvb, offset, *bcp, "Referrals");
+                       ref_tree = proto_item_add_subtree(ref_item,
+                               ett_smb_dfs_referrals);
+               }
+               ucstring_end = -1;
+
+               while(numref--){
+                       proto_item *ri = NULL;
+                       proto_tree *rt = NULL;
+                       int old_offset_2=offset;
+                       guint16 version;
+
+                       if(tree){
+                               tvb_ensure_bytes_exist(tvb, offset, *bcp);
+                               ri = proto_tree_add_text(ref_tree,
+                                       tvb, offset, *bcp, "Referral");
+                               rt = proto_item_add_subtree(ri,
+                                       ett_smb_dfs_referral);
+                       }
+
+                       /* referral version */
+                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+                       version = tvb_get_letohs(tvb, offset);
+                       proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
+                               tvb, offset, 2, version);
+                       COUNT_BYTES_TRANS_SUBR(2);
+
+                       /* referral size */
+                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+                       refsize = tvb_get_letohs(tvb, offset);
+                       proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
+                       COUNT_BYTES_TRANS_SUBR(2);
+
+                       /* referral server type */
+                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+                       proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
+                       COUNT_BYTES_TRANS_SUBR(2);
+
+                       /* referral flags */
+                       CHECK_BYTE_COUNT_TRANS_SUBR(2);
+                       refflags = tvb_get_letohs(tvb, offset);
+                       offset = dissect_dfs_referral_flags(tvb, rt, offset);
                        *bcp -= 2;
 
                        switch(version){
@@ -11036,93 +11584,18 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                break;
 
                        case 2:
-                       case 3: /* XXX - like version 2, but not identical;
-                                  seen in a capture, but the format isn't
-                                  documented */
-                               /* proximity */
-                               CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                               proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
-                               COUNT_BYTES_TRANS_SUBR(2);
-
-                               /* ttl */
-                               CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                               proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
-                               COUNT_BYTES_TRANS_SUBR(2);
-
-                               /* path offset */
-                               CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                               pathoffset = tvb_get_letohs(tvb, offset);
-                               proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
-                               COUNT_BYTES_TRANS_SUBR(2);
-
-                               /* alt path offset */
-                               CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                               altpathoffset = tvb_get_letohs(tvb, offset);
-                               proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
-                               COUNT_BYTES_TRANS_SUBR(2);
-
-                               /* node offset */
-                               CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                               nodeoffset = tvb_get_letohs(tvb, offset);
-                               proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
-                               COUNT_BYTES_TRANS_SUBR(2);
-
-                               /* path */
-                               if (pathoffset != 0) {
-                                       stroffset = old_offset + pathoffset;
-                                       offsetoffset = stroffset - offset;
-                                       if (offsetoffset > 0 &&
-                                           *bcp > offsetoffset) {
-                                               save_bc = *bcp;
-                                               *bcp -= offsetoffset;
-                                               fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
-                                               CHECK_STRING_TRANS_SUBR(fn);
-                                               proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
-                                                       fn);
-                                               stroffset += fn_len;
-                                               if (ucstring_end < stroffset)
-                                                       ucstring_end = stroffset;
-                                               *bcp = save_bc;
-                                       }
-                               }
-
-                               /* alt path */
-                               if (altpathoffset != 0) {
-                                       stroffset = old_offset + altpathoffset;
-                                       offsetoffset = stroffset - offset;
-                                       if (offsetoffset > 0 &&
-                                           *bcp > offsetoffset) {
-                                               save_bc = *bcp;
-                                               *bcp -= offsetoffset;
-                                               fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
-                                               CHECK_STRING_TRANS_SUBR(fn);
-                                               proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
-                                                       fn);
-                                               stroffset += fn_len;
-                                               if (ucstring_end < stroffset)
-                                                       ucstring_end = stroffset;
-                                               *bcp = save_bc;
-                                       }
-                               }
-
-                               /* node */
-                               if (nodeoffset != 0) {
-                                       stroffset = old_offset + nodeoffset;
-                                       offsetoffset = stroffset - offset;
-                                       if (offsetoffset > 0 &&
-                                           *bcp > offsetoffset) {
-                                               save_bc = *bcp;
-                                               *bcp -= offsetoffset;
-                                               fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
-                                               CHECK_STRING_TRANS_SUBR(fn);
-                                               proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
-                                                       fn);
-                                               stroffset += fn_len;
-                                               if (ucstring_end < stroffset)
-                                                       ucstring_end = stroffset;
-                                               *bcp = save_bc;
-                                       }
-                               }
+                               offset = dissect_dfs_referral_entry_v2(tvb, rt, old_offset_2, offset,
+                                                                      refflags, bcp, si->unicode, &ucstring_end);
+                               break;
+                       case 3:
+                               offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
+                                                                      refflags, bcp, si->unicode, &ucstring_end);
+                               break;
+                       case 4:
+                               /* V4 is extactly same as V3, except the version number and
+                                * one more ReferralEntryFlags */
+                               offset = dissect_dfs_referral_entry_v3(tvb, rt, old_offset_2, offset,
+                                                                      refflags, bcp, si->unicode, &ucstring_end);
                                break;
                        }
 
@@ -11130,7 +11603,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                         * Show anything beyond the length of the referral
                         * as unknown data.
                         */
-                       unklen = (old_offset + refsize) - offset;
+                       unklen = (old_offset_2 + refsize) - offset;
                        if (unklen < 0) {
                                /*
                                 * XXX - the length is bogus.
@@ -11144,7 +11617,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                COUNT_BYTES_TRANS_SUBR(unklen);
                        }
 
-                       proto_item_set_len(ri, offset-old_offset);
+                       proto_item_set_len(ri, offset-old_offset_2);
                }
 
                /*
@@ -11237,7 +11710,7 @@ dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        /* ea length */
@@ -11363,7 +11836,7 @@ dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_attributes(tvb, tree, offset, 4);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        *trunc = FALSE;
@@ -11565,7 +12038,7 @@ dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_attributes(tvb, tree, offset, 4);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* 4 pad bytes */
@@ -12056,7 +12529,7 @@ dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_attributes(tvb, tree, offset, 4);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
         /* Unknown, possibly count of network accessors ... */
@@ -12574,8 +13047,8 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
                tvb_ensure_bytes_exist(tvb, offset, dc);
                item = proto_tree_add_text(parent_tree, tvb, offset, dc,
                                "%s Data",
-                               val_to_str(subcmd, trans2_cmd_vals,
-                                               "Unknown (0x%02x)"));
+                               val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
+                                              "Unknown (0x%02x)"));
                tree = proto_item_add_subtree(item, ett_smb_transaction_data);
        }
 
@@ -12921,8 +13394,8 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                    tvb, offset, 2, subcmd);
                                if (check_col(pinfo->cinfo, COL_INFO)) {
                                        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
-                                           val_to_str(subcmd, trans2_cmd_vals,
-                                               "Unknown (0x%02x)"));
+                                           val_to_str_ext(subcmd, &trans2_cmd_vals_ext,
+                                                          "Unknown (0x%02x)"));
                                }
                                if (!si->unidir) {
                                        if(!pinfo->fd->flags.visited && si->sip){
@@ -13128,11 +13601,11 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                 * A tvbuff containing the parameters and the
                                 * data.
                                 */
-                               pd_tvb = tvb_new_subset(tvb, po, -1, -1);
+                               pd_tvb = tvb_new_subset_remaining(tvb, po);
 
                                dissected_trans = dissect_pipe_smb(sp_tvb,
                                    s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
-                                   top_tree);
+                                   top_tree_global);
 
                                /* In case we did not see the TreeConnect call,
                                   store this TID here as well as a IPC TID
@@ -13153,15 +13626,13 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                 */
                                sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
                                dissected_trans = dissect_mailslot_smb(sp_tvb,
-                                   s_tvb, d_tvb, an+10, pinfo, top_tree);
+                                   s_tvb, d_tvb, an+10, pinfo, top_tree_global);
                        }
                        if (!dissected_trans)
                                dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
                } else {
-                       if(check_col(pinfo->cinfo, COL_INFO)){
-                               col_append_str(pinfo->cinfo, COL_INFO,
+                       col_append_str(pinfo->cinfo, COL_INFO,
                                        "[transact continuation]");
-                       }
                }
        }
 
@@ -13241,7 +13712,7 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        /* file name len */
@@ -13342,7 +13813,7 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        /* ea length */
@@ -13714,6 +14185,267 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        return offset;
 }
 
+static int
+dissect_4_3_4_6full(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+    int offset, guint16 *bcp, gboolean *trunc)
+{
+       int fn_len;
+       const char *fn;
+       int old_offset = offset;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+       smb_info_t *si;
+       guint32 neo;
+       int padcnt;
+
+       si = (smb_info_t *)pinfo->private_data;
+       DISSECTOR_ASSERT(si);
+
+       if(parent_tree){
+               tvb_ensure_bytes_exist(tvb, offset, *bcp);
+               item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
+                   val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
+               tree = proto_item_add_subtree(item, ett_smb_ff2_data);
+       }
+
+       /*
+        * XXX - I have not seen any of these that contain a resume
+        * key, even though some of the requests had the "return resume
+        * key" flag set.
+        */
+
+       /* next entry offset */
+       CHECK_BYTE_COUNT_SUBR(4);
+       neo = tvb_get_letohl(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
+       COUNT_BYTES_SUBR(4);
+
+       /* file index */
+       CHECK_BYTE_COUNT_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
+       COUNT_BYTES_SUBR(4);
+
+        /* dissect standard 8-byte timestamps */
+       offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
+       if (*trunc) {
+         return offset;
+       }
+
+       /* end of file */
+       CHECK_BYTE_COUNT_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
+       COUNT_BYTES_SUBR(8);
+
+       /* allocation size */
+       CHECK_BYTE_COUNT_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
+       COUNT_BYTES_SUBR(8);
+
+       /* Extended File Attributes */
+       CHECK_BYTE_COUNT_SUBR(4);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
+       *bcp -= 4;
+
+       /* file name len */
+       CHECK_BYTE_COUNT_SUBR(4);
+       fn_len = tvb_get_letohl(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
+       COUNT_BYTES_SUBR(4);
+
+       /*
+        * EA length.
+        *
+        * XXX - in one captures, this has the topmost bit set, and the
+        * rest of the bits have the value 7.  Is the topmost bit being
+        * set some indication that the value *isn't* the length of
+        * the EAs?
+        */
+       CHECK_BYTE_COUNT_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
+       COUNT_BYTES_SUBR(4);
+
+       /* skip 4 bytes */
+       COUNT_BYTES_SUBR(4);
+
+       CHECK_BYTE_COUNT_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
+       COUNT_BYTES_SUBR(8);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
+       CHECK_STRING_SUBR(fn);
+       proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+               fn);
+       COUNT_BYTES_SUBR(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
+                   format_text(fn, strlen(fn)));
+       }
+
+       /* skip to next structure */
+       if(neo){
+               padcnt = (old_offset + neo) - offset;
+               if (padcnt < 0) {
+                       /*
+                        * XXX - this is bogus; flag it?
+                        */
+                       padcnt = 0;
+               }
+               if (padcnt != 0) {
+                       CHECK_BYTE_COUNT_SUBR(padcnt);
+                       COUNT_BYTES_SUBR(padcnt);
+               }
+       }
+
+       proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
+       proto_item_set_len(item, offset-old_offset);
+
+       *trunc = FALSE;
+       return offset;
+}
+
+static int
+dissect_4_3_4_6_id_both(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+    int offset, guint16 *bcp, gboolean *trunc)
+{
+       int fn_len, sfn_len;
+       const char *fn, *sfn;
+       int old_offset = offset;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+       smb_info_t *si;
+       guint32 neo;
+       int padcnt;
+
+       si = (smb_info_t *)pinfo->private_data;
+       DISSECTOR_ASSERT(si);
+
+       if(parent_tree){
+               tvb_ensure_bytes_exist(tvb, offset, *bcp);
+               item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
+                   val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
+               tree = proto_item_add_subtree(item, ett_smb_ff2_data);
+       }
+
+       /*
+        * XXX - I have not seen any of these that contain a resume
+        * key, even though some of the requests had the "return resume
+        * key" flag set.
+        */
+
+       /* next entry offset */
+       CHECK_BYTE_COUNT_SUBR(4);
+       neo = tvb_get_letohl(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
+       COUNT_BYTES_SUBR(4);
+
+       /* file index */
+       CHECK_BYTE_COUNT_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
+       COUNT_BYTES_SUBR(4);
+
+        /* dissect standard 8-byte timestamps */
+       offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
+       if (*trunc) {
+         return offset;
+       }
+
+       /* end of file */
+       CHECK_BYTE_COUNT_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
+       COUNT_BYTES_SUBR(8);
+
+       /* allocation size */
+       CHECK_BYTE_COUNT_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
+       COUNT_BYTES_SUBR(8);
+
+       /* Extended File Attributes */
+       CHECK_BYTE_COUNT_SUBR(4);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
+       *bcp -= 4;
+
+       /* file name len */
+       CHECK_BYTE_COUNT_SUBR(4);
+       fn_len = tvb_get_letohl(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
+       COUNT_BYTES_SUBR(4);
+
+       /*
+        * EA length.
+        *
+        * XXX - in one captures, this has the topmost bit set, and the
+        * rest of the bits have the value 7.  Is the topmost bit being
+        * set some indication that the value *isn't* the length of
+        * the EAs?
+        */
+       CHECK_BYTE_COUNT_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
+       COUNT_BYTES_SUBR(4);
+
+       /* short file name len */
+       CHECK_BYTE_COUNT_SUBR(1);
+       sfn_len = tvb_get_guint8(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
+       COUNT_BYTES_SUBR(1);
+
+       /* reserved byte */
+       CHECK_BYTE_COUNT_SUBR(1);
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+       COUNT_BYTES_SUBR(1);
+
+       /* short file name - it's not always in Unicode */
+       sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
+       CHECK_STRING_SUBR(sfn);
+       proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
+               sfn);
+       COUNT_BYTES_SUBR(24);
+
+       /* reserved bytes */
+       CHECK_BYTE_COUNT_SUBR(2);
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
+       COUNT_BYTES_SUBR(2);
+
+       /* file id */
+       CHECK_BYTE_COUNT_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
+       COUNT_BYTES_SUBR(8);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
+       CHECK_STRING_SUBR(fn);
+       proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+               fn);
+       COUNT_BYTES_SUBR(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
+                   format_text(fn, strlen(fn)));
+       }
+
+       /* skip to next structure */
+       if(neo){
+               padcnt = (old_offset + neo) - offset;
+               if (padcnt < 0) {
+                       /*
+                        * XXX - this is bogus; flag it?
+                        */
+                       padcnt = 0;
+               }
+               if (padcnt != 0) {
+                       CHECK_BYTE_COUNT_SUBR(padcnt);
+                       COUNT_BYTES_SUBR(padcnt);
+               }
+       }
+
+       proto_item_append_text(item, " File: %s", format_text(fn, strlen(fn)));
+       proto_item_set_len(item, offset-old_offset);
+
+       *trunc = FALSE;
+       return offset;
+}
+
 static int
 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
     int offset, guint16 *bcp, gboolean *trunc)
@@ -13944,6 +14676,14 @@ dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
                offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
                    trunc);
                break;
+       case 0x0105:    /*Find File Full Directory Info*/
+               offset = dissect_4_3_4_6full(tvb, pinfo, tree, offset, bcp,
+                   trunc);
+               break;
+       case 0x0106:    /*Find File Id Both Directory Info*/
+               offset = dissect_4_3_4_6_id_both(tvb, pinfo, tree, offset, bcp,
+                   trunc);
+               break;
        case 0x0202:    /*Find File UNIX*/
                offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
                    trunc);
@@ -14340,7 +15080,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                offset = dissect_qfsi_FS_ATTRIBUTE_INFO(tvb, pinfo, tree, offset, bcp, si->unicode);
                break;
        case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
-               proto_item *item = NULL;
+               proto_item *item_2 = NULL;
                proto_tree *subtree = NULL;
                guint32 caps_lo, caps_hi;
 
@@ -14362,11 +15102,11 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                caps_hi = tvb_get_letohl(tvb, offset + 4);
 
                if (tree) {
-                       item = proto_tree_add_text(
+                       item_2 = proto_tree_add_text(
                                tree, tvb, offset, 8, "Capabilities: 0x%08x%08x",
                                caps_hi, caps_lo);
                        subtree = proto_item_add_subtree(
-                               item, ett_smb_unix_capabilities);
+                               item_2, ett_smb_unix_capabilities);
                }
 
                proto_tree_add_boolean(
@@ -14440,7 +15180,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                COUNT_BYTES_TRANS_SUBR(4);
                /* Mac Support Flags */
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               support = tvb_get_ntohl(tvb, offset);
+               support = tvb_get_letohl(tvb, offset);
                item = proto_tree_add_text(tree, tvb, offset, 4,
                                           "Mac Support Flags: 0x%08x", support);
                ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
@@ -14498,8 +15238,8 @@ dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
                if (t2i != NULL && t2i->subcmd != -1) {
                        item = proto_tree_add_text(parent_tree, tvb, offset, dc,
                                "%s Data",
-                               val_to_str(t2i->subcmd, trans2_cmd_vals,
-                                       "Unknown (0x%02x)"));
+                               val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
+                                              "Unknown (0x%02x)"));
                        tree = proto_item_add_subtree(item, ett_smb_transaction_data);
                } else {
                        item = proto_tree_add_text(parent_tree, tvb, offset, dc,
@@ -14673,8 +15413,8 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                if (t2i != NULL && t2i->subcmd != -1) {
                        item = proto_tree_add_text(parent_tree, tvb, offset, pc,
                                "%s Parameters",
-                               val_to_str(t2i->subcmd, trans2_cmd_vals,
-                                               "Unknown (0x%02x)"));
+                               val_to_str_ext(t2i->subcmd, &trans2_cmd_vals_ext,
+                                              "Unknown (0x%02x)"));
                        tree = proto_item_add_subtree(item, ett_smb_transaction_params);
                } else {
                        item = proto_tree_add_text(parent_tree, tvb, offset, pc,
@@ -14708,7 +15448,7 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                 */
 
                /* File Attributes */
-               offset = dissect_file_attributes(tvb, tree, offset, 2);
+               offset = dissect_file_attributes(tvb, tree, offset);
 
                /* create time */
                offset = dissect_smb_datetime(tvb, tree, offset,
@@ -14940,9 +15680,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                         */
                        proto_tree_add_text(tree, tvb, 0, 0,
                                "Subcommand: <UNKNOWN> since request packet wasn't seen");
-                       if (check_col(pinfo->cinfo, COL_INFO)) {
-                               col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
-                       }
+                       col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
                } else {
                        si->info_level = t2i->info_level;
                        if (t2i->subcmd == -1) {
@@ -14954,9 +15692,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                 */
                                proto_tree_add_text(tree, tvb, 0, 0,
                                        "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
-                               if (check_col(pinfo->cinfo, COL_INFO)) {
-                                       col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
-                               }
+                               col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
                        } else {
                                proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
                                /* FIND_FIRST2 */
@@ -14991,9 +15727,9 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
 
                                if (t2i && check_col(pinfo->cinfo, COL_INFO)) {
                                        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
-                                               val_to_str(t2i->subcmd,
-                                                       trans2_cmd_vals,
-                                                       "<unknown (0x%02x)>"));
+                                               val_to_str_ext(t2i->subcmd,
+                                                              &trans2_cmd_vals_ext,
+                                                              "<unknown (0x%02x)>"));
                                }
                        }
                }
@@ -15063,7 +15799,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                } else {
                        s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
                }
-               sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
+               sp_tvb = tvb_new_subset_remaining(tvb, offset);
        } else {
                s_tvb = NULL;
                sp_tvb=NULL;
@@ -15105,9 +15841,8 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
        if(r_fd){
         proto_item *frag_tree_item;
 
-               pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
+               pd_tvb = tvb_new_child_real_data(tvb, r_fd->data, r_fd->datalen,
                                             r_fd->datalen);
-               tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
                add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
                show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb, &frag_tree_item);
        }
@@ -15146,7 +15881,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                         * XXX - check pc and dc as well?
                         */
                        if (tvb_length_remaining(tvb, po)){
-                               pd_tvb = tvb_new_subset(tvb, po, -1, -1);
+                               pd_tvb = tvb_new_subset_remaining(tvb, po);
                        }
                }
        }
@@ -15224,7 +15959,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                if( pd_tvb) {
                                        dissected_trans = dissect_pipe_smb(
                                                sp_tvb, s_tvb, pd_tvb, p_tvb,
-                                               d_tvb, NULL, pinfo, top_tree);
+                                               d_tvb, NULL, pinfo, top_tree_global);
                                }
                                break;
 
@@ -15235,7 +15970,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                                if(d_tvb){
                                        dissected_trans = dissect_mailslot_smb(
                                                sp_tvb, s_tvb, d_tvb, NULL, pinfo,
-                                               top_tree);
+                                               top_tree_global);
                                }
                                break;
                        }
@@ -15248,10 +15983,8 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
 
 
        if( (p_tvb==0) && (d_tvb==0) ){
-               if(check_col(pinfo->cinfo, COL_INFO)){
-                       col_append_str(pinfo->cinfo, COL_INFO,
+               col_append_str(pinfo->cinfo, COL_INFO,
                                       "[transact continuation]");
-               }
        }
 
        pinfo->fragmented = save_fragmented;
@@ -15657,8 +16390,10 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *s
  * This means that this value_string array MUST always
  * 1, contain all entries 0x00 to 0xff
  * 2, all entries must be in order.
+ * Note: This value_string array can also be accessed directly via the use of value_string_ext
+ * ToDo?: use val_to_str_ext instead of decode_smb_name() ?
  */
-const value_string smb_cmd_vals[] = {
+static const value_string smb_cmd_vals[] = {
   { 0x00, "Create Directory" },
   { 0x01, "Delete Directory" },
   { 0x02, "Open" },
@@ -15918,6 +16653,8 @@ const value_string smb_cmd_vals[] = {
   { 0x00, NULL },
 };
 
+value_string_ext smb_cmd_vals_ext = VALUE_STRING_EXT_INIT(smb_cmd_vals);
+
 static const char *decode_smb_name(guint8 cmd)
 {
   return(smb_cmd_vals[cmd].strptr);
@@ -16222,16 +16959,12 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        conversation_t *conversation;
        nstime_t t, deltat;
 
-       si=ep_alloc(sizeof(smb_info_t));
+       si=ep_alloc0(sizeof(smb_info_t));
 
-       top_tree=parent_tree;
+       top_tree_global=parent_tree;
 
-       if (check_col(pinfo->cinfo, COL_PROTOCOL)){
-               col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
-       }
-       if (check_col(pinfo->cinfo, COL_INFO)){
-               col_clear(pinfo->cinfo, COL_INFO);
-       }
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
+       col_clear(pinfo->cinfo, COL_INFO);
 
        /* start off using the local variable, we will allocate a new one if we
           need to*/
@@ -16275,13 +17008,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
 
        /* find which conversation we are part of and get the tables for that
           conversation*/
-       conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
-                pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
-       if(!conversation){
-               /* OK this is a new conversation so lets create it */
-               conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
-                       pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
-       }
+       conversation = find_or_create_conversation(pinfo);
        /* see if we already have the smb data for this conversation */
        si->ct=conversation_get_proto_data(conversation, proto_smb);
        if(!si->ct){
@@ -16301,6 +17028,8 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                si->ct->fid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB fid_tree");
                si->ct->tid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB tid_tree");
                si->ct->uid_tree=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "SMB uid_tree");
+                /* Initialize the GSL_fid_info for this ct */
+                si->ct->GSL_fid_info=NULL;
                conversation_add_proto_data(conversation, proto_smb, si->ct);
        }
 
@@ -16770,16 +17499,16 @@ proto_register_smb(void)
 {
        static hf_register_info hf[] = {
        { &hf_smb_cmd,
-               { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
-               VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
+               { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
+               &smb_cmd_vals_ext, 0x0, NULL, HFILL }},
 
        { &hf_smb_trans2_subcmd,
-               { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
-               VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
+               { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
+               &trans2_cmd_vals_ext, 0, "Subcommand for TRANSACTION2", HFILL }},
 
        { &hf_smb_nt_trans_subcmd,
-               { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
-               VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
+               { "Function", "smb.nt.function", FT_UINT16, BASE_DEC|BASE_EXT_STRING,
+               &nt_cmd_vals_ext, 0, "Function for NT Transaction", HFILL }},
 
        { &hf_smb_word_count,
                { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
@@ -16818,11 +17547,11 @@ proto_register_smb(void)
                NULL, 0, "DOS Error Code", HFILL }},
 
        { &hf_smb_reserved,
-               { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
+               { "Reserved", "smb.reserved", FT_BYTES, BASE_NONE,
                NULL, 0, "Reserved bytes, must be zero", HFILL }},
 
        { &hf_smb_sig,
-               { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
+               { "Signature", "smb.signature", FT_BYTES, BASE_NONE,
                NULL, 0, "Signature bytes", HFILL }},
 
        { &hf_smb_key,
@@ -16843,7 +17572,7 @@ proto_register_smb(void)
 
        { &hf_smb_pid,
                { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
-               NULL, 0, "Process ID", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_pid_high,
                { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
@@ -16851,15 +17580,15 @@ proto_register_smb(void)
 
        { &hf_smb_tid,
                { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
-               NULL, 0, "Tree ID", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_uid,
                { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
-               NULL, 0, "User ID", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_mid,
                { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
-               NULL, 0, "Multiplex ID", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_flags_lock,
                { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
@@ -16962,7 +17691,7 @@ proto_register_smb(void)
                NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
 
        { &hf_smb_encryption_key,
-               { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
+               { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_NONE,
                NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
 
        { &hf_smb_primary_domain,
@@ -16978,16 +17707,16 @@ proto_register_smb(void)
                NULL, 0, "Maximum raw buffer size", HFILL }},
 
        { &hf_smb_server_guid,
-               { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
+               { "Server GUID", "smb.server_guid", FT_BYTES, BASE_NONE,
                NULL, 0, "Globally unique identifier for this server", HFILL }},
 
        { &hf_smb_security_blob_len,
                { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
-               NULL, 0, "Security blob length", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_security_blob,
-               { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
-               NULL, 0, "Security blob", HFILL }},
+               { "Security Blob", "smb.security_blob", FT_BYTES, BASE_NONE,
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_sm_mode16,
                { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
@@ -17022,7 +17751,7 @@ proto_register_smb(void)
                TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
 
        { &hf_smb_server_date_time,
-               { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                NULL, 0, "Current date and time at server", HFILL }},
 
        { &hf_smb_server_smb_date,
@@ -17095,7 +17824,7 @@ proto_register_smb(void)
 
        { &hf_smb_server_cap_reserved,
                { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
-               TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
+               TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, NULL, HFILL }},
 
        { &hf_smb_server_cap_bulk_transfer,
                { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
@@ -17110,11 +17839,11 @@ proto_register_smb(void)
                TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
 
        { &hf_smb_system_time,
-               { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
-               NULL, 0, "System Time", HFILL }},
+               { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unknown,
-               { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
+               { "Unknown Data", "smb.unknown_data", FT_BYTES, BASE_NONE,
                NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
 
        { &hf_smb_dir_name,
@@ -17126,7 +17855,7 @@ proto_register_smb(void)
                NULL, 0, "Number of times to echo data back", HFILL }},
 
        { &hf_smb_echo_data,
-               { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
+               { "Echo Data", "smb.echo.data", FT_BYTES, BASE_NONE,
                NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
 
        { &hf_smb_echo_seq_num,
@@ -17147,15 +17876,15 @@ proto_register_smb(void)
 
        { &hf_smb_password,
                { "Password", "smb.password", FT_BYTES, BASE_NONE,
-               NULL, 0, "Password", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ansi_password,
                { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
-               NULL, 0, "ANSI Password", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unicode_password,
                { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
-               NULL, 0, "Unicode Password", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_move_flags_file,
                { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
@@ -17215,7 +17944,7 @@ proto_register_smb(void)
 
        { &hf_smb_file_name,
                { "File Name", "smb.file", FT_STRING, BASE_NONE,
-               NULL, 0, "File Name", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_open_function_create,
                { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
@@ -17315,7 +18044,7 @@ proto_register_smb(void)
 
        { &hf_smb_file_size,
                { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
-               NULL, 0, "File Size", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_search_attribute_read_only,
                { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
@@ -17343,11 +18072,11 @@ proto_register_smb(void)
 
        { &hf_smb_access_mode,
                { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
-               VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
+               VALS(da_access_vals), 0x0007, NULL, HFILL }},
 
        { &hf_smb_access_sharing,
                { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
-               VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
+               VALS(da_sharing_vals), 0x0070, NULL, HFILL }},
 
        { &hf_smb_access_locality,
                { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
@@ -17362,20 +18091,20 @@ proto_register_smb(void)
                TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
 
        { &hf_smb_create_time,
-               { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Created", "smb.create.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                NULL, 0, "Creation Time", HFILL }},
 
        { &hf_smb_modify_time,
-               { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                  NULL, 0, "Modification Time", HFILL }},
 
        { &hf_smb_backup_time,
-               { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                  NULL, 0, "Backup time", HFILL}},
 
        { &hf_smb_mac_alloc_block_count,
                { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
-                 NULL, 0, "Allocation Block Count", HFILL}},
+                 NULL, 0, NULL, HFILL}},
 
        { &hf_smb_mac_alloc_block_size,
                { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
@@ -17383,15 +18112,15 @@ proto_register_smb(void)
 
        { &hf_smb_mac_free_block_count,
                { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
-                 NULL, 0, "Free Block Count", HFILL}},
+                 NULL, 0, NULL, HFILL}},
 
        { &hf_smb_mac_root_file_count,
                { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
-               NULL, 0, "Root File Count", HFILL}},
+               NULL, 0, NULL, HFILL}},
 
        { &hf_smb_mac_root_dir_count,
          { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
-           NULL, 0, "Root Directory Count", HFILL}},
+           NULL, 0, NULL, HFILL}},
 
        { &hf_smb_mac_file_count,
          { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
@@ -17403,7 +18132,7 @@ proto_register_smb(void)
 
        { &hf_smb_mac_support_flags,
          { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
-           NULL, 0, "Mac Support Flags", HFILL}},
+           NULL, 0, NULL, HFILL}},
 
        { &hf_smb_mac_sup_access_ctrl,
          { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
@@ -17434,7 +18163,7 @@ proto_register_smb(void)
                NULL, 0, "Create Time, SMB_TIME format", HFILL }},
 
        { &hf_smb_last_write_time,
-               { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                NULL, 0, "Time this file was last written to", HFILL }},
 
        { &hf_smb_last_write_dos_date,
@@ -17458,16 +18187,16 @@ proto_register_smb(void)
                NULL, 0, "Remaining number of bytes", HFILL }},
 
        { &hf_smb_padding,
-               { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
+               { "Padding", "smb.padding", FT_BYTES, BASE_NONE,
                NULL, 0, "Padding or unknown data", HFILL }},
 
        { &hf_smb_file_data,
-               { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
+               { "File Data", "smb.file_data", FT_BYTES, BASE_NONE,
                NULL, 0, "Data read/written to the file", HFILL }},
 
        { &hf_smb_mac_fndrinfo,
-               { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
-                 NULL, 0, "Finder Info", HFILL}},
+               { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_NONE,
+                 NULL, 0, NULL, HFILL}},
 
        { &hf_smb_total_data_len,
                { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
@@ -17490,7 +18219,7 @@ proto_register_smb(void)
                VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
 
        { &hf_smb_access_time,
-               { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                NULL, 0, "Last Access Time", HFILL }},
 
        { &hf_smb_access_dos_date,
@@ -17503,7 +18232,7 @@ proto_register_smb(void)
 
        { &hf_smb_data_size,
                { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
-               NULL, 0, "Data Size", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_alloc_size,
                { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
@@ -17527,7 +18256,7 @@ proto_register_smb(void)
 
        { &hf_smb_timeout,
                { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
-               NULL, 0, "Timeout in miliseconds", HFILL }},
+               NULL, 0, "Timeout in milliseconds", HFILL }},
 
        { &hf_smb_high_offset,
                { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
@@ -17551,11 +18280,11 @@ proto_register_smb(void)
 
        { &hf_smb_data_offset,
                { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
-               NULL, 0, "Data Offset", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_dcm,
                { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
-               NULL, 0, "Data Compaction Mode", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_request_mask,
                { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
@@ -17591,18 +18320,18 @@ proto_register_smb(void)
 
        { &hf_smb_resume_key_len,
                { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
-               NULL, 0, "Resume Key length", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_resume_find_id,
                { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
                NULL, 0, "Handle for Find operation", HFILL }},
 
        { &hf_smb_resume_server_cookie,
-               { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
+               { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_NONE,
                NULL, 0, "Cookie, must not be modified by the client", HFILL }},
 
        { &hf_smb_resume_client_cookie,
-               { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
+               { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_NONE,
                NULL, 0, "Cookie, must not be modified by the server", HFILL }},
 
        { &hf_smb_andxoffset,
@@ -17703,7 +18432,7 @@ proto_register_smb(void)
 
        { &hf_smb_vc_num,
                { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
-               NULL, 0, "VC Number", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_password_len,
                { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
@@ -17735,12 +18464,20 @@ proto_register_smb(void)
 
        { &hf_smb_fs,
                { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
-               NULL, 0, "Native File System", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_connect_flags_dtid,
                { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
                TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
 
+       { &hf_smb_connect_flags_ext_sig,
+               { "Extended Signature", "smb.connect.flags.extendedsig", FT_BOOLEAN, 16,
+               TFS(&tfs_extended_signature), 0x0004, "Extended signature?", HFILL }},
+
+       { &hf_smb_connect_flags_ext_resp,
+               { "Extended Response", "smb.connect.flags.extendedresp", FT_BOOLEAN, 16,
+               TFS(&tfs_extended_response), 0x0008, "Extended response?", HFILL }},
+
        { &hf_smb_connect_support_search,
                { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
                TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
@@ -17749,6 +18486,18 @@ proto_register_smb(void)
                { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
                TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
 
+       { &hf_smb_connect_support_csc_mask_vals,
+               { "CSC Mask", "smb.connect.support.cscmask", FT_UINT16, BASE_DEC,
+               VALS(connect_support_csc_mask_vals), 0x000c, "CSC mask?", HFILL }},
+
+       { &hf_smb_connect_support_uniquefilename,
+               { "Unique File Name", "smb.connect.support.uniqfilename", FT_BOOLEAN, 16,
+               TFS(&tfs_connect_support_uniquefilename), 0x0010, "Unique file name supported?", HFILL }},
+
+       { &hf_smb_connect_support_extended_signature,
+               { "Extended Signatures", "smb.connect.support.extendedsig", FT_BOOLEAN, 16,
+               TFS(&tfs_connect_support_extended_signature), 0x0020, "Extended signatures?", HFILL }},
+
        { &hf_smb_max_setup_count,
                { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
                NULL, 0, "Maximum number of setup words to return", HFILL }},
@@ -17799,11 +18548,11 @@ proto_register_smb(void)
 
        { &hf_smb_data_disp16,
                { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
-               NULL, 0, "Data Displacement", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_data_offset16,
                { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
-               NULL, 0, "Data Offset", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_data_count32,
                { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
@@ -17811,11 +18560,11 @@ proto_register_smb(void)
 
        { &hf_smb_data_disp32,
                { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
-               NULL, 0, "Data Displacement", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_data_offset32,
                { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
-               NULL, 0, "Data Offset", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_setup_count,
                { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
@@ -17907,23 +18656,23 @@ proto_register_smb(void)
 
        { &hf_smb_ea_flags,
                { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
-               NULL, 0, "EA Flags", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ea_name_length,
                { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
-               NULL, 0, "EA Name Length", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ea_data_length,
                { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
-               NULL, 0, "EA Data Length", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ea_name,
                { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
-               NULL, 0, "EA Name", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ea_data,
                { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
-               NULL, 0, "EA Data", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_file_name_len,
                { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
@@ -18060,7 +18809,7 @@ proto_register_smb(void)
 
        { &hf_smb_nt_create_options_sequential_only,
                { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
+               TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will access to this file only be sequential?", HFILL }},
 
        { &hf_smb_nt_create_options_no_intermediate_buffering,
                { "Intermediate Buffering", "smb.nt.create_options.intermediate_buffering", FT_BOOLEAN, 32,
@@ -18139,7 +18888,7 @@ proto_register_smb(void)
 
        { &hf_smb_nt_share_access_delete,
                { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, "", HFILL }},
+               TFS(&tfs_nt_share_access_delete), SHARE_ACCESS_DELETE, NULL, HFILL }},
 
        { &hf_smb_file_eattr_read_only,
                { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
@@ -18207,23 +18956,23 @@ proto_register_smb(void)
 
        { &hf_smb_nt_qsd_owner,
                { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
+               TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security information being queried?", HFILL }},
 
        { &hf_smb_nt_qsd_group,
                { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
+               TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security information being queried?", HFILL }},
 
        { &hf_smb_nt_qsd_dacl,
                { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
+               TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security information being queried?", HFILL }},
 
        { &hf_smb_nt_qsd_sacl,
                { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
+               TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security information being queried?", HFILL }},
 
        { &hf_smb_extended_attributes,
-               { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
-               NULL, 0, "Extended Attributes", HFILL }},
+               { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_NONE,
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_oplock_level,
                { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
@@ -18235,7 +18984,7 @@ proto_register_smb(void)
 
        { &hf_smb_file_id,
                { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
-               NULL, 0, "Server unique file ID", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ea_error_offset,
                { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
@@ -18251,7 +19000,7 @@ proto_register_smb(void)
 
        { &hf_smb_root_dir_handle,
                { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
-               NULL, 0, "Root directory handle", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_target_name_len,
                { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
@@ -18274,7 +19023,7 @@ proto_register_smb(void)
                NULL, 0, "Offset to next entry", HFILL }},
 
        { &hf_smb_change_time,
-               { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Change", "smb.change.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                NULL, 0, "Last Change Time", HFILL }},
 
        { &hf_smb_setup_len,
@@ -18294,7 +19043,7 @@ proto_register_smb(void)
                NULL, 0, "Index of entry after last returned", HFILL }},
 
        { &hf_smb_print_queue_date,
-               { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
+               { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
                NULL, 0, "Date when this entry was queued", HFILL }},
 
        { &hf_smb_print_queue_dos_date,
@@ -18375,7 +19124,7 @@ proto_register_smb(void)
 
        { &hf_smb_search_pattern,
                { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
-               NULL, 0, "Search Pattern", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_ff2_backup,
                { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
@@ -18425,7 +19174,7 @@ proto_register_smb(void)
 
        { &hf_smb_resume,
                { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
-               NULL, 0, "Resume Key", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_max_referral_level,
                { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
@@ -18531,9 +19280,13 @@ proto_register_smb(void)
                { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
                VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
 
-       { &hf_smb_dfs_referral_flags_strip,
-               { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
-               TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
+       { &hf_smb_dfs_referral_flags_name_list_referral,
+               { "NameListReferral", "smb.dfs.referral.flags.name_list_referral", FT_BOOLEAN, 16,
+               TFS(&tfs_dfs_referral_flags_name_list_referral), REFENT_FLAGS_NAME_LIST_REFERRAL, "Is a domain/DC referral response?", HFILL }},
+
+       { &hf_smb_dfs_referral_flags_target_set_boundary,
+               { "TargetSetBoundary", "smb.dfs.referral.flags.target_set_boundary", FT_BOOLEAN, 16,
+               TFS(&tfs_dfs_referral_flags_target_set_boundary), REFENT_FLAGS_TARGET_SET_BOUNDARY, "Is this a first target in the target set?", HFILL }},
 
        { &hf_smb_dfs_referral_node_offset,
                { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
@@ -18544,11 +19297,11 @@ proto_register_smb(void)
                NULL, 0, "Name of entity to visit next", HFILL }},
 
        { &hf_smb_dfs_referral_proximity,
-               { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
+               { "Proximity", "smb.dfs.referral.proximity", FT_UINT32, BASE_DEC,
                NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
 
        { &hf_smb_dfs_referral_ttl,
-               { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
+               { "TTL", "smb.dfs.referral.ttl", FT_UINT32, BASE_DEC,
                NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
 
        { &hf_smb_dfs_referral_path_offset,
@@ -18567,6 +19320,30 @@ proto_register_smb(void)
                { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
                NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
 
+       { &hf_smb_dfs_referral_domain_offset,
+               { "Domain Offset", "smb.dfs.referral.domain_offset", FT_UINT16, BASE_DEC,
+               NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
+
+       { &hf_smb_dfs_referral_number_of_expnames,
+               { "Number of Expanded Names", "smb.dfs.referral.number_of_expnames", FT_UINT16, BASE_DEC,
+               NULL, 0, NULL, HFILL }},
+
+       { &hf_smb_dfs_referral_expnames_offset,
+               { "Expanded Names Offset", "smb.dfs.referral.expnames_offset", FT_UINT16, BASE_DEC,
+               NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
+
+       { &hf_smb_dfs_referral_domain_name,
+               { "Domain Name", "smb.dfs.referral.domain_name", FT_STRING, BASE_NONE,
+               NULL, 0, "Dfs referral domain name", HFILL }},
+
+       { &hf_smb_dfs_referral_expname,
+               { "Expanded Name", "smb.dfs.referral.expname", FT_STRING, BASE_NONE,
+               NULL, 0, "Dfs expanded name", HFILL }},
+
+       { &hf_smb_dfs_referral_server_guid,
+               { "Server GUID", "smb.dfs.referral.server_guid", FT_BYTES, BASE_NONE,
+               NULL, 0, "Globally unique identifier for this server", HFILL }},
+
        { &hf_smb_end_of_search,
                { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
                NULL, 0, "Was last entry returned?", HFILL }},
@@ -18589,7 +19366,7 @@ proto_register_smb(void)
 
        { &hf_smb_file_index,
                { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
-               NULL, 0, "File index", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_short_file_name,
                { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
@@ -18613,7 +19390,7 @@ proto_register_smb(void)
 
        { &hf_smb_fs_sector,
                { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
-               NULL, 0, "Bytes per sector", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_avail_units,
                { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
@@ -18621,14 +19398,14 @@ proto_register_smb(void)
 
        { &hf_smb_volume_serial_num,
                { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
-               NULL, 0, "Volume serial number", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_volume_label_len,
                { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
                NULL, 0, "Length of volume label", HFILL }},
 
        { &hf_smb_volume_label,
-               { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
+               { "Label", "smb.volume.label", FT_STRING, BASE_NONE,
                NULL, 0, "Volume label", HFILL }},
 
        { &hf_smb_free_alloc_units64,
@@ -18644,8 +19421,8 @@ proto_register_smb(void)
                NULL, 0, "Number of actual free allocation units", HFILL }},
 
        { &hf_smb_soft_quota_limit,
-               { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
-               NULL, 0, "Soft Quota treshold", HFILL }},
+               { "(Soft) Quota Threshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
+               NULL, 0, "Soft Quota threshold", HFILL }},
 
        { &hf_smb_hard_quota_limit,
                { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
@@ -18664,7 +19441,7 @@ proto_register_smb(void)
                NULL, 0, "Length of filesystem name in bytes", HFILL }},
 
        { &hf_smb_fs_name,
-               { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
+               { "FS Name", "smb.fs_name", FT_STRING, BASE_NONE,
                NULL, 0, "Name of filesystem", HFILL }},
 
        { &hf_smb_device_char_removable,
@@ -18799,6 +19576,10 @@ proto_register_smb(void)
                { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
                        "Defragmentation error due to illegal fragments", HFILL }},
 
+       { &hf_smb_reassembled_length,
+               { "Reassembled SMB length", "smb.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
+                       "The total length of the reassembled payload", HFILL }},
+
        { &hf_smb_opened_in,
                { "Opened in", "smb.fid.opened_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
                        "The frame this fid was opened", HFILL }},
@@ -18817,11 +19598,11 @@ proto_register_smb(void)
 
        { &hf_smb_segment,
                { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
-                       "SMB Segment", HFILL }},
+                       NULL, HFILL }},
 
        { &hf_smb_segments,
                { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
-                       "SMB Segments", HFILL }},
+                       NULL, HFILL }},
 
        { &hf_smb_unix_major_version,
          { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
@@ -18833,247 +19614,247 @@ proto_register_smb(void)
 
        { &hf_smb_unix_capability_fcntl,
          { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000001, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
 
        { &hf_smb_unix_capability_posix_acl,
          { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000002, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_read_data,
          { "Read Data", "smb.file.accessmask.read_data", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000001, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_write_data,
          { "Write Data", "smb.file.accessmask.write_data", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000002, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_append_data,
          { "Append Data", "smb.file.accessmask.append_data", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000004, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_read_ea,
          { "Read EA", "smb.file.accessmask.read_ea", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000008, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_write_ea,
          { "Write EA", "smb.file.accessmask.write_ea", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000010, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_execute,
          { "Execute", "smb.file.accessmask.execute", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000020, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_read_attribute,
          { "Read Attribute", "smb.file.accessmask.read_attribute", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000080, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
 
        { &hf_smb_file_access_mask_write_attribute,
          { "Write Attribute", "smb.file.accessmask.write_attribute", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000100, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_list,
          { "List", "smb.dir.accessmask.list", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000001, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000001, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_add_file,
          { "Add File", "smb.dir.accessmask.add_file", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000002, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000002, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_add_subdir,
          { "Add Subdir", "smb.dir.accessmask.add_subdir", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000004, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000004, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_read_ea,
          { "Read EA", "smb.dir.accessmask.read_ea", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000008, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000008, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_write_ea,
          { "Write EA", "smb.dir.accessmask.write_ea", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000010, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000010, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_traverse,
          { "Traverse", "smb.dir.accessmask.traverse", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000020, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000020, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_delete_child,
          { "Delete Child", "smb.dir.accessmask.delete_child", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000040, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000040, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_read_attribute,
          { "Read Attribute", "smb.dir.accessmask.read_attribute", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000080, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000080, NULL, HFILL }},
 
        { &hf_smb_dir_access_mask_write_attribute,
          { "Write Attribute", "smb.dir.accessmask.write_attribute", FT_BOOLEAN, 32,
-               TFS(&flags_set_truth), 0x00000100, "", HFILL }},
+               TFS(&tfs_set_notset), 0x00000100, NULL, HFILL }},
 
        { &hf_smb_unix_file_size,
          { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_num_bytes,
          { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
            NULL, 0, "Number of bytes used to store the file", HFILL }},
 
        { &hf_smb_unix_file_last_status,
-         { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
-           NULL, 0, "", HFILL }},
+         { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_last_access,
-         { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
-           NULL, 0, "", HFILL }},
+         { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_last_change,
-         { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
-           NULL, 0, "", HFILL }},
+         { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_uid,
          { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_gid,
          { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_type,
          { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
-           VALS(unix_file_type_vals), 0, "", HFILL }},
+           VALS(unix_file_type_vals), 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_dev_major,
          { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_dev_minor,
          { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_unique_id,
          { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_permissions,
          { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_nlinks,
          { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_file_link_dest,
          { "Link destination", "smb.unix.file.link_dest", FT_STRING,
-           BASE_NONE, NULL, 0, "", HFILL }},
+           BASE_NONE, NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_find_file_nextoffset,
          { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
        { &hf_smb_unix_find_file_resumekey,
          { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
-           NULL, 0, "", HFILL }},
+           NULL, 0, NULL, HFILL }},
 
         { &hf_smb_network_unknown,
-          { "Unknown field", "smb.unknown", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+          { "Unknown field", "smb.unknown_field", FT_UINT32, BASE_HEX,
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_create_flags,
           { "Create Flags", "smb.create_flags", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_create_options,
           { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_share_access,
           { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_access_mask,
           { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_mode,
           { "Mode", "smb.mode", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_attribute,
           { "Attribute", "smb.attribute", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
         { &hf_smb_reparse_tag,
           { "Reparse Tag", "smb.reparse_tag", FT_UINT32, BASE_HEX,
-            NULL, 0, "", HFILL }},
+            NULL, 0, NULL, HFILL }},
 
        { &hf_smb_disposition_delete_on_close,
          { "Delete on close", "smb.disposition.delete_on_close", FT_BOOLEAN, 8,
-               TFS(&tfs_disposition_delete_on_close), 0x01, "", HFILL }},
+               TFS(&tfs_disposition_delete_on_close), 0x01, NULL, HFILL }},
 
        { &hf_smb_pipe_info_flag,
          { "Pipe Info", "smb.pipe_info_flag", FT_BOOLEAN, 8,
-               TFS(&tfs_pipe_info_flag), 0x01, "", HFILL }},
+               TFS(&tfs_pipe_info_flag), 0x01, NULL, HFILL }},
 
        { &hf_smb_logged_in,
-         { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_DEC,
-               NULL, 0, "", HFILL }},
+         { "Logged In", "smb.logged_in", FT_FRAMENUM, BASE_NONE,
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_logged_out,
-         { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_DEC,
-               NULL, 0, "", HFILL }},
+         { "Logged Out", "smb.logged_out", FT_FRAMENUM, BASE_NONE,
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_file_rw_offset,
-         { "File Offset", "smb.file.rw.offset", FT_UINT32, BASE_DEC,
-               NULL, 0, "", HFILL }},
+         { "File Offset", "smb.file.rw.offset", FT_UINT64, BASE_DEC,
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_file_rw_length,
          { "File RW Length", "smb.file.rw.length", FT_UINT32, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_acl_version,
          { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_num_file_aces,
          { "Number of file ACEs", "smb.posix_acl.num_file_aces", FT_UINT16, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_num_def_aces,
          { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_ace_type,
          { "ACE Type", "smb.posix_acl.ace_type", FT_UINT8, BASE_DEC,
-               VALS(&ace_type_vals), 0, "", HFILL }},
+               VALS(ace_type_vals), 0, NULL, HFILL }},
 
        { &hf_smb_posix_ace_flags,
          { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_ace_perm_read,
           {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
-               NULL, 0x04, "", HFILL}},
+               NULL, 0x04, NULL, HFILL}},
 
        { &hf_smb_posix_ace_perm_write,
           {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
-               NULL, 0x02, "", HFILL}},
+               NULL, 0x02, NULL, HFILL}},
 
        { &hf_smb_posix_ace_perm_execute,
           {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
-               NULL, 0x01, "", HFILL}},
+               NULL, 0x01, NULL, HFILL}},
 
        { &hf_smb_posix_ace_perm_owner_uid,
          { "Owner UID", "smb.posix_acl.ace_perms.owner_uid", FT_UINT32, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_ace_perm_owner_gid,
          { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_ace_perm_uid,
          { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        { &hf_smb_posix_ace_perm_gid,
          { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
-               NULL, 0, "", HFILL }},
+               NULL, 0, NULL, HFILL }},
 
        };
 
@@ -19141,6 +19922,7 @@ proto_register_smb(void)
                &ett_smb_dfs_referrals,
                &ett_smb_dfs_referral,
                &ett_smb_dfs_referral_flags,
+               &ett_smb_dfs_referral_expnames,
                &ett_smb_get_dfs_flags,
                &ett_smb_ff2_data,
                &ett_smb_device_characteristics,
@@ -19180,9 +19962,18 @@ proto_register_smb(void)
                "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
                &sid_name_snooping);
 
+       /* For display of SIDs and RIDs in Hex option */
+       prefs_register_bool_preference(smb_module, "sid_display_hex",
+               "Display SIDs in Hex",
+               "Whether the dissector should display SIDs and RIDs in hexadecimal rather than decimal",
+               &sid_display_hex);
+
        register_init_routine(smb_trans_reassembly_init);
        smb_tap = register_tap("smb");
 
+        /* Register the tap for the "Export Object" function */
+        smb_eo_tap = register_tap("smb_eo"); /* SMB Export Object tap */
+
        register_dissector("smb", dissect_smb, proto_smb);
 }
 
@@ -19197,10 +19988,10 @@ proto_reg_handoff_smb(void)
        heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
        heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
        heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
-       smb_handle = create_dissector_handle(dissect_smb, proto_smb);
+
+       smb_handle = find_dissector("smb");
        dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
        dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
-       dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
-           smb_handle);
+       dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER, smb_handle);
        dissector_add("spp.socket", IDP_SOCKET_SMB, smb_handle);
 }