Fix various typos and spelling errors.
[obnox/wireshark/wip.git] / epan / dissectors / packet-smb.c
index 9fde09f9aefa6be0ffc718b9684c558f2fe5f671..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;
@@ -117,6 +121,10 @@ static int hf_smb_nt_status = -1;
 static int hf_smb_error_class = -1;
 static int hf_smb_error_code = -1;
 static int hf_smb_reserved = -1;
+static int hf_smb_create_flags = -1;
+static int hf_smb_create_options = -1;
+static int hf_smb_share_access = -1;
+static int hf_smb_access_mask = -1;
 static int hf_smb_flags_lock = -1;
 static int hf_smb_flags_receive_buffer = -1;
 static int hf_smb_flags_caseless = -1;
@@ -357,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;
@@ -378,10 +391,8 @@ static int hf_smb_data_count32 = -1;
 static int hf_smb_data_offset32 = -1;
 static int hf_smb_setup_count = -1;
 static int hf_smb_nt_trans_subcmd = -1;
-static int hf_smb_nt_ioctl_function_code = -1;
 static int hf_smb_nt_ioctl_isfsctl = -1;
 static int hf_smb_nt_ioctl_flags_root_handle = -1;
-static int hf_smb_nt_ioctl_data = -1;
 #ifdef SMB_UNUSED_HANDLES
 static int hf_smb_nt_security_information = -1;
 #endif
@@ -557,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;
@@ -566,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;
@@ -627,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;
@@ -654,10 +673,27 @@ static int hf_smb_pipe_info_flag = -1;
 static int hf_smb_mode = -1;
 static int hf_smb_attribute = -1;
 static int hf_smb_reparse_tag = -1;
+static int hf_smb_logged_in = -1;
+static int hf_smb_logged_out = -1;
+static int hf_smb_file_rw_offset = -1;
+static int hf_smb_file_rw_length = -1;
+static int hf_smb_posix_acl_version = -1;
+static int hf_smb_posix_num_file_aces = -1;
+static int hf_smb_posix_num_def_aces = -1;
+static int hf_smb_posix_ace_type = -1;
+static int hf_smb_posix_ace_flags = -1;
+static int hf_smb_posix_ace_perm_read = -1;
+static int hf_smb_posix_ace_perm_write = -1;
+static int hf_smb_posix_ace_perm_execute = -1;
+static int hf_smb_posix_ace_perm_owner_uid = -1;
+static int hf_smb_posix_ace_perm_owner_gid = -1;
+static int hf_smb_posix_ace_perm_uid = -1;
+static int hf_smb_posix_ace_perm_gid = -1;
 
 static gint ett_smb = -1;
 static gint ett_smb_fid = -1;
 static gint ett_smb_tid = -1;
+static gint ett_smb_uid = -1;
 static gint ett_smb_hdr = -1;
 static gint ett_smb_command = -1;
 static gint ett_smb_fileattributes = -1;
@@ -718,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;
@@ -729,11 +766,14 @@ static gint ett_smb_secblob = -1;
 static gint ett_smb_unicode_password = -1;
 static gint ett_smb_ea = -1;
 static gint ett_smb_unix_capabilities = -1;
+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,
@@ -747,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);
@@ -847,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 */
@@ -1002,6 +1050,13 @@ static GSList *conv_tables = NULL;
 
 
 
+typedef struct _smb_uid_t {
+       char *domain;
+       char *account;
+       int logged_in;
+       int logged_out;
+} smb_uid_t;
+
 static void
 smb_file_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 mask)
 {
@@ -1065,6 +1120,22 @@ static const value_string buffer_format_vals[] = {
        {0,     NULL}
 };
 
+#define POSIX_ACE_TYPE_USER_OBJ                0x01
+#define POSIX_ACE_TYPE_USER            0x02
+#define POSIX_ACE_TYPE_GROUP_OBJ       0x04
+#define POSIX_ACE_TYPE_GROUP           0x08
+#define POSIX_ACE_TYPE_MASK            0x10
+#define POSIX_ACE_TYPE_OTHER           0x20
+static const value_string ace_type_vals[] = {
+       {POSIX_ACE_TYPE_USER_OBJ,       "User Obj"},
+       {POSIX_ACE_TYPE_USER,           "User"},
+       {POSIX_ACE_TYPE_GROUP_OBJ,      "Group Obj"},
+       {POSIX_ACE_TYPE_GROUP,          "Group"},
+       {POSIX_ACE_TYPE_MASK,           "Mask"},
+       {POSIX_ACE_TYPE_OTHER,          "Other"},
+       {0,     NULL}
+};
+
 /*
  * UTIME - this is *almost* like a UNIX time stamp, except that it's
  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
@@ -1173,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;
@@ -1185,12 +1255,10 @@ TimeZoneFaster(time_t t)
 
                        /* no entry will cover more than 6 months */
                        low = t - MAX_DST_WIDTH/2;
-                       if (t < low)
-                               low = TIME_T_MIN;
+                       /* XXX - what if t < MAX_DST_WIDTH/2? */
 
                        high = t + MAX_DST_WIDTH/2;
-                       if (high < t)
-                               high = TIME_T_MAX;
+                       /* XXX - what if this overflows? */
 
                        /*
                         * Widen the new entry using two bisection searches.
@@ -1417,8 +1485,8 @@ static int
 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *type)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -1426,18 +1494,18 @@ dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, const char *t
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "%s Access: 0x%04x", type, mask);
                tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_access_writetru,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_access_caching,
-               tvb, offset, 2, mask);
-       proto_tree_add_uint(tree, hf_smb_access_locality,
-               tvb, offset, 2, mask);
-       proto_tree_add_uint(tree, hf_smb_access_sharing,
-               tvb, offset, 2, mask);
-       proto_tree_add_uint(tree, hf_smb_access_mode,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_access_writetru,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_access_caching,
+                       tvb, offset, 2, mask);
+               proto_tree_add_uint(tree, hf_smb_access_locality,
+                       tvb, offset, 2, mask);
+               proto_tree_add_uint(tree, hf_smb_access_sharing,
+                       tvb, offset, 2, mask);
+               proto_tree_add_uint(tree, hf_smb_access_mode,
+                       tvb, offset, 2, mask);
+       }
 
        offset += 2;
 
@@ -1522,130 +1590,114 @@ 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 = NULL;
-       proto_tree *tree = NULL;
-
-       if (bytes != 2 && bytes != 4) {
-               THROW(ReportedBoundsError);
-       }
+       proto_item *item;
+       proto_tree *tree;
 
-       /*
-        * 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_archive_16bit,
+                               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
+                               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
+                               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
+                               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
+                               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
+                               tvb, offset, 2, mask);
        }
-       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);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
-               tvb, offset, bytes, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
-               tvb, offset, bytes, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
-               tvb, offset, bytes, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
-               tvb, offset, bytes, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
-               tvb, offset, bytes, 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(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+dissect_file_ext_attr_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+    int len, guint32 mask)
 {
-       guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-
-       mask = tvb_get_letohl(tvb, offset);
+       proto_item *item;
+       proto_tree *tree;
 
        if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 4,
+               item = proto_tree_add_text(parent_tree, tvb, offset, len,
                        "File Attributes: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_file_attributes);
-       }
 
-       /*
-        * XXX - Network Monitor disagrees on some of the
-        * bits, e.g. the bits above temporary are "atomic write"
-        * and "transaction write", and it says nothing about the
-        * bits above that.
-        *
-        * Does the Win32 API documentation, or the NT Native API book,
-        * suggest anything?
-        */
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
-               tvb, offset, 4, mask);
+               /*
+                * XXX - Network Monitor disagrees on some of the
+                * bits, e.g. the bits above temporary are "atomic write"
+                * and "transaction write", and it says nothing about the
+                * bits above that.
+                *
+                * Does the Win32 API documentation, or the NT Native API book,
+                * suggest anything?
+                */
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
+                       tvb, offset, len, mask);
+       }
+
+       offset += len;
 
-       offset += 4;
+       return offset;
+}
+
+/* 3.11 */
+int
+dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint32 mask;
+
+       mask = tvb_get_letohl(tvb, offset);
+
+       offset = dissect_file_ext_attr_bits(tvb, parent_tree, offset, 4, mask);
 
        return offset;
 }
@@ -1654,8 +1706,8 @@ static int
 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_guint8(tvb, offset);
 
@@ -1663,19 +1715,20 @@ dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int off
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
                        "File Attributes: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_file_attributes);
+
+               proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
+                       tvb, offset, 1, mask);
        }
-       proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
-               tvb, offset, 1, mask);
 
        offset += 1;
 
@@ -1707,12 +1760,16 @@ 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)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -1720,20 +1777,20 @@ dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Search Attributes: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_search);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
+                       tvb, offset, 2, mask);
+       }
 
        offset += 2;
        return offset;
@@ -1750,8 +1807,8 @@ static int
 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohl(tvb, offset);
 
@@ -1897,54 +1954,54 @@ static int
 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohl(tvb, offset);
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_capabilities);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
-               tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
+                       tvb, offset, 4, mask);
+       }
 
        return mask;
 }
@@ -1964,18 +2021,18 @@ static int
 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_rawmode);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
+       }
 
        offset += 2;
 
@@ -2037,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_)
 {
@@ -2044,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;
 
@@ -2056,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;
@@ -2084,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;
@@ -2103,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);
 
@@ -2110,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);
@@ -2129,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);
@@ -2332,7 +2425,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                        /* security blob */
                        /* If it runs past the end of the captured data, don't
                         * try to put all of it into the protocol tree as the
-                        * raw security blob; we might get an exception on 
+                        * raw security blob; we might get an exception on
                         * short frames and then we will not see anything at all
                         * of the security blob.
                         */
@@ -2344,11 +2437,11 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                                tree, hf_smb_security_blob,
                                tvb, offset, sbloblen, TRUE);
 
-                       /* 
-                        * If Extended security and BCC == 16, then raw 
+                       /*
+                        * If Extended security and BCC == 16, then raw
                         * NTLMSSP is in use. We need to save this info
                         */
+
                        if(bc){
                                tvbuff_t *gssapi_tvb;
                                proto_tree *gssapi_tree;
@@ -2376,11 +2469,11 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
                                COUNT_BYTES(bc);
                        }
-                       else { 
+                       else {
 
                          /*
                           * There is no blob. We just have to make sure
-                          * that subsequent routines know to call the 
+                          * that subsequent routines know to call the
                           * right things ...
                           */
 
@@ -2399,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;
@@ -2421,6 +2514,12 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        /* dir name */
        dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
                FALSE, FALSE, &bc);
+
+       if((!pinfo->fd->flags.visited) && si->sip){
+               si->sip->extra_info_type=SMB_EI_FILENAME;
+               si->sip->extra_info=se_strdup(dn);
+       }
+
        if (dn == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
@@ -2442,6 +2541,45 @@ dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offse
 {
        guint8 wc;
        guint16 bc;
+       smb_info_t *si = pinfo->private_data;
+       proto_item *item=NULL;
+
+       DISSECTOR_ASSERT(si);
+
+       if(si->sip && si->sip->extra_info_type==SMB_EI_FILENAME){
+               item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, si->sip->extra_info);
+               PROTO_ITEM_SET_GENERATED(item);
+       }
+
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_rename_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint8 wc;
+       guint16 bc;
+       smb_info_t *si = pinfo->private_data;
+       proto_item *item=NULL;
+
+       DISSECTOR_ASSERT(si);
+
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RENAMEDATA){
+               smb_rename_saved_info_t *rni=si->sip->extra_info;
+
+               item=proto_tree_add_string(tree, hf_smb_old_file_name, tvb, 0, 0, rni->old_name);
+               PROTO_ITEM_SET_GENERATED(item);
+               item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, rni->new_name);
+               PROTO_ITEM_SET_GENERATED(item);
+       }
+
 
        WORD_COUNT;
 
@@ -2574,13 +2712,53 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        return offset;
 }
 
+static int
+dissect_smb_uid(tvbuff_t *tvb, proto_tree *parent_tree, int offset, smb_info_t *si)
+{
+       proto_item *item, *subitem;
+       proto_tree *tree;
+       smb_uid_t *smb_uid=NULL;
+
+       item=proto_tree_add_uint(parent_tree, hf_smb_uid, tvb, offset, 2, si->uid);
+       tree=proto_item_add_subtree(item, ett_smb_uid);
+
+       smb_uid=se_tree_lookup32(si->ct->uid_tree, si->uid);
+       if(smb_uid){
+               if(smb_uid->domain && smb_uid->account)
+                       proto_item_append_text(item, "  (");
+               if(smb_uid->domain){
+                       proto_item_append_text(item, "%s", smb_uid->domain);
+                       subitem=proto_tree_add_string(tree, hf_smb_primary_domain, tvb, 0, 0, smb_uid->domain);
+                       PROTO_ITEM_SET_GENERATED(subitem);
+               }
+               if(smb_uid->account){
+                       proto_item_append_text(item, "\\%s", smb_uid->account);
+                       subitem=proto_tree_add_string(tree, hf_smb_account, tvb, 0, 0, smb_uid->account);
+                       PROTO_ITEM_SET_GENERATED(subitem);
+               }
+               if(smb_uid->domain && smb_uid->account)
+                       proto_item_append_text(item, ")");
+               if(smb_uid->logged_in>0){
+                       subitem=proto_tree_add_uint(tree, hf_smb_logged_in, tvb, 0, 0, smb_uid->logged_in);
+                       PROTO_ITEM_SET_GENERATED(subitem);
+               }
+               if(smb_uid->logged_out>0){
+                       subitem=proto_tree_add_uint(tree, hf_smb_logged_out, tvb, 0, 0, smb_uid->logged_out);
+                       PROTO_ITEM_SET_GENERATED(subitem);
+               }
+       }
+       offset += 2;
+
+       return offset;
+}
+
 static int
 dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 tid, gboolean is_created, gboolean is_closed)
 {
        smb_info_t *si = pinfo->private_data;
        proto_item *it;
        proto_tree *tr;
-       smb_fid_info_t *fid_info=NULL;
+       smb_tid_info_t *tid_info=NULL;
 
        DISSECTOR_ASSERT(si);
 
@@ -2590,42 +2768,44 @@ dissect_smb_tid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
        offset += 2;
 
        if((!pinfo->fd->flags.visited) && is_created){
-               fid_info=se_alloc(sizeof(smb_fid_info_t));
-               fid_info->opened_in=pinfo->fd->num;
-               fid_info->closed_in=0;
-               fid_info->type=SMB_FID_TYPE_UNKNOWN;
-               if(si->sip && (si->sip->extra_info_type==SMB_EI_FILENAME)){
-                       fid_info->filename=si->sip->extra_info;
+               tid_info=se_alloc(sizeof(smb_tid_info_t));
+               tid_info->opened_in=pinfo->fd->num;
+               tid_info->closed_in=0;
+               tid_info->type=SMB_FID_TYPE_UNKNOWN;
+               if(si->sip && (si->sip->extra_info_type==SMB_EI_TIDNAME)){
+                       tid_info->filename=si->sip->extra_info;
                } else {
-                       fid_info->filename=NULL;
+                       tid_info->filename=NULL;
                }
-               se_tree_insert32(si->ct->tid_tree, pinfo->fd->num, fid_info);
+               se_tree_insert32(si->ct->tid_tree, tid, tid_info);
        }
 
-       if(!fid_info){
-               fid_info=se_tree_lookup32_le(si->ct->tid_tree, pinfo->fd->num);
+       if(!tid_info){
+               tid_info=se_tree_lookup32_le(si->ct->tid_tree, tid);
        }
-       if(!fid_info){
+       if(!tid_info){
                return offset;
        }
 
        if((!pinfo->fd->flags.visited) && is_closed){
-               fid_info->closed_in=pinfo->fd->num;
+               tid_info->closed_in=pinfo->fd->num;
        }
 
-       if(fid_info->opened_in){
-               if(fid_info->filename){
-                       it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, fid_info->filename);
+       if(tid_info->opened_in){
+               if(tid_info->filename){
+                       proto_item_append_text(it, "  (%s)", tid_info->filename);
+
+                       it=proto_tree_add_string(tr, hf_smb_path, tvb, 0, 0, tid_info->filename);
                        PROTO_ITEM_SET_GENERATED(it);
                }
 
-               it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, fid_info->opened_in);
+               it=proto_tree_add_uint(tr, hf_smb_mapped_in, tvb, 0, 0, tid_info->opened_in);
                PROTO_ITEM_SET_GENERATED(it);
-       }               
-       if(fid_info->closed_in){
-               it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, fid_info->closed_in);
+       }
+       if(tid_info->closed_in){
+               it=proto_tree_add_uint(tr, hf_smb_unmapped_in, tvb, 0, 0, tid_info->closed_in);
                PROTO_ITEM_SET_GENERATED(it);
-       }               
+       }
 
 
        return offset;
@@ -2813,7 +2993,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        if (fn == NULL)
                goto endofcommand;
        proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
-               fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
+               fn_len, fn, "Old File Name: %s", format_text(fn, strlen(fn)));
        COUNT_BYTES(fn_len);
 
        if (check_col(pinfo->cinfo, COL_INFO)) {
@@ -2906,8 +3086,7 @@ dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        COUNT_BYTES(fn_len);
 
        if (check_col(pinfo->cinfo, COL_INFO)) {
-               col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s",
-                   format_text(fn, strlen(fn)));
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", format_text(fn, strlen(fn)));
        }
 
        END_OF_SMB
@@ -2998,62 +3177,362 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        return offset;
 }
 
-/* fids are scoped by tcp session */
-smb_fid_info_t *
-dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
-    int len, guint16 fid, gboolean is_created, gboolean is_closed)
-{
-       smb_info_t *si = pinfo->private_data;
-       proto_item *it;
-       proto_tree *tr;
-       smb_fid_info_t *fid_info=NULL;
-
-       DISSECTOR_ASSERT(si);
-
-       it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
-       tr=proto_item_add_subtree(it, ett_smb_fid);
-       if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
 
-       if((!pinfo->fd->flags.visited) && is_created){
-               fid_info=se_alloc(sizeof(smb_fid_info_t));
-               fid_info->opened_in=pinfo->fd->num;
-               fid_info->closed_in=0;
-               fid_info->type=SMB_FID_TYPE_UNKNOWN;
-               if(si->sip && (si->sip->extra_info_type==SMB_EI_FILENAME)){
-                       fid_info->filename=si->sip->extra_info;
-               } else {
-                       fid_info->filename=NULL;
-               }
 
-               se_tree_insert32(si->ct->fid_tree, pinfo->fd->num, fid_info);
-       }
+static int
+dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+    int len, guint32 mask)
+{
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
 
-       if(!fid_info){
-               fid_info=se_tree_lookup32_le(si->ct->fid_tree, pinfo->fd->num);
-       }
-       if(!fid_info){
-               return NULL;
-       }
+       if(parent_tree){
+               item = proto_tree_add_uint(parent_tree, hf_smb_create_flags, tvb, offset, len, mask);
 
-       if((!pinfo->fd->flags.visited) && is_closed){
-               fid_info->closed_in=pinfo->fd->num;
+               tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
+       }
+
+       /*
+        * XXX - it's 0x00000016 in at least one capture, but
+        * Network Monitor doesn't say what the 0x00000010 bit is.
+        * Does the Win32 API documentation, or NT Native API book,
+        * suggest anything?
+        *
+        * That is the extended response desired bit ... RJS, from Samba
+        * Well, maybe. Samba thinks it is, and uses it to encode
+        * OpLock granted as the high order bit of the Action field
+        * in the response. However, Windows does not do that. Or at least
+        * Win2K doesn't.
+        */
+       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
+                              tvb, offset, len, mask);
+       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
+               tvb, offset, len, mask);
+       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
+               tvb, offset, len, mask);
+       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
+               tvb, offset, len, mask);
+
+       offset += len;
+
+       return offset;
+}
+
+/* FIXME: need to call dissect_nt_access_mask() instead */
+static int
+dissect_smb_access_mask_bits(tvbuff_t *tvb, proto_tree *parent_tree,
+    int offset, int len, guint32 mask)
+{
+       proto_item *item;
+       proto_tree *tree;
+
+       if(parent_tree){
+               item = proto_tree_add_uint(parent_tree, hf_smb_access_mask, tvb, offset, len, mask);
+               tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
+
+               /*
+                * Some of these bits come from
+                *
+                *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
+                *
+                * and others come from the section on ZwOpenFile in "Windows(R)
+                * NT(R)/2000 Native API Reference".
+                */
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
+                       tvb, offset, len, mask);
+       }
+       offset += len;
+
+       return offset;
+}
+
+int
+dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint32 mask;
+
+       mask = tvb_get_letohl(tvb, offset);
+
+       offset = dissect_smb_access_mask_bits(tvb, parent_tree, offset, 4, mask);
+
+       return offset;
+}
+
+
+#define SHARE_ACCESS_DELETE    0x00000004
+#define SHARE_ACCESS_WRITE     0x00000002
+#define SHARE_ACCESS_READ      0x00000001
+
+static int
+dissect_nt_share_access_bits(tvbuff_t *tvb, proto_tree *parent_tree,
+    int offset, int len, guint32 mask)
+{
+       proto_item *item;
+       proto_tree *tree;
+
+       if(parent_tree){
+               item = proto_tree_add_uint(parent_tree, hf_smb_share_access, tvb, offset, len, mask);
+               tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
+
+               proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
+                       tvb, offset, len, mask);
+               if(mask&SHARE_ACCESS_DELETE){
+                       proto_item_append_text(item, " SHARE_DELETE");
+               }
+
+               proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
+                       tvb, offset, len, mask);
+               if(mask&SHARE_ACCESS_WRITE){
+                       proto_item_append_text(item, " SHARE_WRITE");
+               }
+
+               proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
+                       tvb, offset, len, mask);
+               if(mask&SHARE_ACCESS_READ){
+                       proto_item_append_text(item, " SHARE_READ");
+               }
+       }
+
+       offset += len;
+
+       return offset;
+}
+
+int
+dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint32 mask;
+
+       mask = tvb_get_letohl(tvb, offset);
+
+       offset = dissect_nt_share_access_bits(tvb, parent_tree, offset, 4, mask);
+
+       return offset;
+}
+
+
+static int
+dissect_nt_create_options_bits(tvbuff_t *tvb, proto_tree *parent_tree,
+    int offset, int len, guint32 mask)
+{
+       proto_item *item;
+       proto_tree *tree;
+
+       if(parent_tree){
+               item = proto_tree_add_uint(parent_tree, hf_smb_create_options, tvb, offset, len, mask);
+               tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
+
+               /*
+                * From
+                *
+                *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
+                */
+                proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
+                       tvb, offset, len, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
+                       tvb, offset, len, mask);
+       }
+       offset += len;
+
+       return offset;
+}
+
+int
+dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint32 mask;
+
+       mask = tvb_get_letohl(tvb, offset);
+
+       offset = dissect_nt_create_options_bits(tvb, parent_tree, offset, 4, mask);
+
+       return offset;
+}
+
+
+/* fids are scoped by tcp session */
+smb_fid_info_t *
+dissect_smb_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+    int len, guint16 fid, gboolean is_created, gboolean is_closed, gboolean is_generated)
+{
+       smb_info_t *si = pinfo->private_data;
+       smb_saved_info_t *sip = si->sip;
+       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);
+
+       it=proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
+       if(is_generated){
+               PROTO_ITEM_SET_GENERATED(it);
+       }
+       tr=proto_item_add_subtree(it, ett_smb_fid);
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
+
+       if((!pinfo->fd->flags.visited) && is_created){
+               fid_info=se_alloc(sizeof(smb_fid_info_t));
+               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;
+               }
+                /* 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){
+                /* 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;
+       }
+
+       /* Store the fid in the transaction structure and remember if
+          it was in the request or in the reply we saw it
+        */
+       if(sip && (!is_generated) && (!pinfo->fd->flags.visited)) {
+               sip->fid=fid;
+               if(si->request){
+                       sip->fid_seen_in_request=TRUE;
+               } else {
+                       sip->fid_seen_in_request=FALSE;
+               }
+       }
+
+       if((!pinfo->fd->flags.visited) && is_closed){
+               fid_info->closed_in=pinfo->fd->num;
+       }
+
+       if(fid_info->opened_in){
+               it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
+               PROTO_ITEM_SET_GENERATED(it);
+       }
+
+       if(fid_info->closed_in){
+               it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
+               PROTO_ITEM_SET_GENERATED(it);
+       }
+
+
+       if(fid_info->opened_in){
+               if(fid_info->fsi && fid_info->fsi->filename){
+                       it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->fsi->filename);
+                       PROTO_ITEM_SET_GENERATED(it);
+                       proto_item_append_text(tr, " (%s)", fid_info->fsi->filename);
+                       dissect_nt_create_bits(tvb, tr, 0, 0, fid_info->fsi->create_flags);
+                       dissect_smb_access_mask_bits(tvb, tr, 0, 0, fid_info->fsi->access_mask);
+                       dissect_file_ext_attr_bits(tvb, tr, 0, 0, fid_info->fsi->file_attributes);
+                       dissect_nt_share_access_bits(tvb, tr, 0, 0, fid_info->fsi->share_access);
+                       dissect_nt_create_options_bits(tvb, tr, 0, 0, fid_info->fsi->create_options);
+                       it=proto_tree_add_uint(tr, hf_smb_nt_create_disposition, tvb, 0, 0, fid_info->fsi->create_disposition);
+                       PROTO_ITEM_SET_GENERATED(it);
+               }
        }
 
-       if(fid_info->opened_in){
-               if(fid_info->filename){
-                       it=proto_tree_add_string(tr, hf_smb_file_name, tvb, 0, 0, fid_info->filename);
-                       PROTO_ITEM_SET_GENERATED(it);
-               }
-
-               it=proto_tree_add_uint(tr, hf_smb_opened_in, tvb, 0, 0, fid_info->opened_in);
-               PROTO_ITEM_SET_GENERATED(it);
-       }               
-       if(fid_info->closed_in){
-               it=proto_tree_add_uint(tr, hf_smb_closed_in, tvb, 0, 0, fid_info->closed_in);
-               PROTO_ITEM_SET_GENERATED(it);
-       }               
-
        return fid_info;
 }
 
@@ -3068,11 +3547,11 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
        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);
@@ -3102,7 +3581,7 @@ dissect_query_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3123,7 +3602,7 @@ dissect_close_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3144,7 +3623,7 @@ dissect_open_print_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3165,7 +3644,7 @@ dissect_create_new_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3186,7 +3665,7 @@ dissect_flush_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3207,7 +3686,7 @@ dissect_create_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3231,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);
@@ -3272,7 +3751,7 @@ dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
        offset += 2;
 
        /* last write time */
@@ -3311,6 +3790,12 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* file name */
        fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
+
+       if((!pinfo->fd->flags.visited) && si->sip){
+               si->sip->extra_info_type=SMB_EI_FILENAME;
+               si->sip->extra_info=se_strdup(fn);
+       }
+
        if (fn == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
@@ -3332,9 +3817,10 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 {
        smb_info_t *si = pinfo->private_data;
        int fn_len;
-       const char *fn;
+       const char *fn, *old_name=NULL, *new_name=NULL;
        guint8 wc;
        guint16 bc;
+       smb_rename_saved_info_t *rni=NULL;
 
        DISSECTOR_ASSERT(si);
 
@@ -3355,6 +3841,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
+       old_name=fn;
        proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
                fn);
        COUNT_BYTES(fn_len);
@@ -3374,6 +3861,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
+       new_name=fn;
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                fn);
        COUNT_BYTES(fn_len);
@@ -3385,6 +3873,16 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        END_OF_SMB
 
+       /* save the offset/len for this transaction */
+       if(si->sip && !pinfo->fd->flags.visited){
+               rni=se_alloc(sizeof(smb_rename_saved_info_t));
+               rni->old_name=se_strdup(old_name);
+               rni->new_name=se_strdup(new_name);
+
+               si->sip->extra_info_type=SMB_EI_RENAMEDATA;
+               si->sip->extra_info=rni;
+       }
+
        return offset;
 }
 
@@ -3504,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);
@@ -3538,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);
@@ -3579,24 +4077,14 @@ dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
        guint8 wc;
        guint16 cnt=0, bc;
        guint32 ofs=0;
-       smb_info_t *si;
        unsigned int fid;
 
        WORD_COUNT;
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
        offset += 2;
-       if (!pinfo->fd->flags.visited) {
-               /* remember the FID for the processing of the response */
-               si = (smb_info_t *)pinfo->private_data;
-               DISSECTOR_ASSERT(si);
-               if (si->sip) {
-                       si->sip->extra_info=GUINT_TO_POINTER(fid);
-                       si->sip->extra_info_type=SMB_EI_FID;
-               }
-       }
 
        /* read count */
        cnt = tvb_get_letohs(tvb, offset);
@@ -3720,14 +4208,6 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        /* 8 reserved bytes */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
        offset += 8;
-
-       /* If we have seen the request, then print which FID this refers to */
-       /* first check if we have seen the request */
-       if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type == SMB_EI_FID){
-               fid=GPOINTER_TO_INT(si->sip->extra_info);
-               dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE);
-       }
-
        BYTE_COUNT;
 
        /* buffer format */
@@ -3743,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;
        }
 
@@ -3786,6 +4266,12 @@ dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        return offset;
 }
 
+typedef struct _rw_info_t {
+       guint64 offset;
+       guint32 len;
+       guint16 fid;
+} rw_info_t;
+
 
 static int
 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
@@ -3793,12 +4279,16 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        guint32 ofs=0;
        guint16 cnt=0, bc, fid=0;
        guint8 wc;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       rw_info_t *rwi=NULL;
+
+       DISSECTOR_ASSERT(si);
 
        WORD_COUNT;
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* write count */
@@ -3816,6 +4306,29 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
                                ", %u byte%s at offset %u", cnt,
                                (cnt == 1) ? "" : "s", ofs);
 
+       /* save the offset/len for this transaction */
+       if(si->sip && !pinfo->fd->flags.visited){
+               rwi=se_alloc(sizeof(rw_info_t));
+               rwi->offset=ofs;
+               rwi->len=cnt;
+               rwi->fid=fid;
+
+               si->sip->extra_info_type=SMB_EI_RWINFO;
+               si->sip->extra_info=rwi;
+       }
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
+               rwi=si->sip->extra_info;
+       }
+       if(rwi){
+               proto_item *it;
+
+               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;
@@ -3835,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;
        }
 
@@ -3849,6 +4362,10 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 {
        guint8 wc;
        guint16 bc, cnt;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       rw_info_t *rwi=NULL;
+
+       DISSECTOR_ASSERT(si);
 
        WORD_COUNT;
 
@@ -3861,6 +4378,19 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
                col_append_fstr(pinfo->cinfo, COL_INFO,
                                ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
 
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
+               rwi=si->sip->extra_info;
+       }
+       if(rwi){
+               proto_item *it;
+
+               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);
+       }
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -3878,7 +4408,7 @@ dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, in
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* lock count */
@@ -3957,7 +4487,7 @@ dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -3998,7 +4528,7 @@ dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* Seek Mode */
@@ -4045,7 +4575,7 @@ dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* create time */
@@ -4102,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;
 
@@ -4122,7 +4652,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, TRUE, FALSE);
        offset += 2;
 
        /* write count */
@@ -4181,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
@@ -4214,7 +4744,7 @@ dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* offset */
@@ -4296,7 +4826,7 @@ dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* offset */
@@ -4402,8 +4932,8 @@ static int
 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -4411,27 +4941,27 @@ dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Write Mode: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_rawmode);
-       }
 
-       if(bm&WRITE_MODE_CONNECTIONLESS){
-               proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&WRITE_MODE_MESSAGE_START){
-               proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&WRITE_MODE_RAW){
-               proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&WRITE_MODE_RETURN_REMAINING){
-               proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&WRITE_MODE_WRITE_THROUGH){
-               proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
-                       tvb, offset, 2, mask);
+               if(bm&WRITE_MODE_CONNECTIONLESS){
+                       proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
+                               tvb, offset, 2, mask);
+               }
+               if(bm&WRITE_MODE_MESSAGE_START){
+                       proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
+                               tvb, offset, 2, mask);
+                               }
+               if(bm&WRITE_MODE_RAW){
+                       proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
+                               tvb, offset, 2, mask);
+               }
+               if(bm&WRITE_MODE_RETURN_REMAINING){
+                       proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
+                               tvb, offset, 2, mask);
+               }
+               if(bm&WRITE_MODE_WRITE_THROUGH){
+                       proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
+                               tvb, offset, 2, mask);
+               }
        }
 
        offset += 2;
@@ -4449,7 +4979,7 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* total data length */
@@ -4527,7 +5057,7 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* total data length */
@@ -4644,8 +5174,7 @@ dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
                TRUE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        /* ensure that it's null-terminated */
-       strncpy(fname, fn, 11);
-       fname[11] = '\0';
+       g_strlcpy(fname, fn, 11+1);
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
                fname);
        COUNT_BYTES_SUBR(fn_len);
@@ -4725,8 +5254,7 @@ dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
                TRUE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        /* ensure that it's null-terminated */
-       strncpy(fname, fn, 13);
-       fname[13] = '\0';
+       g_strlcpy(fname, fn, 13+1);
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                fname);
        COUNT_BYTES_SUBR(fn_len);
@@ -4952,14 +5480,19 @@ static const true_false_string tfs_lock_type_shared = {
 static int
 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
-       guint8  wc, cmd=0xff, lt=0;
-       guint16 andxoffset=0, un=0, ln=0, bc, fid;
+       guint8  wc, cmd=0xff, lt=0, ol=0;
+       guint16 andxoffset=0, un=0, ln=0, bc, fid, num_lock=0, num_unlock=0;
        guint32 to;
        proto_item *litem = NULL;
        proto_tree *ltree = NULL;
        proto_item *it = NULL;
        proto_tree *tr = NULL;
        int old_offset = offset;
+       smb_info_t *si = pinfo->private_data;
+       smb_locking_saved_info_t *ld=NULL;
+
+
+       DISSECTOR_ASSERT(si);
 
        WORD_COUNT;
 
@@ -4983,7 +5516,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        /* lock type */
@@ -4992,20 +5525,22 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
                litem = proto_tree_add_text(tree, tvb, offset, 1,
                        "Lock Type: 0x%02x", lt);
                ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
+
+               proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
+                       tvb, offset, 1, lt);
+               proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
+                       tvb, offset, 1, lt);
+               proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
+                       tvb, offset, 1, lt);
+               proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
+                       tvb, offset, 1, lt);
+               proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
+                       tvb, offset, 1, lt);
        }
-       proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
-               tvb, offset, 1, lt);
-       proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
-               tvb, offset, 1, lt);
-       proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
-               tvb, offset, 1, lt);
-       proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
-               tvb, offset, 1, lt);
-       proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
-               tvb, offset, 1, lt);
        offset += 1;
 
        /* oplock level */
+       ol = tvb_get_guint8(tvb, offset);
        proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
        offset += 1;
 
@@ -5016,16 +5551,31 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
 
        /* number of unlocks */
        un = tvb_get_letohs(tvb, offset);
+       num_unlock=un;
        proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
        offset += 2;
 
        /* number of locks */
        ln = tvb_get_letohs(tvb, offset);
+       num_lock=ln;
        proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
        offset += 2;
 
        BYTE_COUNT;
 
+       /* store the locking data for the response */
+       if((!pinfo->fd->flags.visited) && si->sip){
+               ld=se_alloc(sizeof(smb_locking_saved_info_t));
+               ld->type=lt;
+               ld->oplock_level= ol;
+               ld->num_lock=num_lock;
+               ld->num_unlock=num_unlock;
+               ld->locks=NULL;
+               ld->unlocks=NULL;
+               si->sip->extra_info_type=SMB_EI_LOCKDATA;
+               si->sip->extra_info=ld;
+       }
+
        /* unlocks */
        if(un){
                old_offset = offset;
@@ -5034,58 +5584,75 @@ 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;
+                               guint64 lock_offset;
+                               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);
-                               proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+                               lock_pid=tvb_get_letohs(tvb, offset);
+                               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 */
                                CHECK_BYTE_COUNT(8);
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
+                               lock_offset=val;
+                               proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
                                COUNT_BYTES(8);
 
                                /* length */
                                CHECK_BYTE_COUNT(8);
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
+                               lock_length=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 */
+                               if(ld){
+                                       smb_lock_info_t *li;
+                                       li=se_alloc(sizeof(smb_lock_info_t));
+                                       li->next=ld->unlocks;
+                                       ld->unlocks=li;
+                                       li->pid=lock_pid;
+                                       li->offset=lock_offset;
+                                       li->length=lock_length;
+                               }
                        } 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);
                        }
                }
@@ -5101,58 +5668,75 @@ 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;
+                               guint64 lock_offset;
+                               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);
-                               proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
+                               lock_pid=tvb_get_letohs(tvb, offset);
+                               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 */
                                CHECK_BYTE_COUNT(8);
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_offset, tvb, offset, 8, val);
+                               lock_offset=val;
+                               proto_tree_add_uint64(ltree_2, hf_smb_lock_long_offset, tvb, offset, 8, val);
                                COUNT_BYTES(8);
 
                                /* length */
                                CHECK_BYTE_COUNT(8);
                                val=((guint64)tvb_get_letohl(tvb, offset)) << 32
                                    | tvb_get_letohl(tvb, offset+4);
-                               proto_tree_add_uint64(ltree, hf_smb_lock_long_length, tvb, offset, 8, val);
+                               lock_length=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 */
+                               if(ld){
+                                       smb_lock_info_t *li;
+                                       li=se_alloc(sizeof(smb_lock_info_t));
+                                       li->next=ld->locks;
+                                       ld->locks=li;
+                                       li->pid=lock_pid;
+                                       li->offset=lock_offset;
+                                       li->length=lock_length;
+                               }
                        } else {
                                /* normal lock format */
-                               litem = proto_tree_add_text(tr, tvb, offset, 10,
-                                       "Unlock");
-                               ltree = proto_item_add_subtree(litem, ett_smb_unlock);
+                               litem_2 = proto_tree_add_text(tr, tvb, offset, 10,
+                                       "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);
                        }
                }
@@ -5186,6 +5770,58 @@ dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0;
        guint16 bc;
+       smb_info_t *si;
+
+       si = (smb_info_t *)pinfo->private_data;
+       DISSECTOR_ASSERT(si);
+
+       /* print the lock info from the request */
+       if (si->sip != NULL && si->sip->extra_info_type == SMB_EI_LOCKDATA) {
+               smb_locking_saved_info_t *ld;
+               proto_item *litem = NULL;
+               proto_tree *ltree = NULL;
+
+               ld = si->sip->extra_info;
+               if (ld != NULL) {
+                       proto_item *lit;
+                       proto_tree *ltr;
+                       smb_lock_info_t *li;
+                       if(tree){
+                               litem = proto_tree_add_text(tree, tvb, 0, 0,
+                                       "Lock Type: 0x%02x", ld->type);
+                               PROTO_ITEM_SET_GENERATED(litem);
+                               ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
+
+                               proto_tree_add_boolean(ltree, hf_smb_lock_type_large, tvb, 0, 0, ld->type);
+                               proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel, tvb, 0, 0, ld->type);
+                               proto_tree_add_boolean(ltree, hf_smb_lock_type_change, tvb, 0, 0, ld->type);
+                               proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock, tvb, 0, 0, ld->type);
+                               proto_tree_add_boolean(ltree, hf_smb_lock_type_shared, tvb, 0, 0, ld->type);
+                               proto_tree_add_uint(ltree, hf_smb_locking_ol, tvb, 0, 0, ld->oplock_level);
+                               proto_tree_add_uint(ltree, hf_smb_number_of_unlocks, tvb, 0, 0, ld->num_unlock);
+                               proto_tree_add_uint(ltree, hf_smb_number_of_locks, tvb, 0, 0, ld->num_lock);
+
+                               lit = proto_tree_add_text(ltree, tvb, 0, 0, "Locks");
+                               ltr = proto_item_add_subtree(lit, ett_smb_lock);
+                               li=ld->locks;
+                               while(li){
+                                       proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
+                                       proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
+                                       proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
+                                       li=li->next;
+                               }
+                               lit = proto_tree_add_text(ltree, tvb, 0, 0, "Unlocks");
+                               ltr = proto_item_add_subtree(lit, ett_smb_unlock);
+                               li=ld->unlocks;
+                               while(li){
+                                       proto_tree_add_uint(ltr, hf_smb_pid, tvb, 0, 0, li->pid);
+                                       proto_tree_add_uint64(ltr, hf_smb_lock_long_offset, tvb, 0, 0, li->offset);
+                                       proto_tree_add_uint64(ltr, hf_smb_lock_long_length, tvb, 0, 0, li->length);
+                                       li=li->next;
+                               }
+                       }
+               }
+       }
 
        WORD_COUNT;
 
@@ -5226,7 +5862,7 @@ const value_string oa_open_vals[] = {
        { 1,            "The file existed and was opened"},
        { 2,            "The file did not exist but was created"},
        { 3,            "The file existed and was truncated"},
-       { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
+       { 0x8001,       "The file existed and was opened, and an OpLock was granted"},
        { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
        { 0x8003,       "The file existed and was truncated, and an OpLock was granted"},
        {0,     NULL}
@@ -5239,8 +5875,8 @@ static int
 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -5248,13 +5884,12 @@ dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Action: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_open_action);
-       }
-
-       proto_tree_add_boolean(tree, hf_smb_open_action_lock,
-               tvb, offset, 2, mask);
-       proto_tree_add_uint(tree, hf_smb_open_action_open,
-               tvb, offset, 2, mask);
 
+               proto_tree_add_boolean(tree, hf_smb_open_action_lock,
+                       tvb, offset, 2, mask);
+               proto_tree_add_uint(tree, hf_smb_open_action_open,
+                       tvb, offset, 2, mask);
+       }
        offset += 2;
 
        return offset;
@@ -5280,8 +5915,8 @@ static int
 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -5289,23 +5924,23 @@ dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_open_flags);
-       }
 
-       if(bm&0x0001){
-               proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&0x0002){
-               proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&0x0004){
-               proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
-                       tvb, offset, 2, mask);
-       }
-       if(bm&0x0008){
-               proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
-                       tvb, offset, 2, mask);
+               if(bm&0x0001){
+                       proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
+                               tvb, offset, 2, mask);
+               }
+               if(bm&0x0002){
+                       proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
+                               tvb, offset, 2, mask);
+               }
+               if(bm&0x0004){
+                       proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
+                               tvb, offset, 2, mask);
+               }
+               if(bm&0x0008){
+                       proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
+                               tvb, offset, 2, mask);
+               }
        }
 
        offset += 2;
@@ -5362,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);
@@ -5394,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)));
@@ -5432,11 +6079,11 @@ 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 = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -5444,21 +6091,21 @@ dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "IPC State: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_ipc_state);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
-               tvb, offset, 2, mask);
-       if (!setstate) {
-               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,
+               proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
                        tvb, offset, 2, mask);
-       }
-       proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
-               tvb, offset, 2, mask);
-       if (!setstate) {
-               proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
+               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,
+                               tvb, offset, 2, mask);
+               }
+               proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
                        tvb, offset, 2, mask);
+               if (!setstate_flag) {
+                       proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
+                               tvb, offset, 2, mask);
+               }
        }
 
        offset += 2;
@@ -5472,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;
 
@@ -5495,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);
+        /* 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;
 
@@ -5512,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);
@@ -5549,9 +6228,14 @@ 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;
-       smb_info_t *si;
+       guint32 offsetlow, offsethigh=0;
+       guint64 ofs;
+       smb_info_t *si= (smb_info_t *)pinfo->private_data;
        unsigned int fid;
+       rw_info_t *rwi=NULL;
+
+
+       DISSECTOR_ASSERT(si);
 
        WORD_COUNT;
 
@@ -5575,20 +6259,11 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
        offset += 2;
-       if (!pinfo->fd->flags.visited) {
-               /* remember the FID for the processing of the response */
-               si = (smb_info_t *)pinfo->private_data;
-               DISSECTOR_ASSERT(si);
-               if (si->sip) {
-                       si->sip->extra_info=GUINT_TO_POINTER(fid);
-                       si->sip->extra_info_type=SMB_EI_FID;
-               }
-       }
 
        /* 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;
 
@@ -5617,11 +6292,25 @@ 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.
+        *
+        * Timeout is a timeout in milliseconds, with 0xffffffff
+        * and 0xfffffffe having special meaning.
         *
-        * We fetch and display it as 32 bits.
-         * 
+        * 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.
         */
@@ -5637,21 +6326,48 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        maxcnt=maxcnt_high;
        maxcnt=(maxcnt<<16)|maxcnt_low;
 
-       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);
-
        /* 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 %" G_GINT64_MODIFIER "u",
+                               maxcnt, (maxcnt == 1) ? "" : "s", ofs);
+
+       /* save the offset/len for this transaction */
+       if(si->sip && !pinfo->fd->flags.visited){
+               rwi=se_alloc(sizeof(rw_info_t));
+               rwi->offset=ofs;
+               rwi->len=maxcnt;
+               rwi->fid=fid;
+
+               si->sip->extra_info_type=SMB_EI_RWINFO;
+               si->sip->extra_info=rwi;
+       }
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
+               rwi=si->sip->extra_info;
+       }
+       if(rwi){
+               proto_item *it;
+
+               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);
+       }
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -5665,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)
 {
@@ -5672,7 +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);
 
@@ -5700,7 +6436,23 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* first check if we have seen the request */
        if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
                fid=GPOINTER_TO_INT(si->sip->extra_info);
-               dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE);
+               dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) fid, FALSE, FALSE, FALSE);
+       }
+
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
+               rwi=si->sip->extra_info;
+       }
+       if(rwi){
+               proto_item *it;
+
+               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);
+
+               /* we need the fid for the call to dcerpc below */
+               fid=rwi->fid;
        }
 
        /* remaining */
@@ -5725,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){
@@ -5754,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 */
@@ -5772,13 +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);
 
@@ -5804,18 +6620,11 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, (guint16) fid, FALSE, FALSE, FALSE);
        offset += 2;
-       if (!pinfo->fd->flags.visited) {
-               /* remember the FID for the processing of the response */
-               if (si->sip) {
-                       si->sip->extra_info=GUINT_TO_POINTER(fid);
-                       si->sip->extra_info_type=SMB_EI_FID;
-               }
-       }
 
        /* 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;
 
@@ -5831,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);
@@ -5850,18 +6663,45 @@ 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 (check_col(pinfo->cinfo, COL_INFO))
-               col_append_fstr(pinfo->cinfo, COL_INFO,
-                               ", %u byte%s at offset %u", datalen,
-                               (datalen == 1) ? "" : "s", ofs);
-
        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 %" G_GINT64_MODIFIER "u",
+                               datalen, (datalen == 1) ? "" : "s", ofs);
+
+       /* save the offset/len for this transaction */
+       if(si->sip && !pinfo->fd->flags.visited){
+               rwi=se_alloc(sizeof(rw_info_t));
+               rwi->offset=ofs;
+               rwi->len=datalen;
+               rwi->fid=fid;
+
+               si->sip->extra_info_type=SMB_EI_RWINFO;
+               si->sip->extra_info=rwi;
+       }
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
+               rwi=si->sip->extra_info;
+       }
+       if(rwi){
+               proto_item *it;
+
+               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);
+       }
+
+
        BYTE_COUNT;
 
        /* if both the MessageStart and the  WriteRawNamedPipe flags are set
@@ -5880,8 +6720,8 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                }
                if(!pinfo->fd->flags.visited){
                        /* In case we did not see the TreeConnect call,
-                          store this TID here as well as a IPC TID 
-                          so we know that future Read/Writes to this 
+                          store this TID here as well as a IPC TID
+                          so we know that future Read/Writes to this
                           TID is (probably) DCERPC.
                        */
                        if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
@@ -5897,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 */
@@ -5918,7 +6817,10 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc, count_low, count_high;
        guint32 count=0;
-       smb_info_t *si;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       rw_info_t *rwi=NULL;
+
+       DISSECTOR_ASSERT(si);
 
        WORD_COUNT;
 
@@ -5940,14 +6842,21 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
        offset += 2;
 
-       /* If we have seen the request, then print which FID this refers to */
-       si = (smb_info_t *)pinfo->private_data;
-       DISSECTOR_ASSERT(si);
-       /* first check if we have seen the request */
-       if(si->sip != NULL && si->sip->frame_req>0 && si->sip->extra_info_type==SMB_EI_FID){
-               dissect_smb_fid(tvb, pinfo, tree, 0, 0, (guint16) GPOINTER_TO_UINT(si->sip->extra_info), FALSE, FALSE);
+
+       if(si->sip && si->sip->extra_info_type==SMB_EI_RWINFO){
+               rwi=si->sip->extra_info;
+       }
+       if(rwi){
+               proto_item *it;
+
+               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);
        }
 
+
        /* write count low */
        count_low = tvb_get_letohs(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
@@ -5997,8 +6906,8 @@ static int
 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -6006,11 +6915,10 @@ dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Action: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_setup_action);
-       }
-
-       proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
-               tvb, offset, 2, mask);
 
+               proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
+                       tvb, offset, 2, mask);
+       }
        offset += 2;
 
        return offset;
@@ -6032,6 +6940,22 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        guint16 sbloblen=0, sbloblen_short;
        guint16 apwlen=0, upwlen=0;
        gboolean unicodeflag;
+       static int ntlmssp_tap_id = 0;
+       const ntlmssp_header_t *ntlmssph;
+
+       if(!ntlmssp_tap_id){
+               GString *error_string;
+               /* We dont specify any callbacks at all.
+                * Instead we manually fetch the tapped data after the
+                * security blob has been fully dissected and before
+                * we exit from this dissector.
+                */
+               error_string=register_tap_listener("ntlmssp", NULL, NULL,
+                   0, NULL, NULL, NULL);
+               if(!error_string){
+                       ntlmssp_tap_id=find_tap_id("ntlmssp");
+               }
+       }
 
        DISSECTOR_ASSERT(si);
 
@@ -6133,7 +7057,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                /* security blob */
                /* If it runs past the end of the captured data, don't
                 * try to put all of it into the protocol tree as the
-                * raw security blob; we might get an exception on 
+                * raw security blob; we might get an exception on
                 * short frames and then we will not see anything at all
                 * of the security blob.
                 */
@@ -6146,7 +7070,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                                                TRUE);
 
                /* As an optimization, because Windows is perverse,
-                  we check to see if NTLMSSP is the first part of the 
+                  we check to see if NTLMSSP is the first part of the
                   blob, and if so, call the NTLMSSP dissector,
                   otherwise we call the GSS-API dissector. This is because
                   Windows can request RAW NTLMSSP, but will happily handle
@@ -6157,7 +7081,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                        tvbuff_t *blob_tvb;
                        proto_tree *blob_tree;
 
-                       blob_tree = proto_item_add_subtree(blob_item, 
+                       blob_tree = proto_item_add_subtree(blob_item,
                                                           ett_smb_secblob);
                         CHECK_BYTE_COUNT(sbloblen);
 
@@ -6177,10 +7101,29 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
                        }
                        else {
-                         call_dissector(gssapi_handle, blob_tvb, 
+                         call_dissector(gssapi_handle, blob_tvb,
                                         pinfo, blob_tree);
                        }
 
+                       /* If we have found a uid->acct_name mapping, store it */
+                       if(!pinfo->fd->flags.visited && si->sip){
+                               int idx=0;
+                               if((ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)) != NULL){
+                                       if(ntlmssph && ntlmssph->type==3){
+                                               smb_uid_t *smb_uid;
+
+                                               smb_uid=se_alloc(sizeof(smb_uid_t));
+                                               smb_uid->logged_in=-1;
+                                               smb_uid->logged_out=-1;
+                                               smb_uid->domain=se_strdup(ntlmssph->domain_name);
+                                               smb_uid->account=se_strdup(ntlmssph->acct_name);
+
+                                               si->sip->extra_info=smb_uid;
+                                               si->sip->extra_info_type=SMB_EI_UID;
+                                       }
+                               }
+                       }
+
                        COUNT_BYTES(sbloblen);
                }
 
@@ -6311,10 +7254,10 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                COUNT_BYTES(dn_len);
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
-                       col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
+                       col_append_str(pinfo->cinfo, COL_INFO, ", User: ");
 
                        if (!dn[0] && !an[0])
-                               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               col_append_str(pinfo->cinfo, COL_INFO,
                                                "anonymous");
                        else
                                col_append_fstr(pinfo->cinfo, COL_INFO,
@@ -6374,6 +7317,15 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
        WORD_COUNT;
 
+       if(!pinfo->fd->flags.visited && si->sip && si->sip->extra_info &&
+           si->sip->extra_info_type==SMB_EI_UID){
+               smb_uid_t *smb_uid;
+
+               smb_uid=si->sip->extra_info;
+               smb_uid->logged_in=pinfo->fd->num;
+               se_tree_insert32(si->ct->uid_tree, si->uid, smb_uid);
+       }
+
        /* next smb command */
        cmd = tvb_get_guint8(tvb, offset);
        if(cmd!=0xff){
@@ -6408,7 +7360,7 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
                proto_item *blob_item;
 
                /* security blob */
-               /* dont try to eat too much of we might get an exception on 
+               /* dont try to eat too much of we might get an exception on
                 * short frames and then we will not see anything at all
                 * of the security blob.
                 */
@@ -6422,21 +7374,21 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
                        tvbuff_t *blob_tvb;
                        proto_tree *blob_tree;
 
-                       blob_tree = proto_item_add_subtree(blob_item, 
+                       blob_tree = proto_item_add_subtree(blob_item,
                                                           ett_smb_secblob);
                         CHECK_BYTE_COUNT(sbloblen);
 
-                       blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
+                       blob_tvb = tvb_new_subset(tvb, offset, sbloblen,
                                                    sbloblen);
 
-                       if (si && si->ct && si->ct->raw_ntlmssp && 
+                       if (si && si->ct && si->ct->raw_ntlmssp &&
                            tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
                          call_dissector(ntlmssp_handle, blob_tvb, pinfo,
                                         blob_tree);
 
                        }
                        else {
-                         call_dissector(gssapi_handle, blob_tvb, pinfo, 
+                         call_dissector(gssapi_handle, blob_tvb, pinfo,
                                         blob_tree);
 
                        }
@@ -6527,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",
@@ -6536,13 +7493,28 @@ 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)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -6550,12 +7522,18 @@ dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Optional Support: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_connect_support_search,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_connect_support_search,
+                       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;
 
@@ -6567,12 +7545,22 @@ 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)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -6580,10 +7568,14 @@ dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_connect_flags);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
-               tvb, offset, 2, mask);
+               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;
 
@@ -6651,7 +7643,7 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
         * dissect_smb_tid()   called from the response.
         */
        if((!pinfo->fd->flags.visited) && si->sip && an){
-               si->sip->extra_info_type=SMB_EI_FILENAME;
+               si->sip->extra_info_type=SMB_EI_TIDNAME;
                si->sip->extra_info=se_strdup(an);
        }
 
@@ -6694,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;
 
@@ -6737,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;
@@ -6832,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"},
@@ -6844,71 +7855,7 @@ const value_string nt_cmd_vals[] = {
        {0, NULL}
 };
 
-/* These IOCTL function values come from Visual 6.0 winioctl.h, and
-   are described in MSDN.
-   They are only FSCTLs (they all start with 0x0009). If we were
-   pedantic, we could check if ioctl_isfsctl boolean is set, but
-   this is redundant.
-*/
-static const value_string nt_ioctl_function_vals[] = {
-       {0x00090000, "FSCTL_REQUEST_OPLOCK_LEVEL_1"},
-       {0x00090004, "FSCTL_REQUEST_OPLOCK_LEVEL_2"},
-       {0x00090008, "FSCTL_REQUEST_BATCH_OPLOCK"},
-       {0x0009000C, "FSCTL_OPLOCK_BREAK_ACKNOWLEDGE"},
-       {0x00090010, "FSCTL_OPBATCH_ACK_CLOSE_PENDING"},
-       {0x00090014, "FSCTL_OPLOCK_BREAK_NOTIFY"},
-       {0x00090018, "FSCTL_LOCK_VOLUME"},
-       {0x0009001C, "FSCTL_UNLOCK_VOLUME"},
-       {0x00090020, "FSCTL_DISMOUNT_VOLUME"},
-       {0x00090028, "FSCTL_IS_VOLUME_MOUNTED"},
-       {0x0009002C, "FSCTL_IS_PATHNAME_VALID"},
-       {0x00090030, "FSCTL_MARK_VOLUME_DIRTY"},
-       {0x0009003B, "FSCTL_QUERY_RETRIEVAL_POINTERS"},
-       {0x0009003C, "FSCTL_GET_COMPRESSION"},
-       {0x0009C040, "FSCTL_SET_COMPRESSION"},
-       {0x0009004F, "FSCTL_MARK_AS_SYSTEM_HIVE"},
-       {0x00090050, "FSCTL_OPLOCK_BREAK_ACK_NO_2"},
-       {0x00090054, "FSCTL_INVALIDATE_VOLUMES"},
-       {0x00090058, "FSCTL_QUERY_FAT_BPB"},
-       {0x0009005C, "FSCTL_REQUEST_FILTER_OPLOCK"},
-       {0x00090060, "FSCTL_FILESYSTEM_GET_STATISTICS"},
-       {0x00090064, "FSCTL_GET_NTFS_VOLUME_DATA"},
-       {0x00090068, "FSCTL_GET_NTFS_FILE_RECORD"},
-       {0x0009006F, "FSCTL_GET_VOLUME_BITMAP"},
-       {0x00090073, "FSCTL_GET_RETRIEVAL_POINTERS"},
-       {0x00090074, "FSCTL_MOVE_FILE"},
-       {0x00090078, "FSCTL_IS_VOLUME_DIRTY"},
-       {0x0009007C, "FSCTL_GET_HFS_INFORMATION"},
-       {0x00090083, "FSCTL_ALLOW_EXTENDED_DASD_IO"},
-       {0x00090087, "FSCTL_READ_PROPERTY_DATA"},
-       {0x0009008B, "FSCTL_WRITE_PROPERTY_DATA"},
-       {0x0009008F, "FSCTL_FIND_FILES_BY_SID"},
-       {0x00090097, "FSCTL_DUMP_PROPERTY_DATA"},
-       {0x00098098, "FSCTL_SET_OBJECT_ID"},
-       {0x0009009C, "FSCTL_GET_OBJECT_ID"},
-       {0x000980A0, "FSCTL_DELETE_OBJECT_ID"},
-       {0x000980A4, "FSCTL_SET_REPARSE_POINT"},
-       {0x000900A8, "FSCTL_GET_REPARSE_POINT"},
-       {0x000980AC, "FSCTL_DELETE_REPARSE_POINT"},
-       {0x000940B3, "FSCTL_ENUM_USN_DATA"},
-       {0x000940B7, "FSCTL_SECURITY_ID_CHECK"},
-       {0x000940BB, "FSCTL_READ_USN_JOURNAL"},
-       {0x000980BC, "FSCTL_SET_OBJECT_ID_EXTENDED"},
-       {0x000900C0, "FSCTL_CREATE_OR_GET_OBJECT_ID"},
-       {0x000980C4, "FSCTL_SET_SPARSE"},
-       {0x000980C8, "FSCTL_SET_ZERO_DATA"},
-       {0x000940CF, "FSCTL_QUERY_ALLOCATED_RANGES"},
-       {0x000980D0, "FSCTL_ENABLE_UPGRADE"},
-       {0x000900D4, "FSCTL_SET_ENCRYPTION"},
-       {0x000900DB, "FSCTL_ENCRYPTION_FSCTL_IO"},
-       {0x000900DF, "FSCTL_WRITE_RAW_ENCRYPTED"},
-       {0x000900E3, "FSCTL_READ_RAW_ENCRYPTED"},
-       {0x000940E7, "FSCTL_CREATE_USN_JOURNAL"},
-       {0x000940EB, "FSCTL_READ_FILE_USN_DATA"},
-       {0x000940EF, "FSCTL_WRITE_USN_CLOSE_RECORD"},
-       {0x000900F0, "FSCTL_EXTEND_VOLUME"},
-       {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"},
@@ -7221,8 +8168,8 @@ static int
 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_guint8(tvb, offset);
 
@@ -7230,153 +8177,14 @@ dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
                        "Security Flags: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
-       }
-
-       proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
-               tvb, offset, 1, mask);
-
-       offset += 1;
-
-       return offset;
-}
-
-int
-dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
-{
-       guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-
-       mask = tvb_get_letohl(tvb, offset);
-
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 4,
-                       "Share Access: 0x%08x", mask);
-               tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
-       }
-
-       proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
-               tvb, offset, 4, mask);
-
-       offset += 4;
-
-       return offset;
-}
-
-/* FIXME: need to call dissect_nt_access_mask() instead */
-
-int
-dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
-{
-       guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-
-       mask = tvb_get_letohl(tvb, offset);
 
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 4,
-                       "Access Mask: 0x%08x", mask);
-               tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
+                       tvb, offset, 1, mask);
        }
 
-       /*
-        * Some of these bits come from
-        *
-        *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
-        *
-        * and others come from the section on ZwOpenFile in "Windows(R)
-        * NT(R)/2000 Native API Reference".
-        */
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
-               tvb, offset, 4, mask);
-
-       offset += 4;
-
-       return offset;
-}
-
-static int
-dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
-{
-       guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-
-       mask = tvb_get_letohl(tvb, offset);
-
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 4,
-                       "Create Flags: 0x%08x", mask);
-               tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
-       }
-
-       /*
-        * XXX - it's 0x00000016 in at least one capture, but
-        * Network Monitor doesn't say what the 0x00000010 bit is.
-        * Does the Win32 API documentation, or NT Native API book,
-        * suggest anything?
-        *
-        * That is the extended response desired bit ... RJS, from Samba
-        * Well, maybe. Samba thinks it is, and uses it to encode
-        * OpLock granted as the high order bit of the Action field
-        * in the response. However, Windows does not do that. Or at least
-        * Win2K doesn't.
-        */
-       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
-                              tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
-               tvb, offset, 4, mask);
-
-       offset += 4;
+       offset += 1;
 
        return offset;
 }
@@ -7479,78 +8287,12 @@ static const true_false_string tfs_nt_create_options_open_for_free_space_query =
        "This is NOT an open for free space query"
 };
 
-int
-dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
-{
-       guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-
-       mask = tvb_get_letohl(tvb, offset);
-
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 4,
-                       "Create Options: 0x%08x", mask);
-               tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
-       }
-
-       /*
-        * From
-        *
-        *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
-        */
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_intermediate_buffering,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_create_tree_connection,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_complete_if_oplocked,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_by_fileid,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_backup_intent,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_compression,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_reserve_opfilter,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_reparse_point,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_no_recall,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_create_options_open_for_free_space_query,
-               tvb, offset, 4, mask);
-
-       offset += 4;
-
-       return offset;
-}
-
 int
 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohl(tvb, offset);
 
@@ -7558,32 +8300,32 @@ dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int
                item = proto_tree_add_text(parent_tree, tvb, offset, 4,
                        "Completion Filter: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
-               tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
+                       tvb, offset, 4, mask);
+       }
 
        offset += 4;
        return offset;
@@ -7593,8 +8335,8 @@ static int
 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_guint8(tvb, offset);
 
@@ -7602,10 +8344,10 @@ dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
                        "Completion Filter: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
-               tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
+                       tvb, offset, 1, mask);
+       }
 
        offset += 1;
        return offset;
@@ -7644,8 +8386,8 @@ int
 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohl(tvb, offset);
 
@@ -7653,16 +8395,16 @@ dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int of
                item = proto_tree_add_text(parent_tree, tvb, offset, 4,
                        "Security Information: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
-               tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
+                       tvb, offset, 4, mask);
+       }
 
        offset += 4;
 
@@ -7733,6 +8475,7 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
        int old_offset = offset;
        guint16 bcp=bc; /* XXX fixme */
        struct access_mask_info *ami=NULL;
+       tvbuff_t *ioctl_tvb;
 
        si = (smb_info_t *)pinfo->private_data;
 
@@ -7742,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);
        }
 
@@ -7764,7 +8507,11 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
                break;
        case NT_TRANS_IOCTL:
                /* ioctl data */
-               proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
+               ioctl_tvb=tvb_new_subset(tvb, offset, MIN((int)bc, tvb_length_remaining(tvb, offset)), bc);
+               if (nti){
+                       dissect_smb2_ioctl_data(ioctl_tvb, pinfo, tree, top_tree_global, nti->ioctl_function, TRUE);
+               }
+
                offset += bc;
 
                break;
@@ -7823,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;
+       guint32 fn_len, create_flags, access_mask, share_access, create_options, create_disposition;
        const char *fn;
 
        si = (smb_info_t *)pinfo->private_data;
@@ -7833,14 +8580,15 @@ 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);
        }
 
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                /* Create flags */
-               offset = dissect_nt_create_bits(tvb, tree, offset);
+               create_flags=tvb_get_letohl(tvb, offset);
+               offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
                bc -= 4;
 
                /* root directory fid */
@@ -7848,7 +8596,8 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(4);
 
                /* nt access mask */
-               offset = dissect_smb_access_mask(tvb, tree, offset);
+               access_mask=tvb_get_letohl(tvb, offset);
+               offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
                bc -= 4;
 
                /* allocation size */
@@ -7860,15 +8609,18 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                bc -= 4;
 
                /* share access */
-               offset = dissect_nt_share_access(tvb, tree, offset);
+               share_access=tvb_get_letohl(tvb, offset);
+               offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
                bc -= 4;
 
                /* create disposition */
+               create_disposition=tvb_get_letohl(tvb, offset);
                proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
                COUNT_BYTES(4);
 
                /* create options */
-               offset = dissect_nt_create_options(tvb, tree, offset);
+               create_options=tvb_get_letohl(tvb, offset);
+               offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
                bc -= 4;
 
                /* sd length */
@@ -7911,7 +8663,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
-               fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+               fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
                offset += 2;
                if(nti){
                        if(fid_info){
@@ -7940,7 +8692,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
-               fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+               fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
                offset += 2;
                if(nti){
                        if(fid_info){
@@ -7974,18 +8726,24 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
-       smb_info_t *si;
        int old_offset = offset;
+       smb_info_t *si;
+       smb_nt_transact_info_t *nti = NULL;
+       smb_saved_info_t *sip;
 
-       si = (smb_info_t *)pinfo->private_data;
 
+       si = (smb_info_t *)pinfo->private_data;
        DISSECTOR_ASSERT(si);
+       sip = si->sip;
+       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);
        }
 
@@ -7996,12 +8754,11 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                guint16 fid;
 
                /* function code */
-               proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
-               offset += 4;
+               offset = dissect_smb2_ioctl_function(tvb, pinfo, tree, offset, nti ? &nti->ioctl_function : NULL);
 
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
-               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
                offset += 2;
 
                /* isfsctl */
@@ -8023,7 +8780,7 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
-               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
                offset += 2;
 
                /* watch tree */
@@ -8066,6 +8823,8 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        guint32 padcnt;
        smb_nt_transact_info_t *nti=NULL;
 
+       ntd.subcmd = ntd.sd_len = ntd.ea_len = 0;
+
        si = (smb_info_t *)pinfo->private_data;
        DISSECTOR_ASSERT(si);
        sip = si->sip;
@@ -8168,11 +8927,11 @@ 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) {
-                       if(!pinfo->fd->flags.visited && sip){
+               if (!si->unidir && sip) {
+                       if(!pinfo->fd->flags.visited){
                                /*
                                 * Allocate a new smb_nt_transact_info_t
                                 * structure.
@@ -8190,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_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
-               }
+               col_append_str(pinfo->cinfo, COL_INFO, " (secondary request)");
        }
        offset += 2;
 
@@ -8263,6 +9020,7 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
        smb_info_t *si;
        guint16 bcp;
        struct access_mask_info *ami=NULL;
+       tvbuff_t *ioctl_tvb;
 
        si = (smb_info_t *)pinfo->private_data;
        DISSECTOR_ASSERT(si);
@@ -8272,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
@@ -8293,7 +9051,9 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
                break;
        case NT_TRANS_IOCTL:
                /* ioctl data */
-               proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
+               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_global, nti->ioctl_function, FALSE);
+
                offset += len;
 
                break;
@@ -8345,6 +9105,9 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
        int old_offset;
        guint32 neo;
        int padcnt;
+       smb_fid_info_t *fid_info=NULL;
+       guint16 ftype;
+       guint8  isdir;
 
        si = (smb_info_t *)pinfo->private_data;
        DISSECTOR_ASSERT(si);
@@ -8359,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
@@ -8387,7 +9150,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
 
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
-               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+               fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
                offset += 2;
 
                /* create action */
@@ -8426,6 +9189,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
                offset += 8;
 
                /* File Type */
+               ftype=tvb_get_letohs(tvb, offset);
                proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
                offset += 2;
 
@@ -8433,8 +9197,29 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
                offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
                /* is directory */
+               isdir=tvb_get_guint8(tvb, offset);
                proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
                offset += 1;
+
+               /* Try to remember the type of this fid so that we can dissect
+                * any future security descriptor (access mask) properly
+                */
+               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){
+                       if(fid_info){
+                               fid_info->type=SMB_FID_TYPE_PIPE;
+                       }
+               }
                break;
        case NT_TRANS_IOCTL:
                break;
@@ -8549,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
@@ -8618,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_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
-               }
+               col_append_str(pinfo->cinfo, COL_INFO, ", <unknown>");
        }
 
        WORD_COUNT;
@@ -8838,7 +9621,7 @@ dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
        offset += 2;
 
        BYTE_COUNT;
@@ -9223,6 +10006,7 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
+       guint32 create_flags=0, access_mask=0, file_attributes=0, share_access=0, create_options=0, create_disposition=0;
 
        DISSECTOR_ASSERT(si);
 
@@ -9256,31 +10040,37 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        offset += 2;
 
        /* Create flags */
-       offset = dissect_nt_create_bits(tvb, tree, offset);
+       create_flags=tvb_get_letohl(tvb, offset);
+       offset = dissect_nt_create_bits(tvb, tree, offset, 4, create_flags);
 
        /* root directory fid */
        proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* nt access mask */
-       offset = dissect_smb_access_mask(tvb, tree, offset);
+       access_mask=tvb_get_letohl(tvb, offset);
+       offset = dissect_smb_access_mask_bits(tvb, tree, offset, 4, access_mask);
 
        /* allocation size */
        proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
        offset += 8;
 
        /* Extended File Attributes */
-       offset = dissect_file_ext_attr(tvb, tree, offset);
+       file_attributes=tvb_get_letohl(tvb, offset);
+       offset = dissect_file_ext_attr_bits(tvb, tree, offset, 4, file_attributes);
 
        /* share access */
-       offset = dissect_nt_share_access(tvb, tree, offset);
+       share_access=tvb_get_letohl(tvb, offset);
+       offset = dissect_nt_share_access_bits(tvb, tree, offset, 4, share_access);
 
        /* create disposition */
+       create_disposition=tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* create options */
-       offset = dissect_nt_create_options(tvb, tree, offset);
+       create_options=tvb_get_letohl(tvb, offset);
+       offset = dissect_nt_create_options_bits(tvb, tree, offset, 4, create_options);
 
        /* impersonation level */
        proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
@@ -9303,8 +10093,19 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         * dissect_smb_fid()   called from the response.
         */
        if((!pinfo->fd->flags.visited) && si->sip && fn){
-               si->sip->extra_info_type=SMB_EI_FILENAME;
-               si->sip->extra_info=se_strdup(fn);
+               smb_fid_saved_info_t *fsi;
+
+               fsi=se_alloc(sizeof(smb_fid_saved_info_t));
+               fsi->filename=se_strdup(fn);
+               fsi->create_flags=create_flags;
+               fsi->access_mask=access_mask;
+               fsi->file_attributes=file_attributes;
+               fsi->share_access=share_access;
+               fsi->create_options=create_options;
+               fsi->create_disposition=create_disposition;
+
+               si->sip->extra_info_type=SMB_EI_FILEDATA;
+               si->sip->extra_info=fsi;
        }
 
        if (check_col(pinfo->cinfo, COL_INFO)) {
@@ -9330,10 +10131,13 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0;
        guint16 bc;
-       guint16 fid;
+       guint16 fid=0;
        guint16 ftype;
        guint8  isdir;
        smb_fid_info_t *fid_info=NULL;
+       smb_info_t              *si;
+
+       si = pinfo->private_data;
 
        WORD_COUNT;
 
@@ -9361,7 +10165,7 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
        /* fid */
        fid = tvb_get_letohs(tvb, offset);
-       fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+       fid_info=dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
        offset += 2;
 
        /* create action */
@@ -9391,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;
 
@@ -9425,7 +10231,7 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                if(fid_info){
                        fid_info->type=SMB_FID_TYPE_PIPE;
                }
-       }               
+       }
 
        BYTE_COUNT;
 
@@ -9437,6 +10243,11 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
        }
 
+       /* if there was an error, add a generated filename to the tree */
+       if(si->nt_status){
+               dissect_smb_fid(tvb, pinfo, tree, 0, 0, fid, TRUE, TRUE, TRUE);
+       }
+
        return offset;
 }
 
@@ -9461,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" },
@@ -9477,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"
@@ -9523,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}
 };
@@ -9547,6 +10363,12 @@ static const value_string qpi_loi_vals[] = {
        { 0x010b,       "Query File Compression Info"},
        { 0x0200,       "Query File Unix Basic"},
        { 0x0201,       "Query File Unix Link"},
+       { 0x0202,       "Query File Unix Hardlink"},
+       { 0x0204,       "Query File Posix ACL"},
+       { 0x0205,       "Query File Posix XATTR"},
+       { 0x0206,       "Query File Posix Attr Flags"},
+       { 0x0207,       "Query File Posix Permissions"},
+       { 0x0208,       "Query File Posix Lock"},
        { 1004,         "Query File Basic Info"},
        { 1005,         "Query File Standard Info"},
        { 1006,         "Query File Internal Info"},
@@ -9602,6 +10424,12 @@ static const value_string spi_loi_vals[] = {
        { 0x0200,       "Set File Unix Basic"},
        { 0x0201,       "Set File Unix Link"},
        { 0x0202,       "Set File Unix HardLink"},
+       { 0x0204,       "Set File Unix ACL"},
+       { 0x0205,       "Set File Unix XATTR"},
+       { 0x0206,       "Set File Unix Attr Flags"},
+       { 0x0208,       "Set File Posix Lock"},
+       { 0x0209,       "Set File Posix Open"},
+       { 0x020a,       "Set File Posix Unlink"},
        { 1004,         "Set File Basic Info"},
        { 1010,         "Set Rename Information"},
        { 1013,         "Set Disposition Information"},
@@ -9679,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}
 };
 
@@ -9812,18 +10643,18 @@ dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, in
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_ff2_backup,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_ff2_continue,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_ff2_resume,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_ff2_close,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_ff2_backup,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_ff2_continue,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_ff2_resume,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_ff2_close,
+                       tvb, offset, 2, mask);
+       }
 
        offset += 2;
 
@@ -9835,8 +10666,8 @@ static int
 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -9844,12 +10675,12 @@ dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "IO Flag: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_ioflag);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_sfi_caching,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_sfi_caching,
+                       tvb, offset, 2, mask);
+       }
 
        offset += 2;
 
@@ -9880,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);
        }
 
@@ -9904,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 */
@@ -9974,6 +10805,9 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* search pattern */
                fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
+               if(t2i && !t2i->name){
+                       t2i->name = se_strdup(fn);
+               }
                proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
                        fn);
                COUNT_BYTES_TRANS(fn_len);
@@ -10037,7 +10871,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
 
                if (check_col(pinfo->cinfo, COL_INFO))
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
-                                       val_to_str(si->info_level, qfsi_vals, 
+                                       val_to_str(si->info_level, qfsi_vals,
                                                   "Unknown (0x%02x)"));
 
                break;
@@ -10052,8 +10886,8 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
                        col_append_fstr(
-                               pinfo->cinfo, COL_INFO, ", %s", 
-                               val_to_str(si->info_level, qpi_loi_vals, 
+                               pinfo->cinfo, COL_INFO, ", %s",
+                               val_to_str(si->info_level, qpi_loi_vals,
                                           "Unknown (%u)"));
                }
 
@@ -10068,6 +10902,9 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
                COUNT_BYTES_TRANS(fn_len);
+               if(t2i && !t2i->name){
+                       t2i->name = se_strdup(fn);
+               }
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
@@ -10108,7 +10945,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
                fid = tvb_get_letohs(tvb, offset);
-               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -10121,8 +10958,8 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
                        col_append_fstr(
-                               pinfo->cinfo, COL_INFO, ", %s", 
-                               val_to_str(si->info_level, qpi_loi_vals, 
+                               pinfo->cinfo, COL_INFO, ", %s",
+                               val_to_str(si->info_level, qpi_loi_vals,
                                           "Unknown (%u)"));
                }
 
@@ -10134,7 +10971,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
                fid = tvb_get_letohs(tvb, offset);
-               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE);
+               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -10319,8 +11156,8 @@ static guint16
 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -10328,12 +11165,12 @@ dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
+                       tvb, offset, 2, mask);
+       }
 
        return mask;
 }
@@ -10343,8 +11180,8 @@ static int
 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -10352,12 +11189,12 @@ dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
-               tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
+                       tvb, offset, 2, mask);
+       }
 
        offset += 2;
        return offset;
@@ -10367,8 +11204,8 @@ static int
 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -10376,10 +11213,12 @@ dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "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,
-               tvb, offset, 2, mask);
+               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);
+       }
 
        offset += 2;
 
@@ -10430,87 +11269,291 @@ 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;
+       /* path */
+       if (pathoffset) {
+               dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_path,
+                                           pathoffset+oldoffset, oldoffset, offset,
+                                           *bcp, unicode, ucstring_end);
+       }
 
-               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;
+       /* alt path */
+       if (altpathoffset) {
+               dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_alt_path,
+                                           altpathoffset+oldoffset, oldoffset, offset,
+                                           *bcp, unicode, ucstring_end);
+       }
 
-               while(numref--){
-                       proto_item *ri = NULL;
-                       proto_tree *rt = NULL;
-                       int old_offset=offset;
-                       guint16 version;
+       /* node */
+       if (nodeoffset) {
+               dissect_dfs_referral_string(tvb, tree, hf_smb_dfs_referral_node,
+                                           nodeoffset+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);
-                       }
+       return offset;
 
-                       /* 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);
+}
+
+
+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);
@@ -10525,6 +11568,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
 
                        /* referral flags */
                        CHECK_BYTE_COUNT_TRANS_SUBR(2);
+                       refflags = tvb_get_letohs(tvb, offset);
                        offset = dissect_dfs_referral_flags(tvb, rt, offset);
                        *bcp -= 2;
 
@@ -10540,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;
                        }
 
@@ -10634,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.
@@ -10648,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);
                }
 
                /*
@@ -10741,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 */
@@ -10779,14 +11748,14 @@ dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
                subtree = proto_item_add_subtree(item, ett_smb_ea);
 
                /* EA flags */
-               
+
                CHECK_BYTE_COUNT_SUBR(1);
                proto_tree_add_item(
                        subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
                COUNT_BYTES_SUBR(1);
 
                /* EA name length */
-               
+
                name_len = tvb_get_guint8(tvb, offset);
 
                CHECK_BYTE_COUNT_SUBR(1);
@@ -10797,7 +11766,7 @@ dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
                /* EA data length */
 
                data_len = tvb_get_letohs(tvb, offset);
-               
+
                CHECK_BYTE_COUNT_SUBR(2);
                proto_tree_add_item(
                        subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
@@ -10810,12 +11779,12 @@ dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 
                CHECK_BYTE_COUNT_SUBR(name_len + 1);
                proto_tree_add_item(
-                       subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
+                       subtree, hf_smb_ea_name, tvb, offset, name_len + 1,
                        TRUE);
                COUNT_BYTES_SUBR(name_len + 1);
 
                /* EA data */
-               
+
                CHECK_BYTE_COUNT_SUBR(data_len);
                proto_tree_add_item(
                        subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
@@ -10867,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;
@@ -11048,7 +12017,7 @@ dissect_qfi_SMB_FILE_ALTERNATE_NAME_INFO(tvbuff_t *tvb, packet_info *pinfo, prot
 }
 
 /* this dissects the SMB_QUERY_FILE_ALL_INFO
-   but not as described in 4.2.16.8 since CNIA spec is wrong 
+   but not as described in 4.2.16.8 since CNIA spec is wrong
 */
 static int
 dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
@@ -11069,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 */
@@ -11137,7 +12106,7 @@ dissect_qfi_SMB_FILE_ALL_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
    as described in 4.2.16.10
 */
 int
-dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+dissect_qfi_SMB_FILE_STREAM_INFO(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree,
     int offset, guint16 *bcp, gboolean *trunc, int unicode)
 {
        proto_item *item;
@@ -11371,10 +12340,174 @@ dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        return offset;
 }
 
+/* unix ACL
+*/
+static int
+dissect_qpi_unix_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                 int offset, guint16 *bcp, gboolean *trunc)
+{
+       guint16 version, num_file_aces, num_def_aces;
+       static const int *perm_fields[] = {
+               &hf_smb_posix_ace_perm_read,
+               &hf_smb_posix_ace_perm_write,
+               &hf_smb_posix_ace_perm_execute,
+               NULL
+       };
+
+       /* version */
+       CHECK_BYTE_COUNT_SUBR(2);
+       version = tvb_get_letohs(tvb, offset);
+       proto_tree_add_item(tree, hf_smb_posix_acl_version, tvb, offset, 2, TRUE);
+       COUNT_BYTES_SUBR(2);
+
+       /* num file acls */
+       CHECK_BYTE_COUNT_SUBR(2);
+       num_file_aces = tvb_get_letohs(tvb, offset);
+       proto_tree_add_item(tree, hf_smb_posix_num_file_aces, tvb, offset, 2, TRUE);
+       COUNT_BYTES_SUBR(2);
+
+       /* num default acls */
+       CHECK_BYTE_COUNT_SUBR(2);
+       num_def_aces = tvb_get_letohs(tvb, offset);
+       proto_tree_add_item(tree, hf_smb_posix_num_def_aces, tvb, offset, 2, TRUE);
+       COUNT_BYTES_SUBR(2);
+
+       while(num_file_aces--){
+               proto_item *it;
+               proto_tree *tr;
+               int old_offset = offset;
+               guint8 ace_type;
+
+               it = proto_tree_add_text(tree, tvb, offset, 0, "ACE");
+               tr = proto_item_add_subtree(it, ett_smb_posic_ace);
+
+               /* ace type */
+               CHECK_BYTE_COUNT_SUBR(1);
+               ace_type = tvb_get_guint8(tvb, offset);
+               proto_tree_add_item(tr, hf_smb_posix_ace_type, tvb, offset, 1, TRUE);
+               COUNT_BYTES_SUBR(1);
+
+               CHECK_BYTE_COUNT_SUBR(1);
+               proto_tree_add_bitmask(tr, tvb, offset, hf_smb_posix_ace_flags, ett_smb_posix_ace_perms, perm_fields, FALSE);
+               COUNT_BYTES_SUBR(1);
+
+               switch(ace_type){
+               case POSIX_ACE_TYPE_USER_OBJ:
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_uid, tvb, offset, 4, TRUE);
+                       COUNT_BYTES_SUBR(4);
+
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       /* 4 reserved bytes */
+                       COUNT_BYTES_SUBR(4);
+                       break;
+               case POSIX_ACE_TYPE_GROUP_OBJ:
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       proto_tree_add_item(tr, hf_smb_posix_ace_perm_owner_gid, tvb, offset, 4, TRUE);
+                       COUNT_BYTES_SUBR(4);
+
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       /* 4 reserved bytes */
+                       COUNT_BYTES_SUBR(4);
+                       break;
+
+               case POSIX_ACE_TYPE_MASK:
+               case POSIX_ACE_TYPE_OTHER:
+                       CHECK_BYTE_COUNT_SUBR(8);
+                       /* 8 reserved bytes */
+                       COUNT_BYTES_SUBR(8);
+                       break;
+
+               case POSIX_ACE_TYPE_USER:
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       proto_tree_add_item(tr, hf_smb_posix_ace_perm_uid, tvb, offset, 4, TRUE);
+                       COUNT_BYTES_SUBR(4);
+
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       /* 4 reserved bytes */
+                       COUNT_BYTES_SUBR(4);
+                       break;
+
+               case POSIX_ACE_TYPE_GROUP:
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       proto_tree_add_item(tr, hf_smb_posix_ace_perm_gid, tvb, offset, 4, TRUE);
+                       COUNT_BYTES_SUBR(4);
+
+                       CHECK_BYTE_COUNT_SUBR(4);
+                       /* 4 reserved bytes */
+                       COUNT_BYTES_SUBR(4);
+                       break;
+               default:
+                       proto_tree_add_text(tr, tvb, offset, 0, "Unknown posix ace type");
+                       CHECK_BYTE_COUNT_SUBR(8);
+                       /* skip 8 bytes */
+                       COUNT_BYTES_SUBR(8);
+               }
+
+               proto_item_set_len(it, offset-old_offset);
+       }
+
+       return offset;
+}
+
+static int
+dissect_qpi_unix_xattr(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
+                 int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
+{
+       proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
+
+       return offset;
+}
+
+static int
+dissect_qpi_unix_attr_flags(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
+                 int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
+{
+       proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
+
+       return offset;
+}
+
+static int
+dissect_qpi_unix_permissions(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
+                 int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
+{
+       proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
+
+       return offset;
+}
+
+static int
+dissect_qpi_unix_lock(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
+                 int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
+{
+       proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
+
+       return offset;
+}
+
+static int
+dissect_qpi_unix_open(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
+                 int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
+{
+       proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
+
+       return offset;
+}
+
+static int
+dissect_qpi_unix_unlink(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_,
+                 int offset _U_, guint16 *bcp _U_, gboolean *trunc _U_)
+{
+       proto_tree_add_text(tree, tvb, offset, 0, "Not Implemented yet");
+
+       return offset;
+}
+
 /* this dissects the SMB_QUERY_FILE_NETWORK_OPEN_INFO
 */
 int
-dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb, 
+dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
     packet_info *pinfo, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
@@ -11396,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 ... */
@@ -11411,8 +12544,8 @@ dissect_qfi_SMB_FILE_NETWORK_OPEN_INFO(tvbuff_t *tvb,
 /* this dissects the SMB_FILE_ATTRIBUTE_TAG_INFO
 */
 int
-dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb, 
-    packet_info *pinfo, proto_tree *tree,
+dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvbuff_t *tvb,
+    packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* attribute */
@@ -11583,7 +12716,7 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
-               
+
        case 2:         /*Info Query EA Size*/
                offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
                    &trunc);
@@ -11669,16 +12802,36 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                 offset = dissect_qfi_SMB_FILE_ATTRIBUTE_TAG_INFO(tvb, pinfo, tree, offset, bcp, &trunc);
                 break;
        case 0x0200:    /* Query File Unix Basic*/
-               offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
+               offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
                                           &trunc);
                break;
        case 0x0201:    /* Query File Unix Link*/
-               offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
+               offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
                                           &trunc);
                break;
        case 0x0202:    /* Query File Unix HardLink*/
                /* XXX add this from the SNIA doc */
                break;
+       case 0x0204:    /* Query File Unix ACL*/
+               offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0205:    /* Query File Unix XATTR*/
+               offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0206:    /* Query File Unix Attr Flags*/
+               offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0207:    /* Query File Unix Permissions*/
+               offset = dissect_qpi_unix_permissions(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0208:    /* Query File Unix Lock*/
+               offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
        }
 
        return offset;
@@ -11738,10 +12891,34 @@ dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
-       case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
+       case 0x0202:    /*Set File Unix HardLink.  Same as link query. */
                offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
+       case 0x0204:    /* Set File Unix ACL*/
+               offset = dissect_qpi_unix_acl(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0205:    /* Set File Unix XATTR*/
+               offset = dissect_qpi_unix_xattr(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0206:    /* Set File Unix Attr Flags*/
+               offset = dissect_qpi_unix_attr_flags(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0208:    /* Set File Unix Lock*/
+               offset = dissect_qpi_unix_lock(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x0209:    /* Set File Unix Open*/
+               offset = dissect_qpi_unix_open(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
+       case 0x020a:    /* Set File Unix Unlink*/
+               offset = dissect_qpi_unix_unlink(tvb, pinfo, tree, offset, bcp,
+                                          &trunc);
+               break;
        case 1010:      /* Set File Rename */
                offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
                    &trunc);
@@ -11791,8 +12968,8 @@ static void
 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_guint8(tvb, offset);
 
@@ -11801,21 +12978,23 @@ dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                        "Quota Flags: 0x%02x %s", mask,
                        mask?"Enabled":"Disabled");
                tree = proto_item_add_subtree(item, ett_smb_quotaflags);
-       }
-
-       proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
-               tvb, offset, 1, mask);
 
-       if(mask && (!(mask&0x01))){
-               proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
-                       tvb, offset, 1, 0x01);
-       } else {
-               proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
+               proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
                        tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
+                       tvb, offset, 1, mask);
+
+               if(mask && (!(mask&0x01))){
+                       proto_item *hidden_item;
+                       hidden_item = proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
+                               tvb, offset, 1, 0x01);
+                       PROTO_ITEM_SET_HIDDEN(hidden_item);
+               } else {
+                       proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
+                               tvb, offset, 1, mask);
+               }
        }
 
 }
@@ -11868,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);
        }
 
@@ -12112,7 +13291,7 @@ dissect_transaction_request(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, FALSE, FALSE);
+                       dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, FALSE, FALSE, FALSE);
 
                        offset += 2;
                }
@@ -12215,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){
@@ -12229,6 +13408,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                                t2i->subcmd = subcmd;
                                                t2i->info_level = -1;
                                                t2i->resume_keys = FALSE;
+                                               t2i->name = NULL;
                                                si->sip->extra_info = t2i;
                                                si->sip->extra_info_type = SMB_EI_T2I;
                                        }
@@ -12421,15 +13601,15 @@ 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 
-                                  so we know that future Read/Writes to this 
+                                  store this TID here as well as a IPC TID
+                                  so we know that future Read/Writes to this
                                   TID is (probably) DCERPC.
                                */
                                if(g_hash_table_lookup(si->ct->tid_service, GUINT_TO_POINTER(si->tid))){
@@ -12446,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]");
-                       }
                }
        }
 
@@ -12534,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 */
@@ -12628,31 +13806,220 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
        COUNT_BYTES_SUBR(4);
 
-       /* allocation size */
+       /* allocation size */
+       CHECK_BYTE_COUNT_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
+       COUNT_BYTES_SUBR(4);
+
+       /* File Attributes */
+       CHECK_BYTE_COUNT_SUBR(2);
+       offset = dissect_file_attributes(tvb, tree, offset);
+       *bcp -= 2;
+
+       /* ea length */
+       CHECK_BYTE_COUNT_SUBR(4);
+       proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
+       COUNT_BYTES_SUBR(4);
+
+       /* file name len */
+       CHECK_BYTE_COUNT_SUBR(1);
+       fn_len = tvb_get_guint8(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
+       COUNT_BYTES_SUBR(1);
+       if (si->unicode)
+               fn_len += 2;    /* include terminating '\0' */
+       else
+               fn_len++;       /* include terminating '\0' */
+
+       /* 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)));
+       }
+
+       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_4(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);
+       }
+
+       /*
+        * We assume that the presence of a next entry offset implies the
+        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        */
+
+       /* 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);
+
+       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);
+
+       /* 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_5(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);
+       }
+
+       /*
+        * We assume that the presence of a next entry offset implies the
+        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        */
+
+       /* 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);
+
+       /* 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);
-       proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
+       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);
 
-       /* File Attributes */
-       CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, tree, offset, 2);
-       *bcp -= 2;
-
        /* ea length */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
        COUNT_BYTES_SUBR(4);
 
-       /* file name len */
-       CHECK_BYTE_COUNT_SUBR(1);
-       fn_len = tvb_get_guint8(tvb, offset);
-       proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
-       COUNT_BYTES_SUBR(1);
-       if (si->unicode)
-               fn_len += 2;    /* include terminating '\0' */
-       else
-               fn_len++;       /* include terminating '\0' */
-
        /* file name */
        fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
@@ -12665,6 +14032,21 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                    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);
 
@@ -12673,11 +14055,11 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 }
 
 static int
-dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
-       int fn_len;
-       const char *fn;
+       int fn_len, sfn_len;
+       const char *fn, *sfn;
        int old_offset = offset;
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -12696,8 +14078,9 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        }
 
        /*
-        * We assume that the presence of a next entry offset implies the
-        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        * 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 */
@@ -12711,10 +14094,11 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        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;
-        }
+       if (*trunc) {
+         return offset;
+       }
 
        /* end of file */
        CHECK_BYTE_COUNT_SUBR(8);
@@ -12737,6 +14121,36 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        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);
+
        /* file name */
        fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
@@ -12772,7 +14186,7 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 }
 
 static int
-dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+dissect_4_3_4_6full(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        int fn_len;
@@ -12795,8 +14209,9 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        }
 
        /*
-        * We assume that the presence of a next entry offset implies the
-        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        * 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 */
@@ -12810,11 +14225,11 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
        COUNT_BYTES_SUBR(4);
 
-       /* standard 8-byte timestamps */
+        /* dissect standard 8-byte timestamps */
        offset = dissect_smb_standard_8byte_timestamps(tvb, pinfo, tree, offset, bcp, trunc);
-        if (*trunc) {
-          return offset;
-        }
+       if (*trunc) {
+         return offset;
+       }
 
        /* end of file */
        CHECK_BYTE_COUNT_SUBR(8);
@@ -12837,11 +14252,25 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
        COUNT_BYTES_SUBR(4);
 
-       /* ea length */
+       /*
+        * 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);
@@ -12877,7 +14306,7 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 }
 
 static int
-dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
+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;
@@ -12973,6 +14402,16 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                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);
@@ -13103,7 +14542,7 @@ dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
        COUNT_BYTES_SUBR(4);
-       
+
        /* ResumeKey */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
@@ -13237,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);
@@ -13254,8 +14701,8 @@ static int
 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohl(tvb, offset);
 
@@ -13263,54 +14710,53 @@ dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 4,
                        "FS Attributes: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
-       }
-
-       /* case sensitive search */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
-               tvb, offset, 4, mask);
-       /* case preserved names */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
-               tvb, offset, 4, mask);
-       /* unicode on disk */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
-               tvb, offset, 4, mask);
-       /* persistent acls */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
-               tvb, offset, 4, mask);
-       /* file compression */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
-               tvb, offset, 4, mask);
-       /* volume quotas */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
-               tvb, offset, 4, mask);
-       /* sparse files */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
-               tvb, offset, 4, mask);
-       /* reparse points */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
-               tvb, offset, 4, mask);
-       /* remote storage */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
-               tvb, offset, 4, mask);
-       /* lfn apis */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
-               tvb, offset, 4, mask);
-       /* volume is compressed */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
-               tvb, offset, 4, mask);
-       /* support oids */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
-               tvb, offset, 4, mask);
-       /* encryption */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
-               tvb, offset, 4, mask);
-       /* named streams */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
-               tvb, offset, 4, mask);
-       /* read only volume */
-       proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
-               tvb, offset, 4, mask);
 
+               /* case sensitive search */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
+                       tvb, offset, 4, mask);
+               /* case preserved names */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
+                       tvb, offset, 4, mask);
+               /* unicode on disk */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_uod,
+                       tvb, offset, 4, mask);
+               /* persistent acls */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
+                       tvb, offset, 4, mask);
+               /* file compression */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
+                       tvb, offset, 4, mask);
+               /* volume quotas */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
+                       tvb, offset, 4, mask);
+               /* sparse files */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_ssf,
+                       tvb, offset, 4, mask);
+               /* reparse points */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_srp,
+                       tvb, offset, 4, mask);
+               /* remote storage */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_srs,
+                       tvb, offset, 4, mask);
+               /* lfn apis */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_sla,
+                       tvb, offset, 4, mask);
+               /* volume is compressed */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
+                       tvb, offset, 4, mask);
+               /* support oids */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_soids,
+                       tvb, offset, 4, mask);
+               /* encryption */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_se,
+                       tvb, offset, 4, mask);
+               /* named streams */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_ns,
+                       tvb, offset, 4, mask);
+               /* read only volume */
+               proto_tree_add_boolean(tree, hf_smb_fs_attr_rov,
+                       tvb, offset, 4, mask);
+       }
 
        offset += 4;
        return offset;
@@ -13321,8 +14767,8 @@ static int
 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohl(tvb, offset);
 
@@ -13330,22 +14776,22 @@ dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offse
                item = proto_tree_add_text(parent_tree, tvb, offset, 4,
                        "Device Characteristics: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
-       }
 
-       proto_tree_add_boolean(tree, hf_smb_device_char_removable,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_device_char_remote,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
-               tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_removable,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_remote,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
+                       tvb, offset, 4, mask);
+               proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
+                       tvb, offset, 4, mask);
+       }
 
        offset += 4;
        return offset;
@@ -13379,7 +14825,7 @@ static const true_false_string tfs_smb_mac_streams = {
 };
 
 int
-dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp, int unicode)
+dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
 {
        int fn_len, vll;
        const char *fn;
@@ -13418,7 +14864,7 @@ dissect_qfsi_FS_VOLUME_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tr
 }
 
 int
-dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
+dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
 {
        /* allocation size */
        CHECK_BYTE_COUNT_TRANS_SUBR(8);
@@ -13444,7 +14890,7 @@ dissect_qfsi_FS_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree
 }
 
 int
-dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
+dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
 {
        /* device type */
        CHECK_BYTE_COUNT_TRANS_SUBR(4);
@@ -13460,7 +14906,7 @@ dissect_qfsi_FS_DEVICE_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tr
 }
 
 int
-dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp, int unicode)
+dissect_qfsi_FS_ATTRIBUTE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp, int unicode)
 {
        int fn_len, fnl;
        const char *fn;
@@ -13505,7 +14951,7 @@ dissect_qfsi_FS_OBJECTID_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree *
 }
 
 int
-dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, int offset, guint16 *bcp)
+dissect_qfsi_FS_FULL_SIZE_INFO(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, int offset, guint16 *bcp)
 {
        /* allocation size */
        CHECK_BYTE_COUNT_TRANS_SUBR(8);
@@ -13540,7 +14986,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
     int offset, guint16 *bcp)
 {
        smb_info_t *si;
-       int fn_len, vll, fnl;
+       int fn_len, vll;
        const char *fn;
        guint support = 0;
        proto_item *item = NULL;
@@ -13634,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;
 
@@ -13656,19 +15102,19 @@ 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(
-                               tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
+                       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(
-                       subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
+                       subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8,
                        caps_lo);
 
                proto_tree_add_boolean(
-                       subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
+                       subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8,
                        caps_lo);
 
                COUNT_BYTES_TRANS_SUBR(8);
@@ -13734,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);
@@ -13792,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,
@@ -13817,7 +15263,7 @@ dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
             break;
         }
                if (count && check_col(pinfo->cinfo, COL_INFO)) {
-                       col_append_fstr(pinfo->cinfo, COL_INFO,
+                       col_append_str(pinfo->cinfo, COL_INFO,
                        ", Files:");
                }
 
@@ -13836,7 +15282,7 @@ dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
             break;
         }
                if (count && check_col(pinfo->cinfo, COL_INFO)) {
-                       col_append_fstr(pinfo->cinfo, COL_INFO,
+                       col_append_str(pinfo->cinfo, COL_INFO,
                        ", Files:");
                }
 
@@ -13967,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,
@@ -13984,7 +15430,7 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
        case 0x00:      /*TRANS2_OPEN2*/
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
-               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE);
+               dissect_smb_fid(tvb, pinfo, tree, offset, 2, fid, TRUE, FALSE, FALSE);
                offset += 2;
 
                /*
@@ -14002,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,
@@ -14215,6 +15661,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
        tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
        tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
        gboolean save_fragmented;
+       proto_item *item;
 
        si = (smb_info_t *)pinfo->private_data;
        DISSECTOR_ASSERT(si);
@@ -14233,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_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
-                       }
+                       col_append_str(pinfo->cinfo, COL_INFO, "<unknown>");
                } else {
                        si->info_level = t2i->info_level;
                        if (t2i->subcmd == -1) {
@@ -14247,16 +15692,44 @@ 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_fstr(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);
-                               if (check_col(pinfo->cinfo, COL_INFO)) {
+                               /* FIND_FIRST2 */
+                               if(t2i && t2i->subcmd==0x0001){
+                                       item=proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
+                                       PROTO_ITEM_SET_GENERATED(item);
+                                       if(t2i->name){
+                                               item=proto_tree_add_string(tree, hf_smb_search_pattern, tvb, 0, 0, t2i->name);
+                                               PROTO_ITEM_SET_GENERATED(item);
+                                       }
+                               }
+
+                               /* QUERY_PATH_INFORMATION */
+                               if(t2i && t2i->subcmd==0x0005){
+                                       item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
+                                       PROTO_ITEM_SET_GENERATED(item);
+                                       if(t2i->name){
+                                               item=proto_tree_add_string(tree, hf_smb_file_name, tvb, 0, 0, t2i->name);
+                                               PROTO_ITEM_SET_GENERATED(item);
+                                       }
+                               }
+                               /* QUERY_FILE_INFORMATION */
+                               if(t2i && t2i->subcmd==0x0007){
+                                       item=proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, 0, 0, t2i->info_level);
+                                       PROTO_ITEM_SET_GENERATED(item);
+                               }
+                               /* QUERY_FS_INFORMATION */
+                               if(t2i && t2i->subcmd==0x0003){
+                                       item=proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, 0, 0, si->info_level);
+                                       PROTO_ITEM_SET_GENERATED(item);
+                               }
+
+                               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)>"));
                                }
                        }
                }
@@ -14326,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;
@@ -14368,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);
        }
@@ -14409,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);
                        }
                }
        }
@@ -14487,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;
 
@@ -14498,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;
                        }
@@ -14511,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;
@@ -14589,7 +16059,7 @@ static smb_function smb_dissector[256] = {
   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
   /* 0x05 Flush File*/  {dissect_flush_file_request, dissect_empty},
   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
-  /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
+  /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_rename_file_response},
   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
@@ -14859,6 +16329,7 @@ static int
 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
 {
        smb_info_t *si;
+       smb_saved_info_t *sip;
 
        si = pinfo->private_data;
        DISSECTOR_ASSERT(si);
@@ -14890,6 +16361,18 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *s
 
                cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
 
+               /* we track FIDs on a per transaction basis.
+                  if this was a request and the fid was seen in a reply
+                  we add a "generated" fid tree for this pdu and v.v.
+                */
+               sip = si->sip;
+               if (sip && sip->fid) {
+                       if( (si->request && (!sip->fid_seen_in_request))
+                         ||((!si->request) && sip->fid_seen_in_request) ){
+                               dissect_smb_fid(tvb, pinfo, cmd_tree, offset, 0, sip->fid, FALSE, FALSE, TRUE);
+                       }
+               }
+
                dissector = (si->request)?
                        smb_dissector[cmd].request:smb_dissector[cmd].response;
 
@@ -14907,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" },
@@ -15168,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);
@@ -15191,6 +16678,7 @@ free_hash_tables(gpointer ctarg, gpointer user_data _U_)
                g_hash_table_destroy(ct->matched);
        if (ct->tid_service)
                g_hash_table_destroy(ct->tid_service);
+       g_free(ct);
 }
 
 static void
@@ -15199,9 +16687,7 @@ smb_init_protocol(void)
        /*
         * Free the hash tables attached to the conversation table
         * structures, and then free the list of conversation table
-        * data structures (which doesn't free the data structures
-        * themselves; that's done by destroying the chunk from
-        * which they were allocated).
+        * data structures.
         */
        if (conv_tables) {
                g_slist_foreach(conv_tables, free_hash_tables, NULL);
@@ -15290,22 +16776,18 @@ static const char *decode_smb_error(guint8 errcls, guint16 errcode)
   case SMB_SUCCESS:
 
     return("No Error");   /* No error ??? */
-    break;
 
   case SMB_ERRDOS:
 
     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
-    break;
 
   case SMB_ERRSRV:
 
     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
-    break;
 
   case SMB_ERRHRD:
 
     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
-    break;
 
   default:
 
@@ -15348,8 +16830,8 @@ static int
 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_guint8(tvb, offset);
 
@@ -15357,21 +16839,23 @@ dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
                        "Flags: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_flags);
-       }
-       proto_tree_add_boolean(tree, hf_smb_flags_response,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags_notify,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags_oplock,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags_canon,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags_caseless,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
-               tvb, offset, 1, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags_lock,
-               tvb, offset, 1, mask);
+
+               proto_tree_add_boolean(tree, hf_smb_flags_response,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags_notify,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags_oplock,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags_canon,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags_caseless,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
+                       tvb, offset, 1, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags_lock,
+                       tvb, offset, 1, mask);
+       }
+
        offset += 1;
        return offset;
 }
@@ -15418,8 +16902,8 @@ static int
 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
+       proto_item *item;
+       proto_tree *tree;
 
        mask = tvb_get_letohs(tvb, offset);
 
@@ -15427,27 +16911,26 @@ dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags2: 0x%04x", mask);
                tree = proto_item_add_subtree(item, ett_smb_flags2);
-       }
-
-       proto_tree_add_boolean(tree, hf_smb_flags2_string,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_roe,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_esn,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_ea,
-               tvb, offset, 2, mask);
-       proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
-               tvb, offset, 2, mask);
 
+               proto_tree_add_boolean(tree, hf_smb_flags2_string,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_roe,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_esn,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_ea,
+                       tvb, offset, 2, mask);
+               proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
+                       tvb, offset, 2, mask);
+       }
        offset += 2;
        return offset;
 }
@@ -15466,33 +16949,22 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        proto_item *tmp_item=NULL;
        guint8          flags;
        guint16         flags2;
-       static smb_info_t       si_arr[20];
-       static int si_counter=0;
        smb_info_t              *si;
        smb_saved_info_t *sip = NULL;
        smb_saved_info_key_t key;
        smb_saved_info_key_t *new_key;
-       guint32 nt_status = 0;
        guint8 errclass = 0;
        guint16 errcode = 0;
        guint32 pid_mid;
        conversation_t *conversation;
        nstime_t t, deltat;
 
-       si_counter++;
-       if(si_counter>=20){
-               si_counter=0;
-       }
-       si=&si_arr[si_counter];
+       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*/
@@ -15536,20 +17008,14 @@ 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){
                /* No, not yet. create it and attach it to the conversation */
-               si->ct = se_alloc(sizeof(conv_tables_t));
+               si->ct = g_malloc(sizeof(conv_tables_t));
 
-                       conv_tables = g_slist_prepend(conv_tables, si->ct);
+               conv_tables = g_slist_prepend(conv_tables, si->ct);
                si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
                        smb_saved_info_equal_matched);
                si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
@@ -15558,9 +17024,12 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                        smb_saved_info_hash_unmatched,
                        smb_saved_info_equal_unmatched);
                si->ct->raw_ntlmssp = 0;
-               
+
                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);
        }
 
@@ -15775,6 +17244,8 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                sip->cmd = si->cmd;
                                sip->extra_info = NULL;
                                sip->extra_info_type = SMB_EI_NONE;
+                               sip->fid=0;
+                               sip->fid_seen_in_request=0;
                                g_hash_table_insert(si->ct->unmatched, GUINT_TO_POINTER(pid_mid), sip);
                                new_key = se_alloc(sizeof(smb_saved_info_key_t));
                                new_key->frame = sip->frame_req;
@@ -15832,7 +17303,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        if(flags2 & 0x4000){
                /* handle NT 32 bit error code */
 
-                nt_status = tvb_get_letohl(tvb, offset);
+               si->nt_status = tvb_get_letohl(tvb, offset);
 
                proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
                        TRUE);
@@ -15945,14 +17416,14 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        pinfo->private_data = si;
 
        /* TID
-        * TreeConnectAndX(0x75) is special, here it is the mere fact of 
-        * having a response that means that the share was mapped and we 
+        * TreeConnectAndX(0x75) is special, here it is the mere fact of
+        * having a response that means that the share was mapped and we
         * need to track it
         */
        if(!pinfo->fd->flags.visited && si->cmd==0x75 && !si->request){
-               offset=dissect_smb_tid(tvb, pinfo, htree, offset, si->tid, TRUE, FALSE);
+               offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, TRUE, FALSE);
        } else {
-               offset=dissect_smb_tid(tvb, pinfo, htree, offset, si->tid, FALSE, FALSE);
+               offset=dissect_smb_tid(tvb, pinfo, htree, offset, (guint16)si->tid, FALSE, FALSE);
        }
 
        /* PID */
@@ -15960,8 +17431,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        offset += 2;
 
        /* UID */
-       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
-       offset += 2;
+       offset=dissect_smb_uid(tvb, htree, offset, si);
 
        /* MID */
        proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
@@ -15980,13 +17450,13 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                         * The status is an NT status code; was there
                         * an error?
                         */
-                       if ((nt_status & 0xC0000000) == 0xC0000000) {
+                       if ((si->nt_status & 0xC0000000) == 0xC0000000) {
                                /*
                                 * Yes.
                                 */
                                col_append_fstr(
                                        pinfo->cinfo, COL_INFO, ", Error: %s",
-                                       val_to_str(nt_status, NT_errors,
+                                       val_to_str(si->nt_status, NT_errors,
                                            "Unknown (0x%08X)"));
                        }
                } else {
@@ -16010,7 +17480,7 @@ static gboolean
 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
 {
        /* must check that this really is a smb packet */
-       if (!tvb_bytes_exist(tvb, 0, 4))
+       if (tvb_length(tvb) < 4)
                return FALSE;
 
        if( (tvb_get_guint8(tvb, 0) != 0xff)
@@ -16029,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,
@@ -16077,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,
@@ -16102,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,
@@ -16110,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,
@@ -16221,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,
@@ -16237,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,
@@ -16281,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,
@@ -16354,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,
@@ -16369,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,
@@ -16385,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,
@@ -16406,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,
@@ -16474,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,
@@ -16574,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,
@@ -16602,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,
@@ -16621,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,
@@ -16642,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,
@@ -16662,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,
@@ -16693,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,
@@ -16705,7 +18175,7 @@ proto_register_smb(void)
                NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
 
        { &hf_smb_old_file_name,
-               { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
+               { "Old File Name", "smb.old_file", FT_STRING, BASE_NONE,
                NULL, 0, "Old File Name (When renaming a file)", HFILL }},
 
        { &hf_smb_offset,
@@ -16717,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,
@@ -16749,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,
@@ -16762,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,
@@ -16786,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,
@@ -16810,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,
@@ -16850,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,
@@ -16962,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,
@@ -16994,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 }},
@@ -17008,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 }},
@@ -17058,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,
@@ -17070,20 +18560,16 @@ 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,
                NULL, 0, "Number of setup words in this buffer", HFILL }},
 
-       { &hf_smb_nt_ioctl_function_code,
-               { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
-               VALS(nt_ioctl_function_vals), 0, "NT IOCTL function code", HFILL }},
-
        { &hf_smb_nt_ioctl_isfsctl,
                { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
                VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
@@ -17092,10 +18578,6 @@ proto_register_smb(void)
                { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
                TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
 
-       { &hf_smb_nt_ioctl_data,
-               { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
-               NULL, 0, "Data for the IOCTL call", HFILL }},
-
        { &hf_smb_nt_notify_action,
                { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
                VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
@@ -17174,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,
@@ -17314,7 +18796,7 @@ proto_register_smb(void)
                TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
 
        { &hf_smb_nt_create_bits_ext_resp,
-         { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
+         { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32,
            TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
 
        { &hf_smb_nt_create_options_directory_file,
@@ -17327,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,
@@ -17398,15 +18880,15 @@ proto_register_smb(void)
 
        { &hf_smb_nt_share_access_read,
                { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
+               TFS(&tfs_nt_share_access_read), SHARE_ACCESS_READ, "Can the object be shared for reading?", HFILL }},
 
        { &hf_smb_nt_share_access_write,
                { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
+               TFS(&tfs_nt_share_access_write), SHARE_ACCESS_WRITE, "Can the object be shared for write?", HFILL }},
 
        { &hf_smb_nt_share_access_delete,
                { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
-               TFS(&tfs_nt_share_access_delete), 0x00000004, "", 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,
@@ -17474,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,
@@ -17502,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,
@@ -17518,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,
@@ -17541,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,
@@ -17561,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,
@@ -17642,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,
@@ -17692,14 +19174,14 @@ 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,
                NULL, 0, "Latest referral version number understood", HFILL }},
 
        { &hf_smb_qfsi_information_level,
-               { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
+               { "Level of Interest", "smb.qfsi_loi", FT_UINT16, BASE_HEX,
                VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
 
        { &hf_smb_nt_rename_level,
@@ -17798,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,
@@ -17811,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,
@@ -17834,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 }},
@@ -17856,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,
@@ -17880,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,
@@ -17888,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,
@@ -17911,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,
@@ -17931,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,
@@ -18066,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 }},
@@ -18084,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,
@@ -18100,167 +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 }},
+         { "Link destination", "smb.unix.file.link_dest", FT_STRING,
+           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, NULL, HFILL }},
+
+        { &hf_smb_create_options,
+          { "Create Options", "smb.create_options", FT_UINT32, BASE_HEX,
+            NULL, 0, NULL, HFILL }},
+
+        { &hf_smb_share_access,
+          { "Share Access", "smb.share_access", FT_UINT32, BASE_HEX,
+            NULL, 0, NULL, HFILL }},
+
+        { &hf_smb_access_mask,
+          { "Access Mask", "smb.access_mask", FT_UINT32, BASE_HEX,
+            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_NONE,
+               NULL, 0, NULL, HFILL }},
+
+       { &hf_smb_logged_out,
+         { "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_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, NULL, HFILL }},
+
+       { &hf_smb_posix_acl_version,
+         { "Posix ACL version", "smb.posix_acl.version", FT_UINT16, BASE_DEC,
+               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, NULL, HFILL }},
+
+       { &hf_smb_posix_num_def_aces,
+         { "Number of default ACEs", "smb.posix_acl.num_def_aces", FT_UINT16, BASE_DEC,
+               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, NULL, HFILL }},
+
+       { &hf_smb_posix_ace_flags,
+         { "Permissions", "smb.posix_acl.ace_perms", FT_UINT8, BASE_HEX,
+               NULL, 0, NULL, HFILL }},
+
+       { &hf_smb_posix_ace_perm_read,
+          {"READ", "smb.posix_acl.ace_perms.read", FT_BOOLEAN, 8,
+               NULL, 0x04, NULL, HFILL}},
+
+       { &hf_smb_posix_ace_perm_write,
+          {"WRITE", "smb.posix_acl.ace_perms.write", FT_BOOLEAN, 8,
+               NULL, 0x02, NULL, HFILL}},
+
+       { &hf_smb_posix_ace_perm_execute,
+          {"EXECUTE", "smb.posix_acl.ace_perms.execute", FT_BOOLEAN, 8,
+               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, NULL, HFILL }},
+
+       { &hf_smb_posix_ace_perm_owner_gid,
+         { "Owner GID", "smb.posix_acl.ace_perms.owner_gid", FT_UINT32, BASE_DEC,
+               NULL, 0, NULL, HFILL }},
+
+       { &hf_smb_posix_ace_perm_uid,
+         { "UID", "smb.posix_acl.ace_perms.uid", FT_UINT32, BASE_DEC,
+               NULL, 0, NULL, HFILL }},
+
+       { &hf_smb_posix_ace_perm_gid,
+         { "GID", "smb.posix_acl.ace_perms.gid", FT_UINT32, BASE_DEC,
+               NULL, 0, NULL, HFILL }},
 
        };
 
@@ -18268,6 +19862,7 @@ proto_register_smb(void)
                &ett_smb,
                &ett_smb_fid,
                &ett_smb_tid,
+               &ett_smb_uid,
                &ett_smb_hdr,
                &ett_smb_command,
                &ett_smb_fileattributes,
@@ -18327,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,
@@ -18338,7 +19934,9 @@ proto_register_smb(void)
                &ett_smb_mac_support_flags,
                &ett_smb_unicode_password,
                &ett_smb_ea,
-               &ett_smb_unix_capabilities
+               &ett_smb_unix_capabilities,
+               &ett_smb_posic_ace,
+               &ett_smb_posix_ace_perms
        };
        module_t *smb_module;
 
@@ -18364,8 +19962,19 @@ 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);
 }
 
 void
@@ -18379,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);
 }