- some radcom files seem to have a different magic key than the one we
[obnox/wireshark/wip.git] / packet-smb.c
index 16c3dfa85804331c9200755bfe4e9b128abdb2e5..0f120d55e9c409ef00d56ac460c019ff9cb8274a 100644 (file)
@@ -3,24 +3,24 @@
  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
  *
- * $Id: packet-smb.c,v 1.200 2002/01/28 00:58:46 guy Exp $
+ * $Id: packet-smb.c,v 1.299 2002/12/05 22:15:54 sahlberg Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
  *
  * Copied from packet-pop.c
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * of the License, or (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <stdio.h>
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
 #include <time.h>
 #include <string.h>
 #include <glib.h>
@@ -52,6 +44,7 @@
 #include "prefs.h"
 #include "reassemble.h"
 
+#include "packet-smb-common.h"
 #include "packet-smb-mailslot.h"
 #include "packet-smb-pipe.h"
 
  *
  *     ftp://ftp.microsoft.com/developr/drg/CIFS/
  *
- * and a CIFS draft from the Storage Networking Industry Association
+ * and a CIFS specification from the Storage Networking Industry Association
  * can be found on a link from the page at
  *
- *     http://www.snia.org/English/Work_Groups/NAS/CIFS/WG_CIFS_Docs.html
+ *     http://www.snia.org/English/Collaterals/Work_Group_Docs/NAS/CIFS/CIFS_Technical_Reference.pdf
  *
  * (it supercedes the document at
  *
@@ -100,6 +93,7 @@ static int hf_smb_tid = -1;
 static int hf_smb_uid = -1;
 static int hf_smb_mid = -1;
 static int hf_smb_response_to = -1;
+static int hf_smb_time = -1;
 static int hf_smb_response_in = -1;
 static int hf_smb_continuation_to = -1;
 static int hf_smb_nt_status = -1;
@@ -135,6 +129,7 @@ static int hf_smb_server_timezone = -1;
 static int hf_smb_encryption_key_length = -1;
 static int hf_smb_encryption_key = -1;
 static int hf_smb_primary_domain = -1;
+static int hf_smb_server = -1;
 static int hf_smb_max_raw_buf_size = -1;
 static int hf_smb_server_guid = -1;
 static int hf_smb_security_blob_len = -1;
@@ -187,7 +182,14 @@ static int hf_smb_service = -1;
 static int hf_smb_move_flags_file = -1;
 static int hf_smb_move_flags_dir = -1;
 static int hf_smb_move_flags_verify = -1;
-static int hf_smb_move_files_moved = -1;
+static int hf_smb_files_moved = -1;
+static int hf_smb_copy_flags_file = -1;
+static int hf_smb_copy_flags_dir = -1;
+static int hf_smb_copy_flags_dest_mode = -1;
+static int hf_smb_copy_flags_source_mode = -1;
+static int hf_smb_copy_flags_verify = -1;
+static int hf_smb_copy_flags_tree_copy = -1;
+static int hf_smb_copy_flags_ea_action = -1;
 static int hf_smb_count = -1;
 static int hf_smb_file_name = -1;
 static int hf_smb_open_function_open = -1;
@@ -227,6 +229,22 @@ static int hf_smb_access_locality = -1;
 static int hf_smb_access_caching = -1;
 static int hf_smb_access_writetru = -1;
 static int hf_smb_create_time = -1;
+static int hf_smb_modify_time = -1;
+static int hf_smb_backup_time = -1;
+static int hf_smb_mac_alloc_block_count = -1;
+static int hf_smb_mac_alloc_block_size = -1;
+static int hf_smb_mac_free_block_count = -1;
+static int hf_smb_mac_fndrinfo = -1;
+static int hf_smb_mac_root_file_count = -1;
+static int hf_smb_mac_root_dir_count = -1;
+static int hf_smb_mac_file_count = -1;
+static int hf_smb_mac_dir_count = -1;
+static int hf_smb_mac_support_flags = -1;
+static int hf_smb_mac_sup_access_ctrl = -1;
+static int hf_smb_mac_sup_getset_comments = -1;
+static int hf_smb_mac_sup_desktopdb_calls = -1;
+static int hf_smb_mac_sup_unique_ids = -1;
+static int hf_smb_mac_sup_streams = -1;
 static int hf_smb_create_dos_date = -1;
 static int hf_smb_create_dos_time = -1;
 static int hf_smb_last_write_time = -1;
@@ -265,6 +283,7 @@ static int hf_smb_write_mode_raw = -1;
 static int hf_smb_write_mode_message_start = -1;
 static int hf_smb_write_mode_connectionless = -1;
 static int hf_smb_resume_key_len = -1;
+static int hf_smb_resume_find_id = -1;
 static int hf_smb_resume_server_cookie = -1;
 static int hf_smb_resume_client_cookie = -1;
 static int hf_smb_andxoffset = -1;
@@ -323,7 +342,9 @@ 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
 static int hf_smb_nt_notify_action = -1;
 static int hf_smb_nt_notify_watch_tree = -1;
 static int hf_smb_nt_notify_stream_write = -1;
@@ -397,13 +418,6 @@ static int hf_smb_file_eattr_compressed = -1;
 static int hf_smb_file_eattr_offline = -1;
 static int hf_smb_file_eattr_not_content_indexed = -1;
 static int hf_smb_file_eattr_encrypted = -1;
-static int hf_smb_file_eattr_write_through = -1;
-static int hf_smb_file_eattr_no_buffering = -1;
-static int hf_smb_file_eattr_random_access = -1;
-static int hf_smb_file_eattr_sequential_scan = -1;
-static int hf_smb_file_eattr_delete_on_close = -1;
-static int hf_smb_file_eattr_backup_semantics = -1;
-static int hf_smb_file_eattr_posix_semantics = -1;
 static int hf_smb_sec_desc_len = -1;
 static int hf_smb_sec_desc_revision = -1;
 static int hf_smb_sec_desc_type_owner_defaulted = -1;
@@ -440,6 +454,7 @@ static int hf_smb_nt_qsd_sacl = -1;
 static int hf_smb_extended_attributes = -1;
 static int hf_smb_oplock_level = -1;
 static int hf_smb_create_action = -1;
+static int hf_smb_file_id = -1;
 static int hf_smb_ea_error_offset = -1;
 static int hf_smb_end_of_file = -1;
 static int hf_smb_device_type = -1;
@@ -458,6 +473,13 @@ static int hf_smb_print_spool_file_number = -1;
 static int hf_smb_print_spool_file_size = -1;
 static int hf_smb_print_spool_file_name = -1;
 static int hf_smb_start_index = -1;
+static int hf_smb_originator_name = -1;
+static int hf_smb_destination_name = -1;
+static int hf_smb_message_len = -1;
+static int hf_smb_message = -1;
+static int hf_smb_mgid = -1;
+static int hf_smb_forwarded_name = -1;
+static int hf_smb_machine_name = -1;
 static int hf_smb_cancel_to = -1;
 static int hf_smb_trans2_subcmd = -1;
 static int hf_smb_trans_name = -1;
@@ -472,6 +494,10 @@ static int hf_smb_ff2_close_eos = -1;
 static int hf_smb_ff2_close = -1;
 static int hf_smb_ff2_information_level = -1;
 static int hf_smb_qpi_loi = -1;
+#if 0
+static int hf_smb_sfi_writetru = -1;
+static int hf_smb_sfi_caching = -1;
+#endif
 static int hf_smb_storage_type = -1;
 static int hf_smb_resume = -1;
 static int hf_smb_max_referral_level = -1;
@@ -509,6 +535,9 @@ static int hf_smb_dfs_referral_alt_path_offset = -1;
 static int hf_smb_dfs_referral_alt_path = -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;
+static int hf_smb_monitor_handle = -1;
+static int hf_smb_change_count = -1;
 static int hf_smb_file_index = -1;
 static int hf_smb_short_file_name = -1;
 static int hf_smb_short_file_name_len = -1;
@@ -521,6 +550,8 @@ static int hf_smb_volume_serial_num = -1;
 static int hf_smb_volume_label_len = -1;
 static int hf_smb_volume_label = -1;
 static int hf_smb_free_alloc_units64 = -1;
+static int hf_smb_caller_free_alloc_units64 = -1;
+static int hf_smb_actual_free_alloc_units64 = -1;
 static int hf_smb_max_name_len = -1;
 static int hf_smb_fs_name_len = -1;
 static int hf_smb_fs_name = -1;
@@ -538,6 +569,23 @@ static int hf_smb_fs_attr_fc = -1;
 static int hf_smb_fs_attr_vq = -1;
 static int hf_smb_fs_attr_dim = -1;
 static int hf_smb_fs_attr_vic = -1;
+static int hf_smb_quota_flags_enabled = -1;
+static int hf_smb_quota_flags_deny_disk = -1;
+static int hf_smb_quota_flags_log_limit = -1;
+static int hf_smb_quota_flags_log_warning = -1;
+static int hf_smb_soft_quota_limit = -1;
+static int hf_smb_hard_quota_limit = -1;
+static int hf_smb_user_quota_used = -1;
+static int hf_smb_user_quota_offset = -1;
+static int hf_smb_nt_rename_level = -1;
+static int hf_smb_cluster_count = -1;
+static int hf_smb_segments = -1;
+static int hf_smb_segment = -1;
+static int hf_smb_segment_overlap = -1;
+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 gint ett_smb = -1;
 static gint ett_smb_hdr = -1;
@@ -562,7 +610,7 @@ static gint ett_smb_lock_type = -1;
 static gint ett_smb_ssetupandxaction = -1;
 static gint ett_smb_optionsup = -1;
 static gint ett_smb_time_date = -1;
-static gint ett_smb_move_flags = -1;
+static gint ett_smb_move_copy_flags = -1;
 static gint ett_smb_file_attributes = -1;
 static gint ett_smb_search_resume_key = -1;
 static gint ett_smb_search_dir_info = -1;
@@ -582,6 +630,8 @@ static gint ett_smb_nt_create_options = -1;
 static gint ett_smb_nt_share_access = -1;
 static gint ett_smb_nt_security_flags = -1;
 static gint ett_smb_nt_trans_setup = -1;
+static gint ett_smb_nt_trans_data = -1;
+static gint ett_smb_nt_trans_param = -1;
 static gint ett_smb_nt_notify_completion_filter = -1;
 static gint ett_smb_nt_ioctl_flags = -1;
 static gint ett_smb_security_information_mask = -1;
@@ -589,6 +639,10 @@ static gint ett_smb_print_queue_entry = -1;
 static gint ett_smb_transaction_flags = -1;
 static gint ett_smb_transaction_params = -1;
 static gint ett_smb_find_first2_flags = -1;
+static gint ett_smb_mac_support_flags = -1;
+#if 0
+static gint ett_smb_ioflag = -1;
+#endif
 static gint ett_smb_transaction_data = -1;
 static gint ett_smb_stream_info = -1;
 static gint ett_smb_dfs_referrals = -1;
@@ -599,20 +653,38 @@ static gint ett_smb_ff2_data = -1;
 static gint ett_smb_device_characteristics = -1;
 static gint ett_smb_fs_attributes = -1;
 static gint ett_smb_segments = -1;
+static gint ett_smb_segment = -1;
 static gint ett_smb_sec_desc = -1;
 static gint ett_smb_sid = -1;
 static gint ett_smb_acl = -1;
 static gint ett_smb_ace = -1;
 static gint ett_smb_ace_flags = -1;
 static gint ett_smb_sec_desc_type = -1;
+static gint ett_smb_quotaflags = -1;
+static gint ett_smb_secblob = -1;
+
+static dissector_handle_t gssapi_handle = NULL;
+static dissector_handle_t ntlmssp_handle = NULL;
+
+static const fragment_items smb_frag_items = {
+       &ett_smb_segment,
+       &ett_smb_segments,
+
+       &hf_smb_segments,
+       &hf_smb_segment,
+       &hf_smb_segment_overlap,
+       &hf_smb_segment_overlap_conflict,
+       &hf_smb_segment_multiple_tails,
+       &hf_smb_segment_too_long_fragment,
+       &hf_smb_segment_error,
+
+       "segments"
+};
 
 proto_tree *top_tree=NULL;     /* ugly */
 
 static char *decode_smb_name(unsigned char);
-static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
-static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
-    int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
-    gboolean exactlen, guint16 *bcp);
+static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
 
 /*
  * Macros for use in the main dissector routines for an SMB.
@@ -720,7 +792,7 @@ smb_dcerpc_reassembly_init(void)
 
 
 static fragment_data *
-smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
+smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
                     int offset, int count, int pos, int totlen)
 {
        fragment_data *fd_head=NULL;
@@ -740,7 +812,7 @@ smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
                 * at one time?
                 *
                 * It is probably not much point in even trying to do something here
-                * if we have never seen the initial request. Without the initial 
+                * if we have never seen the initial request. Without the initial
                 * request we probably miss all parameters and the begining of data
                 * so we cant even call a subdissector since we can not determine
                 * which type of transaction call this is.
@@ -760,7 +832,7 @@ smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
           or else we might end up with dissecting one HUGE transaction PDU
           a LOT of times. (first fragment is the only one containing the setup
           bytes)
-          I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
+          I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
           SMBs. Takes a LOT of time dissecting and is not fun.
        */
        if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
@@ -769,7 +841,7 @@ smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
                return NULL;
        }
 }
-               
+
 
 
 
@@ -858,6 +930,7 @@ static int smb_nt_transact_info_init_count = 200;
 typedef struct {
        int subcmd;
        int info_level;
+       gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
 } smb_transact2_info_t;
 
 static GMemChunk *smb_transact2_info_chunk = NULL;
@@ -948,7 +1021,7 @@ TimeZone(time_t t)
 /*
  * Return the same value as TimeZone, but it should be more efficient.
  *
- * We keep a table of DST offsets to prevent calling localtime() on each 
+ * We keep a table of DST offsets to prevent calling localtime() on each
  * call of this function. This saves a LOT of time on many unixes.
  *
  * Updated by Paul Eggert <eggert@twinsun.com>
@@ -1003,19 +1076,19 @@ TimeZoneFaster(time_t t)
                } else {
                        dst_table = tdt;
                        table_size++;
-    
-                       dst_table[i].zone = zone; 
+
+                       dst_table[i].zone = zone;
                        dst_table[i].start = dst_table[i].end = t;
-    
+
                        /* no entry will cover more than 6 months */
                        low = t - MAX_DST_WIDTH/2;
                        if (t < low)
                                low = TIME_T_MIN;
-      
+
                        high = t + MAX_DST_WIDTH/2;
                        if (high < t)
                                high = TIME_T_MAX;
-      
+
                        /*
                         * Widen the new entry using two bisection searches.
                         */
@@ -1070,11 +1143,11 @@ LocTimeDiff(time_t lt)
 }
 
 static int
-dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
+dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
 {
        guint32 timeval;
        nstime_t ts;
+
        timeval = tvb_get_letohl(tvb, offset);
        if (timeval == 0xffffffff) {
                proto_tree_add_text(tree, tvb, offset, 4,
@@ -1092,7 +1165,7 @@ dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
 
        proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
        offset += 4;
+
        return offset;
 }
 
@@ -1122,7 +1195,7 @@ static gboolean
 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
 {
        double d;
-       /* The next two lines are a fix needed for the 
+       /* The next two lines are a fix needed for the
            broken SCO compiler. JRA. */
        time_t l_time_min = TIME_T_MIN;
        time_t l_time_max = TIME_T_MAX;
@@ -1136,7 +1209,7 @@ nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
        d = ((double)filetime_high)*4.0*(double)(1<<30);
        d += filetime_low;
        d *= 1.0e-7;
+
        /* Now adjust by 369 years, to make the seconds since 1970. */
        d -= TIME_FIXUP_CONSTANT;
 
@@ -1153,11 +1226,15 @@ nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
 }
 
 int
-dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
+dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
 {
        guint32 filetime_high, filetime_low;
        nstime_t ts;
 
+       /* XXX there seems also to be another special time value which is fairly common :
+          0x40000000 00000000
+          the meaning of this one is yet unknown
+       */
        if (tree) {
                filetime_low = tvb_get_letohl(tvb, offset);
                filetime_high = tvb_get_letohl(tvb, offset + 4);
@@ -1165,6 +1242,14 @@ dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
                        proto_tree_add_text(tree, tvb, offset, 8,
                            "%s: No time specified (0)",
                            proto_registrar_get_name(hf_date));
+               } else if(filetime_low==0 && filetime_high==0x80000000){
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: Infinity (relative time)",
+                           proto_registrar_get_name(hf_date));
+               } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: Infinity (absolute time)",
+                           proto_registrar_get_name(hf_date));
                } else {
                        if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
                                proto_tree_add_time(tree, hf_date, tvb,
@@ -1182,9 +1267,8 @@ dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
 }
 
 static int
-dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
-    int hf_dos_time, gboolean time_first)
+dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+    int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
 {
        guint16 dos_time, dos_date;
        proto_item *item = NULL;
@@ -1208,8 +1292,8 @@ dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
                dos_time = tvb_get_letohs(tvb, offset+2);
        }
 
-       if ((dos_time == 0xffff && dos_time == 0xffff) ||
-           (dos_time == 0 && dos_time == 0)) {
+       if ((dos_date == 0xffff && dos_time == 0xffff) ||
+           (dos_date == 0 && dos_time == 0)) {
                /*
                 * No date/time specified.
                 */
@@ -1314,7 +1398,7 @@ static const true_false_string tfs_da_writetru = {
        "Write through disabled"
 };
 static int
-dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
+dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1344,61 +1428,22 @@ dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int o
        return offset;
 }
 
-#define FILE_ATTRIBUTE_READ_ONLY               0x00000001
-#define FILE_ATTRIBUTE_HIDDEN                  0x00000002
-#define FILE_ATTRIBUTE_SYSTEM                  0x00000004
-#define FILE_ATTRIBUTE_VOLUME                  0x00000008
-#define FILE_ATTRIBUTE_DIRECTORY               0x00000010
-#define FILE_ATTRIBUTE_ARCHIVE                 0x00000020
-#define FILE_ATTRIBUTE_DEVICE                  0x00000040
-#define FILE_ATTRIBUTE_NORMAL                  0x00000080
-#define FILE_ATTRIBUTE_TEMPORARY               0x00000100
-#define FILE_ATTRIBUTE_SPARSE                  0x00000200
-#define FILE_ATTRIBUTE_REPARSE                 0x00000400
-#define FILE_ATTRIBUTE_COMPRESSED              0x00000800
-#define FILE_ATTRIBUTE_OFFLINE                 0x00001000
-#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED     0x00002000
-#define FILE_ATTRIBUTE_ENCRYPTED               0x00004000
+#define SMB_FILE_ATTRIBUTE_READ_ONLY           0x00000001
+#define SMB_FILE_ATTRIBUTE_HIDDEN                      0x00000002
+#define SMB_FILE_ATTRIBUTE_SYSTEM                      0x00000004
+#define SMB_FILE_ATTRIBUTE_VOLUME                      0x00000008
+#define SMB_FILE_ATTRIBUTE_DIRECTORY           0x00000010
+#define SMB_FILE_ATTRIBUTE_ARCHIVE                     0x00000020
+#define SMB_FILE_ATTRIBUTE_DEVICE                      0x00000040
+#define SMB_FILE_ATTRIBUTE_NORMAL                      0x00000080
+#define SMB_FILE_ATTRIBUTE_TEMPORARY           0x00000100
+#define SMB_FILE_ATTRIBUTE_SPARSE                      0x00000200
+#define SMB_FILE_ATTRIBUTE_REPARSE                     0x00000400
+#define SMB_FILE_ATTRIBUTE_COMPRESSED          0x00000800
+#define SMB_FILE_ATTRIBUTE_OFFLINE                     0x00001000
+#define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define SMB_FILE_ATTRIBUTE_ENCRYPTED           0x00004000
 
-/*
- * These are flags to be used in NT Create operations.
- */
-#define FILE_ATTRIBUTE_WRITE_THROUGH           0x80000000
-#define FILE_ATTRIBUTE_NO_BUFFERING            0x20000000
-#define FILE_ATTRIBUTE_RANDOM_ACCESS           0x10000000
-#define FILE_ATTRIBUTE_SEQUENTIAL_SCAN         0x08000000
-#define FILE_ATTRIBUTE_DELETE_ON_CLOSE         0x04000000
-#define FILE_ATTRIBUTE_BACKUP_SEMANTICS                0x02000000
-#define FILE_ATTRIBUTE_POSIX_SEMANTICS         0x01000000
-
-static const true_false_string tfs_file_attribute_write_through = {
-       "This object requires WRITE THROUGH",
-       "This object does NOT require write through",
-};
-static const true_false_string tfs_file_attribute_no_buffering = {
-       "This object requires NO BUFFERING",
-       "This object can be buffered",
-};
-static const true_false_string tfs_file_attribute_random_access = {
-       "This object will be RANDOM ACCESSed",
-       "Random access is NOT requested",
-};
-static const true_false_string tfs_file_attribute_sequential_scan = {
-       "This object is optimized for SEQUENTIAL SCAN",
-       "This object is NOT optimized for sequential scan",
-};
-static const true_false_string tfs_file_attribute_delete_on_close = {
-       "This object will be DELETED ON CLOSE",
-       "This object will not be deleted on close",
-};
-static const true_false_string tfs_file_attribute_backup_semantics = {
-       "This object supports BACKUP SEMANTICS",
-       "This object does NOT support backup semantics",
-};
-static const true_false_string tfs_file_attribute_posix_semantics = {
-       "This object supports POSIX SEMANTICS",
-       "This object does NOT support POSIX semantics",
-};
 static const true_false_string tfs_file_attribute_read_only = {
        "This file is READ ONLY",
        "This file is NOT read only",
@@ -1460,41 +1505,62 @@ static const true_false_string tfs_file_attribute_encrypted = {
        "This is NOT an encrypted file"
 };
 
+/*
+ * 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.
+ */
+
 static int
-dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+                       int bytes)
 {
        guint16 mask;
        proto_item *item = NULL;
        proto_tree *tree = NULL;
 
+       if (bytes != 2 && bytes != 4) {
+
+               fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
+               exit(1);
+
+       }
+
+       /*
+        * 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, 2,
-                       "File Attributes: 0x%04x", mask);
+               item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
+                       "File Attributes: 0x%08x", mask);
                tree = proto_item_add_subtree(item, ett_smb_file_attributes);
        }
-       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_hidden_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_volume_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_archive_16bit,
-               tvb, offset, 2, mask);
+               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 += 2;
+       offset += bytes;
 
        return offset;
 }
 
 /* 3.11 */
 static int
-dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -1517,20 +1583,6 @@ dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
         * Does the Win32 API documentation, or the NT Native API book,
         * suggest anything?
         */
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
-               tvb, offset, 4, mask);
-       proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
-               tvb, offset, 4, mask);
        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,
@@ -1568,7 +1620,7 @@ dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
 }
 
 static int
-dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -1625,7 +1677,7 @@ static const true_false_string tfs_search_attribute_archive = {
 };
 
 static int
-dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1644,7 +1696,7 @@ dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
        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);  
+               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,
@@ -1811,7 +1863,7 @@ static const true_false_string tfs_server_cap_extended_security = {
        "Extended security exchanges are not supported"
 };
 static int
-dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -1878,7 +1930,7 @@ static const true_false_string tfs_rm_write = {
 };
 
 static int
-dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1921,7 +1973,7 @@ static const true_false_string tfs_sm_sig_required = {
 };
 
 static int
-dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
+dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
 {
        guint16 mask = 0;
        proto_item *item = NULL;
@@ -1955,7 +2007,7 @@ dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *par
 }
 
 static int
-dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        proto_item *it = NULL;
        proto_tree *tr = NULL;
@@ -2007,8 +2059,9 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
 }
 
 static int
-dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        guint8 wc;
        guint16 dialect;
        const char *dn;
@@ -2054,8 +2107,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
        switch(wc){
        case 13:
                /* Security Mode */
-               offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
-                               wc);
+               offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
 
                /* Maximum Transmit Buffer Size */
                proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
@@ -2073,7 +2125,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                offset += 2;
 
                /* raw mode */
-               offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
+               offset = dissect_negprot_rawmode(tvb, tree, offset);
 
                /* session key */
                proto_tree_add_item(tree, hf_smb_session_key,
@@ -2081,7 +2133,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                offset += 4;
 
                /* current time and date at server */
-               offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
+               offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
                    TRUE);
 
                /* time zone */
@@ -2102,7 +2154,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
        case 17:
                /* Security Mode */
-               offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
+               offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
 
                /* Maximum Multiplex Count */
                proto_tree_add_item(tree, hf_smb_max_mpx_count,
@@ -2130,11 +2182,11 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                offset += 4;
 
                /* server capabilities */
-               caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+               caps = dissect_negprot_capabilities(tvb, tree, offset);
                offset += 4;
 
                /* system time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
                                hf_smb_system_time);
 
                /* time zone */
@@ -2164,9 +2216,22 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                        COUNT_BYTES(ekl);
                }
 
-               /* domain */
+               /*
+                * Primary domain.
+                *
+                * XXX - not present if negotiated dialect isn't
+                * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
+                * have to see the request, or assume what dialect strings
+                * were sent, to determine that.
+                *
+                * Is this something other than a primary domain if the
+                * negotiated dialect is Windows for Workgroups 3.1a?
+                * It appears to be 8 bytes of binary data in at least
+                * one capture - is that an encryption key or something
+                * such as that?
+                */
                dn = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &dn_len, FALSE, FALSE, &bc);
+                       si->unicode, &dn_len, FALSE, FALSE, &bc);
                if (dn == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
@@ -2176,8 +2241,6 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
        case 17:
                if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
-                       smb_info_t *si;
-
                        /* challenge/response encryption key */
                        /* XXX - is this aligned on an even boundary? */
                        if(ekl){
@@ -2189,18 +2252,35 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
                        /* domain */
                        /* this string is special, unicode is flagged in caps */
-                       /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
-                       si = pinfo->private_data;
+                       /* This string is NOT padded to be 16bit aligned.
+                          (seen in actual capture)
+                          XXX - I've seen a capture where it appears to be
+                          so aligned, but I've also seen captures where
+                          it is.  The captures where it appeared to be
+                          aligned may have been from buggy servers. */
                        si->unicode = (caps&SERVER_CAP_UNICODE);
                        dn = get_unicode_or_ascii_string(tvb,
-                               &offset, pinfo, &dn_len, TRUE, FALSE,
+                               &offset, si->unicode, &dn_len, TRUE, FALSE,
                                &bc);
                        if (dn == NULL)
                                goto endofcommand;
                        proto_tree_add_string(tree, hf_smb_primary_domain,
                                tvb, offset, dn_len, dn);
                        COUNT_BYTES(dn_len);
+
+                       /* server name, seen in w2k pro capture */
+                       dn = get_unicode_or_ascii_string(tvb,
+                               &offset, si->unicode, &dn_len, TRUE, FALSE,
+                               &bc);
+                       if (dn == NULL)
+                               goto endofcommand;
+                       proto_tree_add_string(tree, hf_smb_server,
+                               tvb, offset, dn_len, dn);
+                       COUNT_BYTES(dn_len);
+
                } else {
+                       proto_item *blob_item;
+
                        /* guid */
                        /* XXX - show it in the standard Microsoft format
                           for GUIDs? */
@@ -2209,15 +2289,47 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                                tvb, offset, 16, TRUE);
                        COUNT_BYTES(16);
 
+                       blob_item = proto_tree_add_item(
+                               tree, hf_smb_security_blob,
+                               tvb, offset, bc, TRUE);
+
                        /* security blob */
-                       /* XXX - is this ASN.1-encoded?  Is it a Kerberos
-                          data structure, at least in NT 5.0-and-later
-                          server replies? */
+                       /* 
+                        * If Extended security and BCC == 16, then raw 
+                        * NTLMSSP is in use. We need to save this info
+                        */
                        if(bc){
-                               proto_tree_add_item(tree, hf_smb_security_blob,
-                                       tvb, offset, bc, TRUE);
+                               tvbuff_t *gssapi_tvb;
+                               proto_tree *gssapi_tree;
+
+                               gssapi_tree = proto_item_add_subtree(
+                                       blob_item, ett_smb_secblob);
+
+                               gssapi_tvb = tvb_new_subset(
+                                       tvb, offset, bc, bc);
+
+                               call_dissector(
+                                       gssapi_handle, gssapi_tvb, pinfo,
+                                       gssapi_tree);
+
+                               if (si->ct)
+                                 si->ct->raw_ntlmssp = 0;
+
                                COUNT_BYTES(bc);
                        }
+                       else { 
+
+                         /*
+                          * There is no blob. We just have to make sure
+                          * that subsequent routines know to call the 
+                          * right things ...
+                          */
+
+                         if (si->ct)
+                           si->ct->raw_ntlmssp = 1;
+
+                       }
                }
                break;
        }
@@ -2229,15 +2341,16 @@ 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, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int dn_len;
        const char *dn;
        guint8 wc;
        guint16 bc;
 
        WORD_COUNT;
+
        BYTE_COUNT;
 
        /* buffer format */
@@ -2246,7 +2359,7 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
        COUNT_BYTES(1);
 
        /* dir name */
-       dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
+       dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
                FALSE, FALSE, &bc);
        if (dn == NULL)
                goto endofcommand;
@@ -2264,13 +2377,13 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
 }
 
 static int
-dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
+
        WORD_COUNT;
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -2279,7 +2392,7 @@ dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, p
 }
 
 static int
-dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 ec, bc;
        guint8 wc;
@@ -2305,7 +2418,7 @@ dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
 }
 
 static int
-dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 bc;
        guint8 wc;
@@ -2330,15 +2443,16 @@ dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
 }
 
 static int
-dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_tree_connect_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 an_len, pwlen;
        const char *an;
        guint8 wc;
        guint16 bc;
 
        WORD_COUNT;
+
        BYTE_COUNT;
 
        /* buffer format */
@@ -2348,7 +2462,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
        /* Path */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_path, tvb,
@@ -2379,7 +2493,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
        /* Service */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_service, tvb,
@@ -2392,13 +2506,13 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 }
 
 static int
-dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
 
        WORD_COUNT;
+
        /* Maximum Buffer Size */
        proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
        offset += 2;
@@ -2413,7 +2527,7 @@ dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
 
        return offset;
 }
+
 
 static const true_false_string tfs_of_create = {
        "Create file if it does not exist",
@@ -2426,7 +2540,7 @@ static const value_string of_open[] = {
        {0, NULL}
 };
 static int
-dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -2454,7 +2568,7 @@ dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
 static const true_false_string tfs_mf_file = {
        "Target must be a file",
        "Target needn't be a file"
- };
+};
 static const true_false_string tfs_mf_dir = {
        "Target must be a directory",
        "Target needn't be a directory"
@@ -2464,7 +2578,7 @@ static const true_false_string tfs_mf_verify = {
        "Don't have to verify writes"
 };
 static int
-dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -2475,9 +2589,9 @@ dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, i
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
-               tree = proto_item_add_subtree(item, ett_smb_move_flags);
+               tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
        }
+
        proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
                tvb, offset, 2, mask);
        proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
@@ -2490,9 +2604,57 @@ dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, i
        return offset;
 }
 
+static const true_false_string tfs_cf_mode = {
+       "ASCII",
+       "Binary"
+};
+static const true_false_string tfs_cf_tree_copy = {
+       "Copy is a tree copy",
+       "Copy is a file copy"
+};
+static const true_false_string tfs_cf_ea_action = {
+       "Fail copy",
+       "Discard EAs"
+};
+static int
+dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint16 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       mask = tvb_get_letohs(tvb, offset);
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+                       "Flags: 0x%04x", mask);
+               tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
+       }
+
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
+               tvb, offset, 2, mask);
+
+       offset += 2;
+
+       return offset;
+}
+
 static int
-dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_move_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 fn_len;
        guint16 tid;
        guint16 bc;
@@ -2508,10 +2670,10 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        offset += 2;
 
        /* open function */
-       offset = dissect_open_function(tvb, pinfo, tree, offset);
+       offset = dissect_open_function(tvb, tree, offset);
 
        /* move flags */
-       offset = dissect_move_flags(tvb, pinfo, tree, offset);
+       offset = dissect_move_flags(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2521,7 +2683,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2539,7 +2701,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2557,8 +2719,76 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
 }
 
 static int
-dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_copy_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 fn_len;
+       guint16 tid;
+       guint16 bc;
+       guint8 wc;
+       const char *fn;
+
+       WORD_COUNT;
+
+       /* tid */
+       tid = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
+               "TID (target): 0x%04x", tid);
+       offset += 2;
+
+       /* open function */
+       offset = dissect_open_function(tvb, tree, offset);
+
+       /* copy flags */
+       offset = dissect_copy_flags(tvb, tree, offset);
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
+               fn_len, fn, "Source File Name: %s", fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
+       }
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
+               fn_len, fn, "Destination File Name: %s", fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -2567,7 +2797,7 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
        WORD_COUNT;
 
        /* # of files moved */
-       proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
+       proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
        offset += 2;
 
        BYTE_COUNT;
@@ -2578,7 +2808,7 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2592,8 +2822,9 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
 }
 
 static int
-dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_open_file_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -2602,10 +2833,10 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        WORD_COUNT;
 
        /* desired access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+       offset = dissect_access(tvb, tree, offset, "Desired");
 
        /* Search Attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2615,7 +2846,7 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2642,7 +2873,7 @@ add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
 }
 
 static int
-dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -2656,17 +2887,17 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
-       
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
+
        /* File Size */
        proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* granted access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+       offset = dissect_access(tvb, tree, offset, "Granted");
 
        BYTE_COUNT;
 
@@ -2676,7 +2907,7 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -2697,8 +2928,9 @@ dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, pro
 }
 
 static int
-dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_create_file_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -2707,10 +2939,10 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* creation time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
 
        BYTE_COUNT;
 
@@ -2720,7 +2952,7 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* File Name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2738,19 +2970,20 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
 
        BYTE_COUNT;
 
@@ -2760,8 +2993,9 @@ dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_delete_file_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -2770,7 +3004,7 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* search attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2780,7 +3014,7 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2798,8 +3032,9 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_rename_file_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -2808,7 +3043,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* search attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2818,7 +3053,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* old file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2836,7 +3071,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2854,24 +3089,52 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
-       guint16 bc;
-       guint8 wc;
-       const char *fn;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
+       const char *fn;
+       guint8 wc;
+       guint16 bc;
 
        WORD_COUNT;
 
+       /* search attributes */
+       offset = dissect_search_attributes(tvb, tree, offset);
+
+       proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+       offset += 2;
+
+       proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
+       offset += 4;
+
        BYTE_COUNT;
 
-       /* Buffer Format */
+       /* buffer format */
        CHECK_BYTE_COUNT(1);
        proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
        COUNT_BYTES(1);
 
-       /* File Name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       /* old file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
+               fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
+       }
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2880,46 +3143,84 @@ dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        COUNT_BYTES(fn_len);
 
        if (check_col(pinfo->cinfo, COL_INFO)) {
-               col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
        }
 
        END_OF_SMB
 
        return offset;
 }
+
+
 static int
-dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        guint16 bc;
        guint8 wc;
+       const char *fn;
+       int fn_len;
 
        WORD_COUNT;
 
-       /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
-
-       /* Last Write Time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
-
-       /* File Size */
-       proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
-       offset += 4;
-
-       /* 10 reserved bytes */
-       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
-       offset += 10;
-
        BYTE_COUNT;
 
-       END_OF_SMB
+       /* Buffer Format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* File Name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+               fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       /* File Attributes */
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
+
+       /* Last Write Time */
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
+
+       /* File Size */
+       proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
+       offset += 4;
+
+       /* 10 reserved bytes */
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
+       offset += 10;
+
+       BYTE_COUNT;
+
+       END_OF_SMB
 
        return offset;
 }
 
 static int
-dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_set_information_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -2928,10 +3229,10 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
 
        /* 10 reserved bytes */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
@@ -2945,7 +3246,7 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2963,25 +3264,41 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 }
 
 static int
-dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 cnt=0, bc;
+       guint32 ofs=0;
+       smb_info_t *si;
+       unsigned int fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
+       if (!pinfo->fd->flags.visited) {
+               /* remember the FID for the processing of the response */
+               si = (smb_info_t *)pinfo->private_data;
+               si->sip->extra_info=(void *)fid;
+       }
 
        /* read count */
+       cnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
        offset += 2;
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s at offset %u", cnt,
+                               (cnt == 1) ? "" : "s", ofs);
+
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
        offset += 2;
@@ -2994,7 +3311,7 @@ dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 }
 
 int
-dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
+dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
 {
        int tvblen;
 
@@ -3018,10 +3335,37 @@ dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
 }
 
 static int
-dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+    proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
+{
+       int tvblen;
+       tvbuff_t *dcerpc_tvb;
+
+       if(bc>datalen){
+               /* We have some initial padding bytes. */
+               /* XXX - use the data offset here instead? */
+               proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
+                       TRUE);
+               offset += bc-datalen;
+               bc = datalen;
+       }
+       tvblen = tvb_length_remaining(tvb, offset);
+       dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
+       dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
+       if(bc>tvblen)
+               offset += tvblen;
+       else
+               offset += bc;
+       return offset;
+}
+
+static int
+dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 cnt=0, bc;
        guint8 wc;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       int fid=0;
 
        WORD_COUNT;
 
@@ -3034,6 +3378,13 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        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){
+               fid=(int)si->sip->extra_info;
+               add_fid(tvb, pinfo, tree, 0, 0, fid);
+       }
+
        BYTE_COUNT;
 
        /* buffer format */
@@ -3046,9 +3397,19 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
        COUNT_BYTES(2);
 
-       if (bc != 0) {
-               /* file data */
-               offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
+       /* another way to transport DCERPC over SMB is to skip Transaction completely and just
+          read write */
+       if(bc){
+               if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, bc, fid);
+               } else {
+                       /* ordinary file data, or we didn't see the request,
+                          so we don't know whether this is a DCERPC call
+                          or not */
+                       offset = dissect_file_data(tvb, tree, offset, bc, bc);
+               }
                bc = 0;
        }
 
@@ -3058,7 +3419,7 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 cnt, bc;
        guint8 wc;
@@ -3093,15 +3454,18 @@ dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 
 static int
-dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
-       guint16 cnt=0, bc;
+       guint32 ofs=0;
+       guint16 cnt=0, bc, fid=0;
        guint8 wc;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* write count */
@@ -3110,9 +3474,15 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s at offset %u", cnt,
+                               (cnt == 1) ? "" : "s", ofs);
+
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
        offset += 2;
@@ -3130,8 +3500,14 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(2);
 
        if (bc != 0) {
-               /* file data */
-               offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
+               if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, bc, fid);
+               } else {
+                       /* ordinary file data */
+                       offset = dissect_file_data(tvb, tree, offset, bc, bc);
+               }
                bc = 0;
        }
 
@@ -3139,19 +3515,24 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        return offset;
 }
+
 static int
-dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, cnt;
 
        WORD_COUNT;
 
        /* write count */
+       cnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -3160,15 +3541,16 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* lock count */
@@ -3187,8 +3569,9 @@ dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
 }
 
 static int
-dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_create_temporary_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -3201,7 +3584,7 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        offset += 2;
 
        /* Creation time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
 
        BYTE_COUNT;
 
@@ -3211,7 +3594,7 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        COUNT_BYTES(1);
 
        /* directory name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -3229,13 +3612,13 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 static int
-dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
-       guint16 bc;
-       guint16 fid;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
@@ -3252,7 +3635,7 @@ dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -3273,15 +3656,16 @@ static const value_string seek_mode_vals[] = {
 };
 
 static int
-dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* Seek Mode */
@@ -3300,7 +3684,7 @@ dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 }
 
 static int
-dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3317,31 +3701,32 @@ dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        return offset;
 }
+
 static int
-dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* create time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
 
        /* access time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
 
        /* last write time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
 
@@ -3353,7 +3738,7 @@ dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 static int
-dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3361,17 +3746,17 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        WORD_COUNT;
 
        /* create time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
 
        /* access time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
 
        /* last write time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
 
@@ -3384,7 +3769,7 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        offset += 4;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        BYTE_COUNT;
 
@@ -3394,16 +3779,17 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
 }
 
 static int
-dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 cnt=0;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* write count */
@@ -3416,8 +3802,8 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 4;
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
-       
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
+
        if(wc==12){
                /* 12 reserved bytes */
                proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
@@ -3430,17 +3816,17 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        CHECK_BYTE_COUNT(1);
        proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
        COUNT_BYTES(1);
-       
-       offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
+
+       offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
        bc = 0; /* XXX */
 
        END_OF_SMB
 
        return offset;
 }
+
 static int
-dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3459,16 +3845,17 @@ dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 static int
-dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
        guint32 to;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* offset */
@@ -3506,7 +3893,7 @@ dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 }
 
 static int
-dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3541,15 +3928,16 @@ dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto
 }
 
 static int
-dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* offset */
@@ -3576,7 +3964,7 @@ dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 }
 
 static int
-dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 datalen=0, bc;
        guint8 wc;
@@ -3615,7 +4003,7 @@ dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        BYTE_COUNT;
 
        /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
        bc = 0;
 
        END_OF_SMB
@@ -3645,7 +4033,7 @@ static const true_false_string tfs_write_mode_connectionless = {
        "Connectionless mode NOT requested"
 };
 static int
-dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
+dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -3685,16 +4073,17 @@ dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, i
 }
 
 static int
-dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint32 to;
-       guint16 datalen=0, bc;
+       guint16 datalen=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* total data length */
@@ -3715,7 +4104,7 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 4;
 
        /* mode */
-       offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
+       offset = dissect_write_mode(tvb, tree, offset, 0x0003);
 
        /* 4 reserved bytes */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
@@ -3734,16 +4123,16 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 
        /* file data */
        /* XXX - use the data offset to determine where the data starts? */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
        bc = 0;
 
        END_OF_SMB
 
        return offset;
 }
+
 static int
-dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3762,16 +4151,17 @@ dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint32 to;
-       guint16 datalen=0, bc;
+       guint16 datalen=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* total data length */
@@ -3792,12 +4182,12 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 4;
 
        /* mode */
-       offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
+       offset = dissect_write_mode(tvb, tree, offset, 0x0083);
 
        /* request mask */
        proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
        offset += 4;
-       
+
        /* data len */
        datalen = tvb_get_letohs(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
@@ -3811,16 +4201,16 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 
        /* file data */
        /* XXX - use the data offset to determine where the data starts? */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
        bc = 0;
 
        END_OF_SMB
 
        return offset;
 }
+
 static int
-dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3830,7 +4220,7 @@ dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* response mask */
        proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
        offset += 4;
-       
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -3839,7 +4229,7 @@ dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3859,10 +4249,12 @@ dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, pro
 
 static int
 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
+    proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
+    gboolean has_find_id)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        char fname[11+1];
@@ -3880,7 +4272,7 @@ dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
 
        /* file name */
        fn_len = 11;
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                TRUE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        /* ensure that it's null-terminated */
@@ -3890,10 +4282,21 @@ dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
                fname);
        COUNT_BYTES_SUBR(fn_len);
 
-       /* server cookie */
-       CHECK_BYTE_COUNT_SUBR(5);
-       proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
-       COUNT_BYTES_SUBR(5);
+       if (has_find_id) {
+               CHECK_BYTE_COUNT_SUBR(1);
+               proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
+               COUNT_BYTES_SUBR(1);
+
+               /* server cookie */
+               CHECK_BYTE_COUNT_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
+               COUNT_BYTES_SUBR(4);
+       } else {
+               /* server cookie */
+               CHECK_BYTE_COUNT_SUBR(5);
+               proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
+               COUNT_BYTES_SUBR(5);
+       }
 
        /* client cookie */
        CHECK_BYTE_COUNT_SUBR(4);
@@ -3906,10 +4309,12 @@ dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
 
 static int
 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
+    proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
+    gboolean has_find_id)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        char fname[13+1];
@@ -3921,18 +4326,19 @@ dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
        }
 
        /* resume key */
-       offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
+       offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
+           trunc, has_find_id);
        if (*trunc)
                return offset;
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(1);
-       offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_dir_info_file_attributes(tvb, tree, offset);
        *bcp -= 1;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
                TRUE);
@@ -3945,7 +4351,7 @@ dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
 
        /* file name */
        fn_len = 13;
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                TRUE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        /* ensure that it's null-terminated */
@@ -3961,8 +4367,11 @@ dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
 
 
 static int
-dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_,
+    gboolean has_find_id)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint16 rkl;
@@ -3977,7 +4386,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* Search Attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -3987,7 +4396,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                TRUE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -4013,7 +4422,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* resume key */
        if(rkl){
                offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
-                   &bc, &trunc);
+                   &bc, &trunc, has_find_id);
                if (trunc)
                        goto endofcommand;
        }
@@ -4024,7 +4433,33 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_request(tvb, pinfo, tree, offset,
+           smb_tree, FALSE);
+}
+
+static int
+dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_request(tvb, pinfo, tree, offset,
+           smb_tree, TRUE);
+}
+
+static int
+dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_request(tvb, pinfo, tree, offset,
+           smb_tree, TRUE);
+}
+
+static int
+dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_,
+    gboolean has_find_id)
 {
        guint16 count=0;
        guint8 wc;
@@ -4052,7 +4487,7 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        while(count--){
                offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
-                   &bc, &trunc);
+                   &bc, &trunc, has_find_id);
                if (trunc)
                        goto endofcommand;
        }
@@ -4062,6 +4497,59 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        return offset;
 }
 
+static int
+dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
+           FALSE);
+}
+
+static int
+dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
+           TRUE);
+}
+
+static int
+dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint8 wc;
+       guint16 bc;
+       guint16 data_len;
+
+       WORD_COUNT;
+
+       /* reserved */
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* data len */
+       CHECK_BYTE_COUNT(2);
+       data_len = tvb_get_ntohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
+       COUNT_BYTES(2);
+
+       if (data_len != 0) {
+               CHECK_BYTE_COUNT(data_len);
+               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
+                   data_len, TRUE);
+               COUNT_BYTES(data_len);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
 static const value_string locking_ol_vals[] = {
        {0,     "Client is not holding oplock on this file"},
        {1,     "Level 2 oplock currently held by client"},
@@ -4089,10 +4577,10 @@ static const true_false_string tfs_lock_type_shared = {
        "This is an exclusive lock"
 };
 static int
-dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+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;
+       guint16 andxoffset=0, un=0, ln=0, bc, fid;
        guint32 to;
        proto_item *litem = NULL;
        proto_tree *ltree = NULL;
@@ -4121,7 +4609,8 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        offset += 2;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* lock type */
@@ -4184,7 +4673,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                                litem = proto_tree_add_text(tr, tvb, offset, 20,
                                        "Unlock");
                                ltree = proto_item_add_subtree(litem, ett_smb_unlock);
-                               
+
                                /* PID */
                                CHECK_BYTE_COUNT(2);
                                proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
@@ -4209,7 +4698,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                                litem = proto_tree_add_text(tr, tvb, offset, 10,
                                        "Unlock");
                                ltree = proto_item_add_subtree(litem, ett_smb_unlock);
-                               
+
                                /* PID */
                                CHECK_BYTE_COUNT(2);
                                proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
@@ -4245,7 +4734,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                                litem = proto_tree_add_text(tr, tvb, offset, 20,
                                        "Lock");
                                ltree = proto_item_add_subtree(litem, ett_smb_lock);
-                               
+
                                /* PID */
                                CHECK_BYTE_COUNT(2);
                                proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
@@ -4270,7 +4759,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                                litem = proto_tree_add_text(tr, tvb, offset, 10,
                                        "Unlock");
                                ltree = proto_item_add_subtree(litem, ett_smb_unlock);
-                               
+
                                /* PID */
                                CHECK_BYTE_COUNT(2);
                                proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
@@ -4303,13 +4792,13 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        }
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
 
 static int
-dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0;
@@ -4340,7 +4829,7 @@ dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4358,7 +4847,7 @@ static const true_false_string tfs_oa_lock = {
        "File is opened by another user (or mode not supported by server)"
 };
 static int
-dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4399,7 +4888,7 @@ static const true_false_string tfs_open_flags_ealen = {
        "Total length of EAs not requested"
 };
 static int
-dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
+dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4447,6 +4936,7 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 {
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
@@ -4471,22 +4961,22 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 2;
 
        /* open flags */
-       offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
+       offset = dissect_open_flags(tvb, tree, offset, 0x0007);
 
        /* desired access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+       offset = dissect_access(tvb, tree, offset, "Desired");
 
        /* Search Attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* creation time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
-       
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
+
        /* open function */
-       offset = dissect_open_function(tvb, pinfo, tree, offset);
+       offset = dissect_open_function(tvb, tree, offset);
 
        /* allocation size */
        proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
@@ -4499,7 +4989,7 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        BYTE_COUNT;
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -4514,7 +5004,7 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4540,8 +5030,8 @@ static const value_string ipc_state_read_mode_vals[] = {
 };
 
 int
-dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
-    int offset, gboolean setstate)
+dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+    gboolean setstate)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4608,27 +5098,27 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
-       
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
+
        /* File Size */
        proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* granted access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+       offset = dissect_access(tvb, tree, offset, "Granted");
 
        /* File Type */
        proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
        offset += 2;
 
        /* IPC State */
-       offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+       offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
        /* open_action */
-       offset = dissect_open_action(tvb, pinfo, tree, offset);
+       offset = dissect_open_action(tvb, tree, offset);
 
        /* server fid */
        proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
@@ -4643,7 +5133,7 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4652,7 +5142,8 @@ static int
 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
-       guint16 andxoffset=0, bc;
+       guint16 andxoffset=0, bc, maxcnt = 0;
+       guint32 ofs = 0;
        smb_info_t *si;
        unsigned int fid;
 
@@ -4687,13 +5178,20 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        }
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* max count */
+       maxcnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       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);
+
        /* min count */
        proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
        offset += 2;
@@ -4717,7 +5215,7 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4728,6 +5226,7 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
        smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       int fid=0;
 
        WORD_COUNT;
 
@@ -4739,7 +5238,7 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
        }
        offset += 1;
+
        /* reserved byte */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
        offset += 1;
@@ -4752,7 +5251,8 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* 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){
-               add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
+               fid=(int)si->sip->extra_info;
+               add_fid(tvb, pinfo, tree, 0, 0, fid);
        }
 
        /* remaining */
@@ -4772,6 +5272,11 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s", datalen,
+                               (datalen == 1) ? "" : "s");
+
        /* data offset */
        dataoffset=tvb_get_letohs(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
@@ -4787,11 +5292,13 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* is this part of DCERPC over SMB reassembly?*/
        if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
            && (bc<=tvb_length_remaining(tvb, offset)) ){
-               guint32 frame;
-               if (si->sip != NULL && (frame=(guint32)g_hash_table_lookup(
+               gpointer hash_value;
+               if (si->sip != NULL && (hash_value = g_hash_table_lookup(
                                                si->ct->dcerpc_fid_to_frame,
                                                si->sip->extra_info)) != NULL) {
                        fragment_data *fd_head;
+                       guint32 frame = GPOINTER_TO_UINT(hash_value);
+
                        /* first fragment is always from a SMB Trans command and
                           offset 0 of the following read/write SMB commands start
                           BEYOND the first Trans SMB payload. Look for offset
@@ -4810,26 +5317,38 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                }
                                fd_head=fragment_add(tvb, dataoffset, pinfo,
                                        frame, dcerpc_fragment_table,
-                                       fd_head->offset+fd_head->len, 
+                                       fd_head->offset+fd_head->len,
                                        datalen, TRUE);
-                               /* we completed reassembly, abort searching for more 
+                               /* we completed reassembly, abort searching for more
                                   fragments*/
                                if(fd_head){
                                        g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
-                                               si->sip->extra_info);   
+                                               si->sip->extra_info);
                                }
                        }
                }
        }
 
-       /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
-       bc = 0;
+       /* another way to transport DCERPC over SMB is to skip Transaction completely and just
+          read write */
+       if(bc){
+               if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, datalen, fid);
+               } else {
+                       /* ordinary file data, or we didn't see the request,
+                          so we don't know whether this is a DCERPC call
+                          or not */
+                       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
+               }
+               bc = 0;
+       }
 
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4837,10 +5356,11 @@ 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, datalen=0, dataoffset=0;
        smb_info_t *si = (smb_info_t *)pinfo->private_data;
-       unsigned int fid;
+       unsigned int fid=0;
 
        WORD_COUNT;
 
@@ -4872,6 +5392,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
@@ -4880,7 +5401,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 4;
 
        /* mode */
-       offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
+       offset = dissect_write_mode(tvb, tree, offset, 0x000f);
 
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
@@ -4900,6 +5421,12 @@ 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 */
                proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
@@ -4910,11 +5437,13 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* is this part of DCERPC over SMB reassembly?*/
        if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
-               guint32 frame;
-               frame=(guint32)g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
+               gpointer hash_value;
+               hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
                        si->sip->extra_info);
-               if(frame){
+               if(hash_value){
                        fragment_data *fd_head;
+                       guint32 frame = GPOINTER_TO_UINT(hash_value);
+
                        /* first fragment is always from a SMB Trans command and
                           offset 0 of the following read/write SMB commands start
                           BEYOND the first Trans SMB payload. Look for offset
@@ -4933,26 +5462,36 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                }
                                fd_head=fragment_add(tvb, dataoffset, pinfo,
                                        frame, dcerpc_fragment_table,
-                                       fd_head->offset+fd_head->len, 
+                                       fd_head->offset+fd_head->len,
                                        datalen, TRUE);
-                               /* we completed reassembly, abort searching for more 
+                               /* we completed reassembly, abort searching for more
                                   fragments*/
                                if(fd_head){
                                        g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
-                                               si->sip->extra_info);   
+                                               si->sip->extra_info);
                                }
                        }
                }
        }
 
        /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
-       bc = 0;
+       if (bc != 0) {
+               if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, datalen, fid);
+               } else {
+                       /* ordinary file data */
+                       offset = dissect_file_data(tvb, tree, offset,
+                           bc, datalen);
+               }
+               bc = 0;
+       }
 
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4961,7 +5500,7 @@ static int
 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
-       guint16 andxoffset=0, bc;
+       guint16 andxoffset=0, bc, datalen=0;
        smb_info_t *si;
 
        WORD_COUNT;
@@ -4974,7 +5513,7 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
        }
        offset += 1;
+
        /* reserved byte */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
        offset += 1;
@@ -4992,9 +5531,15 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* write count */
+       datalen = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s", datalen,
+                               (datalen == 1) ? "" : "s");
+
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
        offset += 2;
@@ -5008,7 +5553,7 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5019,7 +5564,7 @@ static const true_false_string tfs_setup_action_guest = {
        "Not logged in as GUEST"
 };
 static int
-dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -5040,7 +5585,7 @@ dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        return offset;
 }
+
 
 static int
 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
@@ -5048,6 +5593,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        guint8  wc, cmd=0xff;
        guint16 bc;
        guint16 andxoffset=0;
+       smb_info_t *si = pinfo->private_data;
        int an_len;
        const char *an;
        int dn_len;
@@ -5117,7 +5663,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                offset += 4;
 
                /* capabilities */
-               dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+               dissect_negprot_capabilities(tvb, tree, offset);
                offset += 4;
 
                break;
@@ -5140,7 +5686,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                offset += 4;
 
                /* capabilities */
-               dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+               dissect_negprot_capabilities(tvb, tree, offset);
                offset += 4;
 
                break;
@@ -5149,20 +5695,50 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        BYTE_COUNT;
 
        if (wc==12) {
+               proto_item *blob_item;
+
                /* security blob */
-               /* XXX - is this ASN.1-encoded?  Is it a Kerberos
-                  data structure, at least in NT 5.0-and-later
-                  server replies? */
+
+               blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
+                                               tvb, offset, sbloblen, TRUE);
+
+               /* As an optimization, because Windows is perverse,
+                  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
+                  a client that wraps NTLMSSP in SPNEGO
+               */
+
                if(sbloblen){
-                       CHECK_BYTE_COUNT(sbloblen);
-                       proto_tree_add_item(tree, hf_smb_security_blob,
-                               tvb, offset, sbloblen, TRUE);
+                       tvbuff_t *blob_tvb;
+                       proto_tree *blob_tree;
+
+                       blob_tree = proto_item_add_subtree(blob_item, 
+                                                          ett_smb_secblob);
+                        CHECK_BYTE_COUNT(sbloblen);
+
+                       blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
+                                                 sbloblen);
+
+                       if (si && si->ct && si->ct->raw_ntlmssp && 
+                           !strncmp("NTLMSSP", 
+                                    tvb_get_ptr(tvb, offset, 7), 7)) {
+                         call_dissector(ntlmssp_handle, blob_tvb, pinfo,
+                                        blob_tree);
+
+                       }
+                       else {
+                         call_dissector(gssapi_handle, blob_tvb, 
+                                        pinfo, blob_tree);
+                       }
+
                        COUNT_BYTES(sbloblen);
                }
 
                /* OS */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_os, tvb,
@@ -5177,7 +5753,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                 * because the bug didn't appear to get fixed until NT 5.0....
                 */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_lanman, tvb,
@@ -5190,7 +5766,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                 * ASCII and the account name is empty. Another bug?
                 */
                dn = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &dn_len, FALSE, FALSE, &bc);
+                       si->unicode, &dn_len, FALSE, FALSE, &bc);
                if (dn == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
@@ -5203,7 +5779,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                        if(pwlen){
                                /* password, ASCII */
                                CHECK_BYTE_COUNT(pwlen);
-                               proto_tree_add_item(tree, hf_smb_password, 
+                               proto_tree_add_item(tree, hf_smb_password,
                                        tvb, offset, pwlen, TRUE);
                                COUNT_BYTES(pwlen);
                        }
@@ -5214,7 +5790,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                        if(apwlen){
                                /* password, ANSI */
                                CHECK_BYTE_COUNT(apwlen);
-                               proto_tree_add_item(tree, hf_smb_ansi_password, 
+                               proto_tree_add_item(tree, hf_smb_ansi_password,
                                        tvb, offset, apwlen, TRUE);
                                COUNT_BYTES(apwlen);
                        }
@@ -5222,7 +5798,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                        if(upwlen){
                                /* password, Unicode */
                                CHECK_BYTE_COUNT(upwlen);
-                               proto_tree_add_item(tree, hf_smb_unicode_password, 
+                               proto_tree_add_item(tree, hf_smb_unicode_password,
                                        tvb, offset, upwlen, TRUE);
                                COUNT_BYTES(upwlen);
                        }
@@ -5232,7 +5808,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
                /* Account Name */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
@@ -5245,7 +5821,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                 * ASCII and the account name is empty. Another bug?
                 */
                dn = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &dn_len, FALSE, FALSE, &bc);
+                       si->unicode, &dn_len, FALSE, FALSE, &bc);
                if (dn == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
@@ -5253,13 +5829,19 @@ 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: %s@%s",
-                       an,dn);
+                       col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
+
+                       if (!dn[0] && !an[0])
+                               col_append_fstr(pinfo->cinfo, COL_INFO,
+                                               "anonymous");
+                       else
+                               col_append_fstr(pinfo->cinfo, COL_INFO,
+                                               "%s\\%s", dn,an);
                }
 
                /* OS */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_os, tvb,
@@ -5274,7 +5856,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                 * because the bug didn't appear to get fixed until NT 5.0....
                 */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_lanman, tvb,
@@ -5285,7 +5867,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5296,6 +5878,7 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc;
        guint16 sbloblen=0;
+       smb_info_t *si = pinfo->private_data;
        int an_len;
        const char *an;
 
@@ -5320,7 +5903,7 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        offset += 2;
 
        /* flags */
-       offset = dissect_setup_action(tvb, pinfo, tree, offset);
+       offset = dissect_setup_action(tvb, tree, offset);
 
        if(wc==4){
                /* security blob length */
@@ -5332,21 +5915,44 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        BYTE_COUNT;
 
        if(wc==4) {
+               proto_item *blob_item;
+
                /* security blob */
-               /* XXX - is this ASN.1-encoded?  Is it a Kerberos
-                  data structure, at least in NT 5.0-and-later
-                  server replies? */
+
+               blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
+                                               tvb, offset, sbloblen, TRUE);
+
                if(sbloblen){
-                       CHECK_BYTE_COUNT(sbloblen);
-                       proto_tree_add_item(tree, hf_smb_security_blob,
-                               tvb, offset, sbloblen, TRUE);
-                       COUNT_BYTES(sbloblen);
-               }
-       }
+                       tvbuff_t *blob_tvb;
+                       proto_tree *blob_tree;
 
-       /* OS */
+                       blob_tree = proto_item_add_subtree(blob_item, 
+                                                          ett_smb_secblob);
+                        CHECK_BYTE_COUNT(sbloblen);
+
+                       blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
+                                                   sbloblen);
+
+                       if (si && si->ct && si->ct->raw_ntlmssp && 
+                           !strncmp("NTLMSSP", 
+                                    tvb_get_ptr(tvb, offset, 7), 7)) {
+                         call_dissector(ntlmssp_handle, blob_tvb, pinfo,
+                                        blob_tree);
+
+                       }
+                       else {
+                         call_dissector(gssapi_handle, blob_tvb, pinfo, 
+                                        blob_tree);
+
+                       }
+
+                        COUNT_BYTES(sbloblen);
+               }
+       }
+
+       /* OS */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_os, tvb,
@@ -5355,7 +5961,7 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
 
        /* LANMAN */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_lanman, tvb,
@@ -5365,7 +5971,7 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        if(wc==3) {
                /* Primary domain */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
@@ -5376,12 +5982,12 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
 
+
 static int
 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
@@ -5414,12 +6020,12 @@ dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offs
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
 
+
 static const true_false_string tfs_connect_support_search = {
        "Exclusive search bits supported",
        "Exclusive search bits not supported"
@@ -5430,7 +6036,7 @@ static const true_false_string tfs_connect_support_in_dfs = {
 };
 
 static int
-dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -5460,7 +6066,7 @@ static const true_false_string tfs_disconnect_tid = {
 };
 
 static int
-dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -5488,6 +6094,7 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        guint8  wc, cmd=0xff;
        guint16 bc;
        guint16 andxoffset=0, pwlen=0;
+       smb_info_t *si = pinfo->private_data;
        int an_len;
        const char *an;
 
@@ -5512,7 +6119,7 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        offset += 2;
 
        /* flags */
-       offset = dissect_connect_flags(tvb, pinfo, tree, offset);
+       offset = dissect_connect_flags(tvb, tree, offset);
 
        /* password length*/
        pwlen = tvb_get_letohs(tvb, offset);
@@ -5523,13 +6130,13 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
        /* password */
        CHECK_BYTE_COUNT(pwlen);
-       proto_tree_add_item(tree, hf_smb_password, 
+       proto_tree_add_item(tree, hf_smb_password,
                tvb, offset, pwlen, TRUE);
        COUNT_BYTES(pwlen);
 
        /* Path */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_path, tvb,
@@ -5558,7 +6165,7 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5572,6 +6179,7 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        guint16 bc;
        int an_len;
        const char *an;
+       smb_info_t *si = pinfo->private_data;
 
        WORD_COUNT;
 
@@ -5603,7 +6211,7 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                goto bytecount;
 
        /* flags */
-       offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
+       offset = dissect_connect_support_bits(tvb, tree, offset);
        wleft--;
 
        /* XXX - I've seen captures where this is 7, but I have no
@@ -5649,6 +6257,21 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                offset, an_len, an);
        COUNT_BYTES(an_len);
 
+       /* Now when we know the service type, store it so that we know it for later commands down
+          this tree */
+       if(!pinfo->fd->flags.visited){
+               /* Remove any previous entry for this TID */
+               if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
+                       g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
+               }
+               if(strcmp(an,"IPC") == 0){
+                       g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
+               } else {
+                       g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
+               }
+       }
+
+
        if(wc==3){
                if (bc != 0) {
                        /*
@@ -5657,7 +6280,8 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
                        /* Native FS */
                        an = get_unicode_or_ascii_string(tvb, &offset,
-                               pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
+                               si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
+                               &bc);
                        if (an == NULL)
                                goto endofcommand;
                        proto_tree_add_string(tree, hf_smb_fs, tvb,
@@ -5669,7 +6293,7 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5685,13 +6309,17 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 #define NT_TRANS_NOTIFY                4
 #define NT_TRANS_RENAME                5
 #define NT_TRANS_QSD           6
+#define NT_TRANS_GET_USER_QUOTA        7
+#define NT_TRANS_SET_USER_QUOTA 8
 static const value_string nt_cmd_vals[] = {
-       {NT_TRANS_CREATE,       "NT CREATE"},
-       {NT_TRANS_IOCTL,        "NT IOCTL"},
-       {NT_TRANS_SSD,          "NT SET SECURITY DESC"},
-       {NT_TRANS_NOTIFY,       "NT NOTIFY"},
-       {NT_TRANS_RENAME,       "NT RENAME"},
-       {NT_TRANS_QSD,          "NT QUERY SECURITY DESC"},
+       {NT_TRANS_CREATE,               "NT CREATE"},
+       {NT_TRANS_IOCTL,                "NT IOCTL"},
+       {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
+       {NT_TRANS_NOTIFY,               "NT NOTIFY"},
+       {NT_TRANS_RENAME,               "NT RENAME"},
+       {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
+       {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
+       {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
        {0, NULL}
 };
 
@@ -5924,7 +6552,7 @@ static const true_false_string tfs_nt_share_access_write = {
 };
 static const true_false_string tfs_nt_share_access_read = {
        "Object can be shared for READ",
-       "Object can NOT be shared for delete"
+       "Object can NOT be shared for read"
 };
 
 static const value_string oplock_level_vals[] = {
@@ -5998,7 +6626,7 @@ typedef struct _nt_trans_data {
 
 
 static int
-dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -6023,7 +6651,7 @@ dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
 }
 
 static int
-dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6051,7 +6679,7 @@ dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
 
 
 static int
-dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6066,7 +6694,7 @@ dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tre
        }
 
        /*
-        * Some of these bits come from 
+        * Some of these bits come from
         *
         *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
         *
@@ -6120,7 +6748,7 @@ dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tre
 }
 
 static int
-dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6211,7 +6839,7 @@ static const true_false_string tfs_nt_create_options_delete_on_close = {
 };
 
 static int
-dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6255,9 +6883,9 @@ dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
 
        return offset;
 }
+
 static int
-dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6270,7 +6898,7 @@ dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tre
                        "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,
@@ -6299,9 +6927,9 @@ dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        offset += 4;
        return offset;
 }
+
 static int
-dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -6352,7 +6980,7 @@ static const true_false_string tfs_nt_qsd_sacl = {
 #define NT_QSD_SACL    0x00000008
 
 static int
-dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6380,16 +7008,24 @@ dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        return offset;
 }
 
+static void
+free_g_string(void *arg)
+{
+       g_string_free(arg, TRUE);
+}
+
 int
-dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
+dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
-       int old_offset = offset;
+       int old_offset = offset, sa_offset = offset;
+       guint rid;
        guint8 revision;
        guint8 num_auth;
+        guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
        int i;
-       char str[256], *strp;
+       GString *gstr;
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, -1,
@@ -6403,7 +7039,8 @@ dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
        offset += 1;
 
        switch(revision){
-       case 1:  /*only revision of SOD we will se ?*/
+       case 1:
+       case 2:  /* Not sure what the different revision numbers mean */
          /* number of authorities*/
          num_auth = tvb_get_guint8(tvb, offset);
          proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
@@ -6412,34 +7049,51 @@ dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
          /* XXX perhaps we should have these thing searchable?
             a new FT_xxx thingie? SMB is quite common!*/
          /* identifier authorities */
-         strp=str;
-         strcpy(strp, "S-1-");
-
-         proto_tree_add_text(tree, tvb, offset, 6, "Authorities");
 
          for(i=0;i<6;i++){
-           guint8 auth = tvb_get_guint8(tvb, offset);
+           auth = (auth << 8) + tvb_get_guint8(tvb, offset);
 
-           if (auth > 0)
-             sprintf(strp,"%s%d-",strp, auth);
            offset++;
          }
 
-         proto_tree_add_text(tree, tvb, offset, num_auth * 4, "Sub-authorities");
+         proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
+
+          sa_offset = offset;
+
+          gstr = g_string_new("");
+
+         CLEANUP_PUSH(free_g_string, gstr);
+
+         /* sub authorities, leave RID to last */
+         for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
+           /*
+            * XXX should not be letohl but native byteorder according to
+            * Samba header files.
+            *
+            * However, considering that there were never any NT ports
+            * to big-endian platforms (PowerPC and MIPS ran little-endian,
+            * and IA-64 runs little-endian, as does x86-64), we can (?)
+            * assume that non le byte encodings will be "uncommon"?
+            */
+             g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
+                  tvb_get_letohl(tvb, offset));
+             offset+=4;
+         }
+
+          proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
 
-         /* sub authorities */
-         for(i=0;i<num_auth;i++){
-           /* XXX should not be letohl but native byteorder according to
-              samba header files. considering that all non-x86 NT ports
-              are dead we can (?) assume that non le byte encodings
-              will be "uncommon"?*/
-           sprintf(strp,"%s%d-",strp,tvb_get_letohl(tvb, offset));
+         if (num_auth > 4) {
+           rid = tvb_get_letohl(tvb, offset);
+           proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
+           proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
            offset+=4;
          }
-         /* strip trailing '-'*/
-         str[strlen(str)-1]=0;
+         else {
+           proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);
+         }
+
+         CLEANUP_CALL_AND_POP;
 
-         proto_item_append_text(item, ": %s", str);  
        }
 
        proto_item_set_len(item, offset-old_offset);
@@ -6484,51 +7138,54 @@ static const true_false_string tfs_ace_flags_failed_access = {
 };
 
 #define APPEND_ACE_TEXT(flag, item, string) \
-        if(item && flag){                                     \
-                  proto_item_append_text(item, string);       \
-        }
+       if(flag){                                                       \
+               if(item)                                                \
+                       proto_item_append_text(item, string, sep);      \
+               sep = ", ";                                             \
+       }
 
 static int
-dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
+dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        guint8 mask;
+       char *sep = " ";
 
        mask = tvb_get_guint8(tvb, offset);
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
-                                          "NT ACE Flags:0x%02x", mask);
+                                          "NT ACE Flags: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_ace_flags);
        }
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x80, item, "  Failed Access,");
+       APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x40, item, "  Successful Access,");
+       APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x10, item, "  Inherited ACE,");
+       APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x08, item, "  Inherit Only,");
+       APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x04, item, "  No Propagate Inherit,");
+       APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x02, item, "  Container Inherit,");
+       APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x01, item, "  Object Inherit,");
+       APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
 
 
        offset += 1;
@@ -6536,12 +7193,13 @@ dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tre
 }
 
 static int
-dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
+dissect_nt_v2_ace(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        int old_offset = offset;
-       
+       guint16 size;
+
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, -1,
                                           "NT ACE: ");
@@ -6556,29 +7214,34 @@ dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *par
        offset += 1;
 
        /* flags */
-       offset = dissect_nt_v2_ace_flags(tvb, pinfo, offset, tree);
+       offset = dissect_nt_v2_ace_flags(tvb, offset, tree);
 
        /* size */
-       proto_tree_add_item(tree, hf_smb_ace_size, tvb, offset, 2, TRUE);
+       size = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
        offset += 2;
 
        /* access mask */
-       offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+       offset = dissect_nt_access_mask(tvb, tree, offset);
 
        /* SID */
-       offset = dissect_nt_sid(tvb, pinfo, offset, tree, "ACE");
+       offset = dissect_nt_sid(tvb, offset, tree, "ACE");
 
        proto_item_set_len(item, offset-old_offset);
-       return offset;
+
+       /* Sometimes there is some spare space at the end of the ACE so use
+          the size field to work out where the end is. */
+
+       return old_offset + size;
 }
 
 static int
-dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
+dissect_nt_acl(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        int old_offset = offset;
-       guint16 revision, size;
+       guint16 revision;
        guint32 num_aces;
 
        if(parent_tree){
@@ -6595,6 +7258,7 @@ dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
 
        switch(revision){
        case 2:  /* only version we will ever see of this structure?*/
+       case 3:
          /* size */
          proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
          offset += 2;
@@ -6606,7 +7270,7 @@ dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
          offset += 4;
 
          while(num_aces--){
-           offset=dissect_nt_v2_ace(tvb, pinfo, offset, tree);
+           offset=dissect_nt_v2_ace(tvb, offset, tree);
          }
        }
 
@@ -6669,7 +7333,7 @@ static const true_false_string tfs_sec_desc_type_self_relative = {
 
 
 static int
-dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
+dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -6714,9 +7378,8 @@ dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tr
        return offset;
 }
 
-
-static int
-dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
+int
+dissect_nt_sec_desc(tvbuff_t *tvb, int offset, proto_tree *parent_tree, int len)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -6742,46 +7405,49 @@ dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *p
        switch(revision){
        case 1:  /* only version we will ever see of this structure?*/
          /* type */
-         offset = dissect_nt_sec_desc_type(tvb, pinfo, offset, tree);
+         offset = dissect_nt_sec_desc_type(tvb, offset, tree);
 
          /* offset to owner sid */
          owner_sid_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID : %d", owner_sid_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
          offset += 4;
 
          /* offset to group sid */
          group_sid_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID : %d", group_sid_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
          offset += 4;
 
          /* offset to sacl */
          sacl_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL : %d", sacl_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
          offset += 4;
 
          /* offset to dacl */
          dacl_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL : %d", dacl_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
          offset += 4;
 
          /*owner SID*/
          if(owner_sid_offset){
-           dissect_nt_sid(tvb, pinfo, old_offset+owner_sid_offset, tree, "Owner");
+           if (len == -1)
+             offset = dissect_nt_sid(tvb, offset, tree, "Owner");
+           else
+             dissect_nt_sid(tvb, old_offset+owner_sid_offset, tree, "Owner");
          }
 
          /*group SID*/
          if(group_sid_offset){
-           dissect_nt_sid(tvb, pinfo, old_offset+group_sid_offset, tree, "Group");
+           dissect_nt_sid(tvb, old_offset+group_sid_offset, tree, "Group");
          }
 
          /* sacl */
          if(sacl_offset){
-           dissect_nt_acl(tvb, pinfo, old_offset+sacl_offset, tree, "System (SACL)");
+           dissect_nt_acl(tvb, old_offset+sacl_offset, tree, "System (SACL)");
          }
 
          /* dacl */
          if(dacl_offset){
-           dissect_nt_acl(tvb, pinfo, old_offset+dacl_offset, tree, "User (DACL)");
+           dissect_nt_acl(tvb, old_offset+dacl_offset, tree, "User (DACL)");
          }
 
        }
@@ -6790,26 +7456,83 @@ dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *p
 }
 
 static int
-dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
+dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
+{
+       int old_offset, old_sid_offset;
+       guint32 qsize;
+
+       do {
+               old_offset=offset;
+
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               qsize=tvb_get_letohl(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               /* length of SID */
+               proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* 16 unknown bytes */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* number of bytes for used quota */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* number of bytes for quota warning */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* number of bytes for quota limit */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* SID of the user */
+               old_sid_offset=offset;
+               offset = dissect_nt_sid(tvb, offset, tree, "Quota");
+               *bcp -= (offset-old_sid_offset);
+
+               if(qsize){
+                       offset = old_offset+qsize;
+               }
+       }while(qsize);
+
+
+       return offset;
+}
+
+
+static int
+dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
+       int old_offset = offset;
+       guint16 bcp=bc; /* XXX fixme */
 
        si = (smb_info_t *)pinfo->private_data;
 
        if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, len,
+               item = proto_tree_add_text(parent_tree, tvb, offset, bc,
                                "%s Data",
                                val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
        }
 
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                /* security descriptor */
                if(ntd->sd_len){
-                       offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, ntd->sd_len);
+                       offset = dissect_nt_sec_desc(tvb, offset, tree, ntd->sd_len);
                }
 
                /* extended attributes */
@@ -6821,12 +7544,12 @@ 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, len, TRUE);
-               offset += len;
+               proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
+               offset += bc;
 
                break;
        case NT_TRANS_SSD:
-               offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
+               offset = dissect_nt_sec_desc(tvb, offset, tree, bc);
                break;
        case NT_TRANS_NOTIFY:
                break;
@@ -6835,6 +7558,28 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
                break;
        case NT_TRANS_QSD:
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               /* unknown 4 bytes */
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 4, TRUE);
+               offset += 4;
+
+               /* length of SID */
+               proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
+               offset +=4;
+
+               offset = dissect_nt_sid(tvb, offset, tree, "Quota");
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
+               break;
+       }
+
+       /* ooops there were data we didnt know how to process */
+       if((offset-old_offset) < bc){
+               proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
+                   bc - (offset-old_offset), TRUE);
+               offset += bc - (offset-old_offset);
        }
 
        return offset;
@@ -6855,13 +7600,13 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Parameters",
                                val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               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, pinfo, tree, offset);
+               offset = dissect_nt_create_bits(tvb, tree, offset);
                bc -= 4;
 
                /* root directory fid */
@@ -6869,27 +7614,27 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(4);
 
                /* nt access mask */
-               offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+               offset = dissect_nt_access_mask(tvb, tree, offset);
                bc -= 4;
-       
+
                /* allocation size */
                proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
                COUNT_BYTES(8);
-       
+
                /* Extended File Attributes */
-               offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+               offset = dissect_file_ext_attr(tvb, tree, offset);
                bc -= 4;
 
                /* share access */
-               offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
+               offset = dissect_nt_share_access(tvb, tree, offset);
                bc -= 4;
-       
+
                /* create disposition */
                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, pinfo, tree, offset);
+               offset = dissect_nt_create_options(tvb, tree, offset);
                bc -= 4;
 
                /* sd length */
@@ -6910,13 +7655,13 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                /* impersonation level */
                proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
                COUNT_BYTES(4);
-       
+
                /* security flags */
-               offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
+               offset = dissect_nt_security_flags(tvb, tree, offset);
                bc -= 1;
 
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
                if (fn != NULL) {
                        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                                fn);
@@ -6926,9 +7671,12 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                break;
        case NT_TRANS_IOCTL:
                break;
-       case NT_TRANS_SSD:
+       case NT_TRANS_SSD: {
+               guint16 fid;
+
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* 2 reserved bytes */
@@ -6936,16 +7684,20 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 2;
 
                /* security information */
-               offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
+               offset = dissect_security_information_mask(tvb, tree, offset);
                break;
+       }
        case NT_TRANS_NOTIFY:
                break;
        case NT_TRANS_RENAME:
                /* XXX not documented */
                break;
-       case NT_TRANS_QSD:
+       case NT_TRANS_QSD: {
+               guint16 fid;
+
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* 2 reserved bytes */
@@ -6953,7 +7705,14 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 2;
 
                /* security information */
-               offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
+               offset = dissect_security_information_mask(tvb, tree, offset);
+               break;
+       }
+       case NT_TRANS_GET_USER_QUOTA:
+               /* not decoded yet */
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
                break;
        }
 
@@ -6976,17 +7735,20 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                                val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
                tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
        }
+
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                break;
-       case NT_TRANS_IOCTL:
+       case NT_TRANS_IOCTL: {
+               guint16 fid;
+
                /* function code */
                proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
                offset += 4;
 
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* isfsctl */
@@ -6994,17 +7756,21 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 1;
 
                /* isflags */
-               offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
+               offset = dissect_nt_ioctl_flags(tvb, tree, offset);
 
                break;
+       }
        case NT_TRANS_SSD:
                break;
-       case NT_TRANS_NOTIFY:
+       case NT_TRANS_NOTIFY: {
+               guint16 fid;
+
                /* completion filter */
-               offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
+               offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
 
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* watch tree */
@@ -7016,19 +7782,26 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 1;
 
                break;
+       }
        case NT_TRANS_RENAME:
                /* XXX not documented */
                break;
        case NT_TRANS_QSD:
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               /* not decoded yet */
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
+               break;
        }
+
        return old_offset+len;
 }
 
 
 static int
-dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc, sc;
        guint32 pc=0, po=0, pd, dc=0, od=0, dd;
@@ -7065,7 +7838,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        /* total param count */
        proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
        offset += 4;
-       
+
        /* total data count */
        proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
        offset += 4;
@@ -7085,7 +7858,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        pc = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
        offset += 4;
-       
+
        /* param offset */
        po = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
@@ -7146,7 +7919,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
                ntd.subcmd = subcmd;
                if (!si->unidir) {
                        if(!pinfo->fd->flags.visited){
-                               /* 
+                               /*
                                 * Allocate a new smb_nt_transact_info_t
                                 * structure.
                                 */
@@ -7177,7 +7950,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        }
 
        BYTE_COUNT;
-       
+
        /* parameters */
        if(po>(guint32)offset){
                /* We have some initial padding bytes.
@@ -7218,12 +7991,15 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 
 static int
-dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
+dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
+                              int offset, proto_tree *parent_tree, int len,
+                              nt_trans_data *ntd _U_)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
        smb_nt_transact_info_t *nti;
+       guint16 bcp;
 
        si = (smb_info_t *)pinfo->private_data;
        if (si->sip != NULL)
@@ -7244,7 +8020,7 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "Unknown NT Transaction Data (matching request not seen)");
                }
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
        }
 
        if (nti == NULL) {
@@ -7273,15 +8049,24 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                 * which may be documented in the Win32 documentation
                 * somewhere.
                 */
-               offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
+               offset = dissect_nt_sec_desc(tvb, offset, tree, len);
+               break;
+       case NT_TRANS_GET_USER_QUOTA:
+               bcp=len;
+               offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
                break;
        }
 
        return offset;
 }
+
 static int
-dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc)
+dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
+                               int offset, proto_tree *parent_tree,
+                               int len, nt_trans_data *ntd _U_, guint16 bc)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -7290,6 +8075,9 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
        smb_info_t *si;
        smb_nt_transact_info_t *nti;
        guint16 fid;
+       int old_offset;
+       guint32 neo;
+       int padcnt;
 
        si = (smb_info_t *)pinfo->private_data;
        if (si->sip != NULL)
@@ -7310,7 +8098,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "Unknown NT Transaction Parameters (matching request not seen)");
                }
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
        }
 
        if (nti == NULL) {
@@ -7326,7 +8114,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                /* reserved byte */
                proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
                offset += 1;
-               
+
                /* fid */
                fid = tvb_get_letohs(tvb, offset);
                add_fid(tvb, pinfo, tree, offset, 2, fid);
@@ -7341,23 +8129,23 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                offset += 4;
 
                /* create time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_create_time);
-       
+
                /* access time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_access_time);
-       
+
                /* last write time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_last_write_time);
-       
+
                /* last change time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_change_time);
-       
+
                /* Extended File Attributes */
-               offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+               offset = dissect_file_ext_attr(tvb, tree, offset);
 
                /* allocation size */
                proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
@@ -7372,7 +8160,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                offset += 2;
 
                /* device state */
-               offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+               offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
                /* is directory */
                proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
@@ -7384,13 +8172,16 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                break;
        case NT_TRANS_NOTIFY:
                while(len){
+                       old_offset = offset;
+
                        /* next entry offset */
-                       proto_tree_add_item(tree, hf_smb_next_entry_offset, tvb, offset, 4, TRUE);
+                       neo = tvb_get_letohl(tvb, offset);
+                       proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
                        COUNT_BYTES(4);
                        len -= 4;
                        /* broken implementations */
                        if(len<0)break;
-       
+
                        /* action */
                        proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
                        COUNT_BYTES(4);
@@ -7407,7 +8198,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                        if(len<0)break;
 
                        /* file name */
-                       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
+                       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
                        if (fn == NULL)
                                break;
                        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
@@ -7417,6 +8208,23 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                        /* broken implementations */
                        if(len<0)break;
 
+                       if (neo == 0)
+                               break;  /* no more structures */
+
+                       /* skip to next structure */
+                       padcnt = (old_offset + neo) - offset;
+                       if (padcnt < 0) {
+                               /*
+                                * XXX - this is bogus; flag it?
+                                */
+                               padcnt = 0;
+                       }
+                       if (padcnt != 0) {
+                               COUNT_BYTES(padcnt);
+                               len -= padcnt;
+                               /* broken implementations */
+                               if(len<0)break;
+                       }
                }
                break;
        case NT_TRANS_RENAME:
@@ -7435,13 +8243,23 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
                offset += 4;
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
+                       tvb_get_letohl(tvb, offset));
+               offset += 4;
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
+               break;
        }
 
        return offset;
 }
+
 static int
-dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
+dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
+                               int offset, proto_tree *parent_tree,
+                               int len, nt_trans_data *ntd _U_)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -7488,13 +8306,19 @@ dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                break;
        case NT_TRANS_QSD:
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               /* not decoded yet */
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
+               break;
        }
 
        return offset;
 }
 
 static int
-dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc, sc;
        guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
@@ -7539,7 +8363,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        tp = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
        offset += 4;
-       
+
        /* total data count */
        td = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
@@ -7549,7 +8373,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        pc = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
        offset += 4;
-       
+
        /* param offset */
        po = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
@@ -7580,7 +8404,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
        offset += 1;
 
-       /* setup data */        
+       /* setup data */
        if(sc){
                dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
                offset += sc*2;
@@ -7595,44 +8419,34 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        save_fragmented = pinfo->fragmented;
        /* do we need reassembly? */
        if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
-               /* oh yeah, either data or parameter section needs 
+               /* oh yeah, either data or parameter section needs
                   reassembly...
                */
                pinfo->fragmented = TRUE;
                if(smb_trans_reassembly){
                        /* ...and we were told to do reassembly */
                        if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
-                               r_fd = smb_trans_defragment(tree, pinfo, tvb, 
+                               r_fd = smb_trans_defragment(tree, pinfo, tvb,
                                                             po, pc, pd, td+tp);
-                               
+
                        }
                        if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
-                               r_fd = smb_trans_defragment(tree, pinfo, tvb, 
+                               r_fd = smb_trans_defragment(tree, pinfo, tvb,
                                                             od, dc, dd+tp, td+tp);
                        }
                }
        }
 
        /* if we got a reassembled fd structure from the reassembly routine we
-          must create pd_tvb from it 
+          must create pd_tvb from it
        */
        if(r_fd){
-               proto_tree *tr;
-               proto_item *it;
-               fragment_data *fd;
-               
-               it = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
-               tr = proto_item_add_subtree(it, ett_smb_segments);
-               for(fd=r_fd->next;fd;fd=fd->next){
-                       proto_tree_add_text(tr, tvb, 0, 0, "Frame:%u Data:%u-%u",
-                                           fd->frame, fd->offset, fd->offset+fd->len-1);
-               }
-               
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
-                                            r_fd->datalen, "Reassembled SMB");
+                                            r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, pd_tvb);
-               pinfo->fragmented = FALSE;
+               add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+
+               show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
        }
 
 
@@ -7642,7 +8456,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                                          &ntd, tvb_length(pd_tvb));
          dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
        } else {
-         /* we do not have reassembled data, just use what we have in the 
+         /* we do not have reassembled data, just use what we have in the
             packet as well as we can */
          /* parameters */
          if(po>(guint32)offset){
@@ -7659,7 +8473,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
            dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
            COUNT_BYTES(pc);
          }
-         
+
          /* data */
          if(od>(guint32)offset){
            /* We have some initial padding bytes.
@@ -7692,10 +8506,11 @@ static const value_string print_mode_vals[] = {
        {1,     "Graphics Mode"},
        {0, NULL}
 };
+
 static int
-dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_open_print_file_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 fn_len;
        const char *fn;
        guint8 wc;
@@ -7719,7 +8534,7 @@ dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        COUNT_BYTES(1);
 
        /* print identifier */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
@@ -7733,16 +8548,17 @@ dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
 
 static int
-dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        int cnt;
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        BYTE_COUNT;
@@ -7759,7 +8575,7 @@ dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        COUNT_BYTES(2);
 
        /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
+       offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
 
        END_OF_SMB
 
@@ -7776,9 +8592,9 @@ static const value_string print_status_vals[] = {
        {6,     "Printer error"},
        {0, NULL}
 };
+
 static int
-dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -7806,6 +8622,7 @@ dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
@@ -7817,7 +8634,7 @@ dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
 
        /* queued time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_print_queue_date,
                hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
        *bcp -= 4;
@@ -7844,7 +8661,7 @@ dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
 
        /* file name */
        fn_len = 16;
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
                fn);
@@ -7855,7 +8672,7 @@ dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
 }
 
 static int
-dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 cnt=0, len;
        guint8 wc;
@@ -7901,81 +8718,297 @@ dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 
 
 static int
-dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
-       guint8  wc, cmd=0xff;
-       guint16 andxoffset=0;
+       int name_len;
        guint16 bc;
-       int fn_len;
-       const char *fn;
+       guint8 wc;
+       guint16 message_len;
 
        WORD_COUNT;
 
-       /* next smb command */
-       cmd = tvb_get_guint8(tvb, offset);
-       if(cmd!=0xff){
-               proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
-       } else {
-               proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
-       }
-       offset += 1;
-
-       /* reserved byte */
-       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
-       offset += 1;
+       BYTE_COUNT;
 
-       /* andxoffset */
-       andxoffset = tvb_get_letohs(tvb, offset);
-       proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
-       offset += 2;
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
 
-       /* reserved byte */
-       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
-       offset += 1;
+       /* originator name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
 
-       /* file name len */
-       fn_len = tvb_get_letohs(tvb, offset);
-       proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
-       offset += 2;
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
 
-       /* Create flags */
-       offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
+       /* destination name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
 
-       /* root directory fid */
-       proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
-       offset += 4;
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
 
-       /* nt access mask */
-       offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+       /* message len */
+       CHECK_BYTE_COUNT(2);
+       message_len = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
+           message_len);
+       COUNT_BYTES(2);
 
-       /* allocation size */
-       proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
-       offset += 8;
+       /* message */
+       CHECK_BYTE_COUNT(message_len);
+       proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
+           TRUE);
+       COUNT_BYTES(message_len);
 
-       /* Extended File Attributes */
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       END_OF_SMB
 
-       /* share access */
-       offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
+       return offset;
+}
 
-       /* create disposition */
-       proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
-       offset += 4;
+static int
+dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
 
-       /* create options */
-       offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
+       WORD_COUNT;
 
-       /* impersonation level */
-       proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
-       offset += 4;
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* originator name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* destination name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       /* message group ID */
+       proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint16 bc;
+       guint8 wc;
+       guint16 message_len;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* message len */
+       CHECK_BYTE_COUNT(2);
+       message_len = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
+           message_len);
+       COUNT_BYTES(2);
+
+       /* message */
+       CHECK_BYTE_COUNT(message_len);
+       proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
+           TRUE);
+       COUNT_BYTES(message_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* forwarded name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* machine name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+
+static int
+dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+{
+       guint8  wc, cmd=0xff;
+       guint16 andxoffset=0;
+       guint16 bc;
+       smb_info_t *si = pinfo->private_data;
+       int fn_len;
+       const char *fn;
+
+       WORD_COUNT;
+
+       /* next smb command */
+       cmd = tvb_get_guint8(tvb, offset);
+       if(cmd!=0xff){
+               proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
+       } else {
+               proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
+       }
+       offset += 1;
+
+       /* reserved byte */
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+       offset += 1;
+
+       /* andxoffset */
+       andxoffset = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
+       offset += 2;
+
+       /* reserved byte */
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
+       offset += 1;
+
+       /* file name len */
+       fn_len = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
+       offset += 2;
+
+       /* Create flags */
+       offset = dissect_nt_create_bits(tvb, tree, offset);
+
+       /* root directory fid */
+       proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
+       offset += 4;
+
+       /* nt access mask */
+       offset = dissect_nt_access_mask(tvb, tree, offset);
+
+       /* 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);
+
+       /* share access */
+       offset = dissect_nt_share_access(tvb, tree, offset);
+
+       /* create disposition */
+       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);
+
+       /* impersonation level */
+       proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
+       offset += 4;
 
        /* security flags */
-       offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
+       offset = dissect_nt_security_flags(tvb, tree, offset);
 
        BYTE_COUNT;
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
@@ -7989,11 +9022,11 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
+
 
 static int
 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
@@ -8038,23 +9071,20 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 4;
 
        /* create time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_create_time);
-       
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
+
        /* access time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_access_time);
-       
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
+
        /* last write time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
                hf_smb_last_write_time);
 
        /* last change time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_change_time);
-       
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
+
        /* Extended File Attributes */
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
 
        /* allocation size */
        proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
@@ -8069,7 +9099,7 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 2;
 
        /* IPC State */
-       offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+       offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
        /* is directory */
        proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
@@ -8080,20 +9110,20 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
 
 
 static int
-dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
 
        WORD_COUNT;
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -8111,6 +9141,7 @@ static const value_string trans2_cmd_vals[] = {
        { 0x01,         "FIND_FIRST2" },
        { 0x02,         "FIND_NEXT2" },
        { 0x03,         "QUERY_FS_INFORMATION" },
+       { 0x04,         "SET_FS_QUOTA" },
        { 0x05,         "QUERY_PATH_INFORMATION" },
        { 0x06,         "SET_PATH_INFORMATION" },
        { 0x07,         "QUERY_FILE_INFORMATION" },
@@ -8186,25 +9217,73 @@ static const value_string qpi_loi_vals[] = {
        { 0x0103,       "Query File EA Info  (4.2.14.6)"},
        { 0x0104,       "Query File Name Info  (4.2.14.7)"},
        { 0x0107,       "Query File All Info  (4.2.14.8)"},
-       { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
+       { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
        { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
        { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
        { 0x0200,       "Set File Unix Basic"},
        { 0x0201,       "Set File Unix Link"},
        { 0x0202,       "Set File Unix HardLink"},
+       { 1004,         "Query File Basic Info  (4.2.14.4)"},
+       { 1005,         "Query File Standard Info  (4.2.14.5)"},
+       { 1006,         "Query File Internal Info  (4.2.14.?)"},
+       { 1007,         "Query File EA Info  (4.2.14.6)"},
+       { 1009,         "Query File Name Info  (4.2.14.7)"},
+       { 1010,         "Query File Rename Info  (4.2.14.?)"},
+       { 1011,         "Query File Link Info  (4.2.14.?)"},
+       { 1012,         "Query File Names Info  (4.2.14.?)"},
+       { 1013,         "Query File Disposition Info  (4.2.14.?)"},
+       { 1014,         "Query File Position Info  (4.2.14.?)"},
+       { 1015,         "Query File Full EA Info  (4.2.14.?)"},
+       { 1016,         "Query File Mode Info  (4.2.14.?)"},
+       { 1017,         "Query File Alignment Info  (4.2.14.?)"},
+       { 1018,         "Query File All Info  (4.2.14.8)"},
+       { 1019,         "Query File Allocation Info  (4.2.14.?)"},
+       { 1020,         "Query File End of File Info  (4.2.14.?)"},
+       { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
+       { 1022,         "Query File Stream Info  (4.2.14.10)"},
+       { 1023,         "Query File Pipe Info  (4.2.14.?)"},
+       { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
+       { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
+       { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
+       { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
+       { 1028,         "Query File Compression Info  (4.2.14.11)"},
+       { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
+       { 1030,         "Query File Completion Info  (4.2.14.?)"},
+       { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
+       { 1032,         "Query File Quota Info  (4.2.14.?)"},
+       { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
+       { 1034,         "Query File Network Open Info  (4.2.14.?)"},
+       { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
+       { 1036,         "Query File Tracking Info  (4.2.14.?)"},
+       { 1037,         "Query File Maximum Info  (4.2.14.?)"},
        {0, NULL}
 };
 
 static const value_string qfsi_vals[] = {
        { 1,            "Info Allocation"},
        { 2,            "Info Volume"},
+       { 0x0101,       "Query FS Label Info"},
        { 0x0102,       "Query FS Volume Info"},
        { 0x0103,       "Query FS Size Info"},
        { 0x0104,       "Query FS Device Info"},
        { 0x0105,       "Query FS Attribute Info"},
+       { 0x0301,       "Mac Query FS INFO"},
+       { 1001,         "Query FS Label Info"},
+       { 1002,         "Query FS Volume Info"},
+       { 1003,         "Query FS Size Info"},
+       { 1004,         "Query FS Device Info"},
+       { 1005,         "Query FS Attribute Info"},
+       { 1006,         "Query FS Quota Info"},
+       { 1007,         "Query Full FS Size Info"},
        {0, NULL}
 };
 
+static const value_string nt_rename_vals[] = {
+       { 0x0103,       "Create Hard Link"},
+       {0, NULL}
+};
+
+
 static const value_string delete_pending_vals[] = {
        {0,     "Normal, no pending delete"},
        {1,     "This object has DELETE PENDING"},
@@ -8308,7 +9387,7 @@ static const true_false_string tfs_fs_attr_vic = {
        "This FS is NOT on a compressed volume"
 };
 
-
+#define FF2_RESUME     0x0004
 
 static int
 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
@@ -8316,9 +9395,20 @@ dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, in
        guint16 mask;
        proto_item *item = NULL;
        proto_tree *tree = NULL;
+       smb_info_t *si;
+       smb_transact2_info_t *t2i;
 
        mask = tvb_get_letohs(tvb, offset);
 
+       si = (smb_info_t *)pinfo->private_data;
+       if (si->sip != NULL) {
+               t2i = si->sip->extra_info;
+               if (t2i != NULL) {
+                       if (!pinfo->fd->flags.visited)
+                               t2i->resume_keys = (mask & FF2_RESUME);
+               }
+       }
+
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
@@ -8341,6 +9431,33 @@ dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, in
        return offset;
 }
 
+#if 0
+static int
+dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint16 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       mask = tvb_get_letohs(tvb, offset);
+
+       if(parent_tree){
+               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);
+
+       offset += 2;
+
+       return offset;
+}
+#endif
+
 static int
 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
@@ -8362,7 +9479,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, bc,
                                "%s Parameters",
-                               val_to_str(subcmd, trans2_cmd_vals, 
+                               val_to_str(subcmd, trans2_cmd_vals,
                                           "Unknown (0x%02x)"));
                tree = proto_item_add_subtree(item, ett_smb_transaction_params);
        }
@@ -8371,27 +9488,27 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
        case 0x00:      /*TRANS2_OPEN2*/
                /* open flags */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
+               offset = dissect_open_flags(tvb, tree, offset, 0x000f);
                bc -= 2;
 
                /* desired access */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+               offset = dissect_access(tvb, tree, offset, "Desired");
                bc -= 2;
 
-               /* 2 reserved bytes */
+               /* Search Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
-               COUNT_BYTES_TRANS(2);
+               offset = dissect_search_attributes(tvb, tree, offset);
+               bc -= 2;
 
                /* File Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_file_attributes(tvb, tree, offset, 2);
                bc -= 2;
 
                /* create time */
                CHECK_BYTE_COUNT_TRANS(4);
-               offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+               offset = dissect_smb_datetime(tvb, tree, offset,
                        hf_smb_create_time,
                        hf_smb_create_dos_date, hf_smb_create_dos_time,
                        TRUE);
@@ -8399,7 +9516,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
 
                /* open function */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_open_function(tvb, pinfo, tree, offset);
+               offset = dissect_open_function(tvb, tree, offset);
                bc -= 2;
 
                /* allocation size */
@@ -8413,7 +9530,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(10);
 
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
@@ -8423,13 +9540,11 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
                        fn);
                }
-
-               /* XXX dont know how to decode FEAList */
                break;
        case 0x01:      /*TRANS2_FIND_FIRST2*/
                /* Search Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_search_attributes(tvb, tree, offset);
                bc -= 2;
 
                /* search count */
@@ -8456,7 +9571,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(4);
 
                /* search pattern */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
                        fn);
@@ -8467,8 +9582,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        fn);
                }
 
-               /* XXX dont know how to decode FEAList */
-
                break;
        case 0x02:      /*TRANS2_FIND_NEXT2*/
                /* sid */
@@ -8500,7 +9613,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                bc -= 2;
 
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
@@ -8530,14 +9643,14 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        t2i->info_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
-               
+
                /* 4 reserved bytes */
                CHECK_BYTE_COUNT_TRANS(4);
                proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
                COUNT_BYTES_TRANS(4);
 
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
@@ -8557,14 +9670,14 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        t2i->info_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
-               
+
                /* 4 reserved bytes */
                CHECK_BYTE_COUNT_TRANS(4);
                proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
                COUNT_BYTES_TRANS(4);
 
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
@@ -8576,10 +9689,13 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                }
 
                break;
-       case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
+       case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
+               guint16 fid;
+
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -8589,12 +9705,16 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        t2i->info_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
-               
+
                break;
-       case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
+       }
+       case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
+               guint16 fid;
+
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -8604,21 +9724,108 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        t2i->info_level = si->info_level;
                proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
                COUNT_BYTES_TRANS(2);
-               
+
+#if 0
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this is I/O flags, but it's
+                * reserved in the SNIA spec, and some clients appear
+                * to leave junk in it.
+                *
+                * Is this some field used only if a particular
+                * dialect was negotiated, so that clients can feel
+                * safe not setting it if they haven't negotiated that
+                * dialect?  Or do the (non-OS/2) clients simply not care
+                * about that particular OS/2-oriented dialect?
+                */
+
+               /* IO Flag */
+               CHECK_BYTE_COUNT_TRANS(2);
+               offset = dissect_sfi_ioflag(tvb, tree, offset);
+               bc -= 2;
+#else
                /* 2 reserved bytes */
                CHECK_BYTE_COUNT_TRANS(2);
                proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
                COUNT_BYTES_TRANS(2);
+#endif
 
                break;
+       }
        case 0x09:      /*TRANS2_FSCTL*/
+               /* this call has no parameter block in the request */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "File system specific parameter block".  (That means
+                * we may not be able to dissect it in any case.)
+                */
+               break;
        case 0x0a:      /*TRANS2_IOCTL2*/
-               /* these calls have no parameter block in the request */
+               /* this call has no parameter block in the request */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "Device/function specific parameter block".  (That
+                * means we may not be able to dissect it in any case.)
+                */
                break;
-       case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
-       case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
-               /* XXX unknown structure*/
+       case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
+               /* Search Attributes */
+               CHECK_BYTE_COUNT_TRANS(2);
+               offset = dissect_search_attributes(tvb, tree, offset);
+               bc -= 2;
+
+               /* Number of changes to wait for */
+               CHECK_BYTE_COUNT_TRANS(2);
+               proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
+               COUNT_BYTES_TRANS(2);
+
+               /* Find Notify information level */
+               CHECK_BYTE_COUNT_TRANS(2);
+               si->info_level = tvb_get_letohs(tvb, offset);
+               if (!pinfo->fd->flags.visited)
+                       t2i->info_level = si->info_level;
+               proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
+               COUNT_BYTES_TRANS(2);
+
+               /* 4 reserved bytes */
+               CHECK_BYTE_COUNT_TRANS(4);
+               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS(4);
+
+               /* file name */
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
+               CHECK_STRING_TRANS(fn);
+               proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+                       fn);
+               COUNT_BYTES_TRANS(fn_len);
+
+               if (check_col(pinfo->cinfo, COL_INFO)) {
+                       col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
+                       fn);
+               }
+
                break;
+       }
+       case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
+               /* Monitor handle */
+               CHECK_BYTE_COUNT_TRANS(2);
+               proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
+               COUNT_BYTES_TRANS(2);
+
+               /* Number of changes to wait for */
+               CHECK_BYTE_COUNT_TRANS(2);
+               proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
+               COUNT_BYTES_TRANS(2);
+
+               break;
+       }
        case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
                /* 4 reserved bytes */
                CHECK_BYTE_COUNT_TRANS(4);
@@ -8626,7 +9833,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(4);
 
                /* dir name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                        FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
@@ -8637,8 +9844,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
                        fn);
                }
-
-               /* XXX optional FEAList, unknown what FEAList looks like*/
                break;
        case 0x0e:      /*TRANS2_SESSION_SETUP*/
                /* XXX unknown structure*/
@@ -8648,9 +9853,9 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                CHECK_BYTE_COUNT_TRANS(2);
                proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
                COUNT_BYTES_TRANS(2);
-               
+
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
@@ -8664,7 +9869,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                break;
        case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                        fn);
@@ -8692,7 +9897,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
  * XXX - just use "dissect_connect_flags()" here?
  */
 static guint16
-dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -8713,10 +9918,10 @@ dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
 
        return mask;
 }
+
 
 static int
-dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -8740,7 +9945,7 @@ dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
 }
 
 static int
-dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -8769,6 +9974,7 @@ static int
 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *tree, int offset, guint16 *bcp)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
@@ -8790,11 +9996,11 @@ dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
 
        /* referral flags */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
+       offset = dissect_dfs_referral_flags(tvb, tree, offset);
        *bcp -= 2;
 
        /* node name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
        CHECK_STRING_TRANS_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
                fn);
@@ -8809,6 +10015,7 @@ 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 pathoffset;
@@ -8836,7 +10043,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
 
        /* get dfs flags */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
+       offset = dissect_get_dfs_flags(tvb, tree, offset);
        *bcp -= 2;
 
        /* XXX - in at least one capture there appears to be 2 bytes
@@ -8872,7 +10079,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                rt = proto_item_add_subtree(ri,
                                        ett_smb_dfs_referral);
                        }
-               
+
                        /* referral version */
                        CHECK_BYTE_COUNT_TRANS_SUBR(2);
                        version = tvb_get_letohs(tvb, offset);
@@ -8893,14 +10100,14 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
 
                        /* referral flags */
                        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                       offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
+                       offset = dissect_dfs_referral_flags(tvb, rt, offset);
                        *bcp -= 2;
 
                        switch(version){
 
                        case 1:
                                /* node name */
-                               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+                               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
                                CHECK_STRING_TRANS_SUBR(fn);
                                proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
                                        fn);
@@ -8947,7 +10154,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                            *bcp > offsetoffset) {
                                                save_bc = *bcp;
                                                *bcp -= offsetoffset;
-                                               fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
+                                               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);
@@ -8957,7 +10164,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                                *bcp = save_bc;
                                        }
                                }
-                       
+
                                /* alt path */
                                if (altpathoffset != 0) {
                                        stroffset = old_offset + altpathoffset;
@@ -8966,7 +10173,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                            *bcp > offsetoffset) {
                                                save_bc = *bcp;
                                                *bcp -= offsetoffset;
-                                               fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
+                                               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);
@@ -8976,7 +10183,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                                *bcp = save_bc;
                                        }
                                }
-                       
+
                                /* node */
                                if (nodeoffset != 0) {
                                        stroffset = old_offset + nodeoffset;
@@ -8985,7 +10192,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
                                            *bcp > offsetoffset) {
                                                save_bc = *bcp;
                                                *bcp -= offsetoffset;
-                                               fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
+                                               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);
@@ -9042,26 +10249,26 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
    as described in 4.2.14.1
 */
 static int
-dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* create time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
                FALSE);
        *bcp -= 4;
 
        /* access time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
                FALSE);
        *bcp -= 4;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
                FALSE);
        *bcp -= 4;
@@ -9078,7 +10285,7 @@ dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
        *bcp -= 2;
 
        /* ea size */
@@ -9094,7 +10301,7 @@ dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.2
 */
 static int
-dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* list length */
@@ -9113,11 +10320,12 @@ static int
 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
        CHECK_STRING_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                fn);
@@ -9131,37 +10339,34 @@ dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.4
 */
 static int
-dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
-       
+
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
                hf_smb_last_write_time);
        *bcp -= 8;
-       
+
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
-       
+
        /* File Attributes */
-       CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
-       *bcp -= 2;
+       CHECK_BYTE_COUNT_SUBR(4);
+       offset = dissect_file_attributes(tvb, tree, offset, 4);
+       *bcp -= 4;
 
        *trunc = FALSE;
        return offset;
@@ -9171,7 +10376,7 @@ dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.5
 */
 static int
-dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* allocation size */
@@ -9207,7 +10412,7 @@ dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.6
 */
 static int
-dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* ea size */
@@ -9228,6 +10433,7 @@ static int
 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
@@ -9237,7 +10443,7 @@ dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES_SUBR(4);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
        CHECK_STRING_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                fn);
@@ -9256,11 +10462,13 @@ dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 {
 
        offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
-       if (trunc)
+       if (*trunc) {
                return offset;
+       }
        offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
-       if (trunc)
+       if (*trunc) {
                return offset;
+       }
 
        /* index number */
        CHECK_BYTE_COUNT_SUBR(8);
@@ -9268,12 +10476,12 @@ dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES_SUBR(8);
 
        offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
-       if (trunc)
+       if (*trunc)
                return offset;
 
        /* access flags */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+       offset = dissect_nt_access_mask(tvb, tree, offset);
        COUNT_BYTES_SUBR(4);
 
        /* index number */
@@ -9288,14 +10496,14 @@ dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* mode */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
+       offset = dissect_nt_create_options(tvb, tree, offset);
        *bcp -= 4;
 
        /* alignment */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
        COUNT_BYTES_SUBR(4);
-       
+
        offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
 
        return offset;
@@ -9312,6 +10520,7 @@ dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_tree *tree;
        int old_offset;
        guint32 neo;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        int padcnt;
@@ -9332,13 +10541,13 @@ dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                neo = tvb_get_letohl(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
                COUNT_BYTES_SUBR(4);
-       
+
                /* stream name len */
                CHECK_BYTE_COUNT_SUBR(4);
                fn_len = tvb_get_letohl(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
                COUNT_BYTES_SUBR(4);
-       
+
                /* stream size */
                CHECK_BYTE_COUNT_SUBR(8);
                proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
@@ -9350,12 +10559,12 @@ dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                COUNT_BYTES_SUBR(8);
 
                /* stream name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+               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_t2_stream_name, tvb, offset, fn_len,
                        fn);
                COUNT_BYTES_SUBR(fn_len);
+
                proto_item_append_text(item, ": %s", fn);
                proto_item_set_len(item, offset-old_offset);
 
@@ -9384,7 +10593,7 @@ dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
    as described in 4.2.14.11
 */
 static int
-dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* compressed file size */
@@ -9396,22 +10605,22 @@ dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        CHECK_BYTE_COUNT_SUBR(2);
        proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
        COUNT_BYTES_SUBR(2);
-       
+
        /* compression unit shift */
        CHECK_BYTE_COUNT_SUBR(1);
        proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
        COUNT_BYTES_SUBR(1);
-       
+
        /* compression chunk shift */
        CHECK_BYTE_COUNT_SUBR(1);
        proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
        COUNT_BYTES_SUBR(1);
-       
+
        /* compression cluster shift */
        CHECK_BYTE_COUNT_SUBR(1);
        proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
        COUNT_BYTES_SUBR(1);
-       
+
        /* 3 reserved bytes */
        CHECK_BYTE_COUNT_SUBR(3);
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
@@ -9434,7 +10643,7 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
        if(!*bcp){
                return offset;
        }
-       
+
        si = (smb_info_t *)pinfo->private_data;
        switch(si->info_level){
        case 1:         /*Info Standard*/
@@ -9452,34 +10661,43 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                    &trunc);
                break;
        case 0x0101:    /*Query File Basic Info*/
+       case 1004:      /* SMB_FILE_BASIC_INFORMATION */
                offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0102:    /*Query File Standard Info*/
+       case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
                offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0103:    /*Query File EA Info*/
+       case 1007:      /* SMB_FILE_EA_INFORMATION */
                offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0104:    /*Query File Name Info*/
+       case 1009:      /* SMB_FILE_NAME_INFORMATION */
                offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0107:    /*Query File All Info*/
+       case 1018:      /* SMB_FILE_ALL_INFORMATION */
                offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0108:    /*Query File Alt File Info*/
+       case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
                offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
+       case 1022:      /* SMB_FILE_STREAM_INFORMATION */
+               ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
        case 0x0109:    /*Query File Stream Info*/
                offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x010b:    /*Query File Compression Info*/
+       case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
                offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
@@ -9493,11 +10711,93 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                /* XXX add this from the SNIA doc */
                break;
        }
-       
+
        return offset;
 }
 
 
+static const true_false_string tfs_quota_flags_deny_disk = {
+       "DENY DISK SPACE for users exceeding quota limit",
+       "Do NOT deny disk space for users exceeding quota limit"
+};
+static const true_false_string tfs_quota_flags_log_limit = {
+       "LOG EVENT when a user exceeds their QUOTA LIMIT",
+       "Do NOT log event when a user exceeds their quota limit"
+};
+static const true_false_string tfs_quota_flags_log_warning = {
+       "LOG EVENT when a user exceeds their WARNING LEVEL",
+       "Do NOT log event when a user exceeds their warning level"
+};
+static const true_false_string tfs_quota_flags_enabled = {
+       "Quotas are ENABLED of this fs",
+       "Quotas are NOT enabled on this fs"
+};
+static void
+dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint8 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       mask = tvb_get_guint8(tvb, offset);
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 1,
+                       "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,
+                       tvb, offset, 1, mask);
+       }
+
+}
+
+static int
+dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
+{
+       /* first 24 bytes are unknown */
+       CHECK_BYTE_COUNT_TRANS_SUBR(24);
+       proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                   offset, 24, TRUE);
+       COUNT_BYTES_TRANS_SUBR(24);
+
+       /* number of bytes for quota warning */
+       CHECK_BYTE_COUNT_TRANS_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
+       COUNT_BYTES_TRANS_SUBR(8);
+
+       /* number of bytes for quota limit */
+       CHECK_BYTE_COUNT_TRANS_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
+       COUNT_BYTES_TRANS_SUBR(8);
+
+       /* one byte of quota flags */
+       CHECK_BYTE_COUNT_TRANS_SUBR(1);
+       dissect_quota_flags(tvb, tree, offset);
+       COUNT_BYTES_TRANS_SUBR(1);
+
+       /* these 7 bytes are unknown */
+       CHECK_BYTE_COUNT_TRANS_SUBR(7);
+       proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                   offset, 7, TRUE);
+       COUNT_BYTES_TRANS_SUBR(7);
+
+       return offset;
+}
+
 static int
 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
@@ -9511,50 +10811,103 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, dc,
                                "%s Data",
-                               val_to_str(subcmd, trans2_cmd_vals, 
+                               val_to_str(subcmd, trans2_cmd_vals,
                                                "Unknown (0x%02x)"));
                tree = proto_item_add_subtree(item, ett_smb_transaction_data);
        }
 
        switch(subcmd){
        case 0x00:      /*TRANS2_OPEN2*/
-               /* XXX FAEList here?*/
+               /* XXX dont know how to decode FEAList */
                break;
        case 0x01:      /*TRANS2_FIND_FIRST2*/
-               /* XXX FAEList here?*/
+               /* XXX dont know how to decode FEAList */
                break;
        case 0x02:      /*TRANS2_FIND_NEXT2*/
-               /* no data field in this request */
+               /* XXX dont know how to decode FEAList */
                break;
        case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
                /* no data field in this request */
                break;
+       case 0x04:      /* TRANS2_SET_QUOTA */
+               offset = dissect_nt_quota(tvb, tree, offset, &dc);
+               break;
        case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
                /* no data field in this request */
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says there may be "Additional
+                * FileInfoLevel dependent information" here.
+                *
+                * Was that just a cut-and-pasteo?
+                * TRANS2_SET_PATH_INFORMATION *does* have that information
+                * here.
+                */
                break;
        case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
                offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
                break;
        case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
                /* no data field in this request */
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says there may be "Additional
+                * FileInfoLevel dependent information" here.
+                *
+                * Was that just a cut-and-pasteo?
+                * TRANS2_SET_FILE_INFORMATION *does* have that information
+                * here.
+                */
                break;
        case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
                offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
                break;
        case 0x09:      /*TRANS2_FSCTL*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "File system specific data block".  (That means we
+                * may not be able to dissect it in any case.)
+                */
                break;
        case 0x0a:      /*TRANS2_IOCTL2*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "Device/function specific data block".  (That
+                * means we may not be able to dissect it in any case.)
+                */
                break;
        case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains "additional
+                * level dependent match data".
+                */
                break;
        case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains "additional
+                * level dependent monitor information".
+                */
                break;
        case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
-               /* no data block for this one */
+               /* XXX optional FEAList, unknown what FEAList looks like*/
                break;
        case 0x0e:      /*TRANS2_SESSION_SETUP*/
                /*XXX dont know how to decode this yet */
@@ -9579,7 +10932,7 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
 
 static void
 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
-    packet_info *pinfo, proto_tree *tree)
+    proto_tree *tree)
 {
        int i;
        int offset;
@@ -9632,7 +10985,7 @@ dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
    Transaction2 Secondary 0x33
 */
 static int
-dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc, sc=0;
        int so=offset;
@@ -9661,7 +11014,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                /* total param count, only a 16bit integer here*/
                proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
                offset += 2;
-       
+
                /* total data count , only 16bit integer here*/
                proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
                offset += 2;
@@ -9680,7 +11033,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                pd = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
                offset += 2;
-       
+
                /* data count */
                dc = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
@@ -9690,15 +11043,19 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                od = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
                offset += 2;
-       
+
                /* data disp */
                dd = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
                offset += 2;
 
                if(si->cmd==SMB_COM_TRANSACTION2){
+                       guint16 fid;
+
                        /* fid */
-                       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+                       fid = tvb_get_letohs(tvb, offset);
+                       add_fid(tvb, pinfo, tree, offset, 2, fid);
+
                        offset += 2;
                }
 
@@ -9734,7 +11091,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                offset += 1;
 
                /* transaction flags */
-               tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
+               tf = dissect_transaction_flags(tvb, tree, offset);
                offset += 2;
 
                /* timeout */
@@ -9755,7 +11112,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                pc = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
                offset += 2;
-       
+
                /* param offset */
                po = tvb_get_letohs(tvb, offset);
                proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
@@ -9785,8 +11142,8 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                /* reserved byte */
                proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
                offset += 1;
-               
-               /* this is where the setup bytes, if any start */       
+
+               /* this is where the setup bytes, if any start */
                so = offset;
                sl = sc*2;
 
@@ -9796,18 +11153,21 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
                        case SMB_COM_TRANSACTION2:
                                /* TRANSACTION2 only has one setup word and
-                                  that is the subcommand code. */
+                                  that is the subcommand code.
+
+                                  XXX - except for TRANS2_FSCTL
+                                  and TRANS2_IOCTL. */
                                subcmd = tvb_get_letohs(tvb, offset);
                                proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
                                    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, 
+                                           val_to_str(subcmd, trans2_cmd_vals,
                                                "Unknown (0x%02x)"));
                                }
                                if (!si->unidir) {
                                        if(!pinfo->fd->flags.visited){
-                                               /* 
+                                               /*
                                                 * Allocate a new
                                                 * smb_transact2_info_t
                                                 * structure.
@@ -9815,9 +11175,15 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                                t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
                                                t2i->subcmd = subcmd;
                                                t2i->info_level = -1;
+                                               t2i->resume_keys = FALSE;
                                                si->sip->extra_info = t2i;
                                        }
-                               }     
+                               }
+
+                               /*
+                                * XXX - process TRANS2_FSCTL and
+                                * TRANS2_IOCTL setup words here.
+                                */
                                break;
 
                        case SMB_COM_TRANSACTION:
@@ -9830,14 +11196,14 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        BYTE_COUNT;
-       
+
        if(wc!=8){
                /* primary request */
                /* name is NULL if transaction2 */
                if(si->cmd == SMB_COM_TRANSACTION){
                        /* Transaction Name */
                        an = get_unicode_or_ascii_string(tvb, &offset,
-                               pinfo, &an_len, FALSE, FALSE, &bc);
+                               si->unicode, &an_len, FALSE, FALSE, &bc);
                        if (an == NULL)
                                goto endofcommand;
                        proto_tree_add_string(tree, hf_smb_trans_name, tvb,
@@ -9913,7 +11279,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /*TRANSACTION request parameters */
        if(si->cmd==SMB_COM_TRANSACTION){
-               /*XXX replace this block with a function and use that one 
+               /*XXX replace this block with a function and use that one
                     for both requests/responses*/
                if(dd==0){
                        tvbuff_t *p_tvb, *d_tvb, *s_tvb;
@@ -9949,7 +11315,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
                        if (!si->unidir) {
                                if(!pinfo->fd->flags.visited){
-                                       /* 
+                                       /*
                                         * Allocate a new smb_transact_info_t
                                         * structure.
                                         */
@@ -10000,6 +11366,16 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                dissected_trans = dissect_pipe_smb(sp_tvb,
                                    s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
                                    top_tree);
+
+                               /* 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 
+                                  TID is (probably) DCERPC.
+                               */
+                               if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
+                                       g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
+                               }
+                               g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
                        } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
                                if (tri != NULL)
                                        tri->subcmd=TRANSACTION_MAILSLOT;
@@ -10012,10 +11388,8 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                dissected_trans = dissect_mailslot_smb(sp_tvb,
                                    s_tvb, d_tvb, an+10, pinfo, top_tree);
                        }
-                       if (!dissected_trans) {
-                               dissect_trans_data(s_tvb, p_tvb, d_tvb,
-                                   pinfo, tree);
-                       }
+                       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,
@@ -10029,7 +11403,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        return offset;
 }
 
+
 
 static int
 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
@@ -10041,8 +11415,15 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
+       smb_transact2_info_t *t2i;
+       gboolean resume_keys = FALSE;
 
        si = (smb_info_t *)pinfo->private_data;
+       if (si->sip != NULL) {
+               t2i = si->sip->extra_info;
+               if (t2i != NULL)
+                       resume_keys = t2i->resume_keys;
+       }
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
@@ -10050,23 +11431,30 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
 
+       if (resume_keys) {
+               /* resume key */
+               CHECK_BYTE_COUNT_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
+               COUNT_BYTES_SUBR(4);
+       }
+
        /* create time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
        *bcp -= 4;
 
        /* access time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
        *bcp -= 4;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
        *bcp -= 4;
@@ -10083,7 +11471,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, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
        *bcp -= 2;
 
        /* file name len */
@@ -10091,9 +11479,13 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        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, pinfo, &fn_len, FALSE, TRUE, bcp);
+       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);
@@ -10103,7 +11495,7 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
                fn);
        }
+
        proto_item_append_text(item, " File: %s", fn);
        proto_item_set_len(item, offset-old_offset);
 
@@ -10121,32 +11513,46 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
+       smb_transact2_info_t *t2i;
+       gboolean resume_keys = FALSE;
 
        si = (smb_info_t *)pinfo->private_data;
+       if (si->sip != NULL) {
+               t2i = si->sip->extra_info;
+               if (t2i != NULL)
+                       resume_keys = t2i->resume_keys;
+       }
 
        if(parent_tree){
                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);
        }
+
+       if (resume_keys) {
+               /* resume key */
+               CHECK_BYTE_COUNT_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
+               COUNT_BYTES_SUBR(4);
+       }
+
        /* create time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
        *bcp -= 4;
 
        /* access time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
        *bcp -= 4;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
        *bcp -= 4;
@@ -10163,7 +11569,7 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
        *bcp -= 2;
 
        /* ea size */
@@ -10178,11 +11584,15 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        COUNT_BYTES_SUBR(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+       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 (si->unicode)
+               fn_len += 2;    /* include terminating '\0' */
+       else
+               fn_len++;       /* include terminating '\0' */
 
        if (check_col(pinfo->cinfo, COL_INFO)) {
                col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
@@ -10217,12 +11627,17 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                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);
@@ -10230,28 +11645,25 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
-       
+
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
                hf_smb_last_write_time);
        *bcp -= 8;
-       
+
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
-       
+
        /* end of file */
        CHECK_BYTE_COUNT_SUBR(8);
        proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
@@ -10264,7 +11676,7 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* Extended File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* file name len */
@@ -10274,7 +11686,7 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        COUNT_BYTES_SUBR(4);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+       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);
@@ -10328,12 +11740,17 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                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);
@@ -10341,28 +11758,25 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
-       
+
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
                hf_smb_last_write_time);
        *bcp -= 8;
-       
+
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
-       
+
        /* end of file */
        CHECK_BYTE_COUNT_SUBR(8);
        proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
@@ -10375,7 +11789,7 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* Extended File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* file name len */
@@ -10390,7 +11804,7 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        COUNT_BYTES_SUBR(4);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+       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);
@@ -10444,12 +11858,18 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
 
+       /*
+        * XXX - I have not seen any of these that contain a resume
+        * key, even though some of the requests had the "return resume
+        * key" flag set.
+        */
+
        /* next entry offset */
        CHECK_BYTE_COUNT_SUBR(4);
        neo = tvb_get_letohl(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
        COUNT_BYTES_SUBR(4);
-       
+
        /* file index */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
@@ -10457,28 +11877,25 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
-       
+
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
                hf_smb_last_write_time);
        *bcp -= 8;
-       
+
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
-       
+
        /* end of file */
        CHECK_BYTE_COUNT_SUBR(8);
        proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
@@ -10491,7 +11908,7 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* Extended File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* file name len */
@@ -10515,16 +11932,16 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        CHECK_BYTE_COUNT_SUBR(1);
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
        COUNT_BYTES_SUBR(1);
+
        /* short file name */
-       sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
+       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, pinfo, &fn_len, FALSE, TRUE, bcp);
+       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);
@@ -10577,13 +11994,18 @@ dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                    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);
@@ -10596,7 +12018,7 @@ dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        COUNT_BYTES_SUBR(4);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+       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);
@@ -10628,10 +12050,11 @@ dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        *trunc = FALSE;
        return offset;
 }
+
 static int
-dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
-    int offset, guint16 *bcp, gboolean *trunc)
+dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
+               proto_tree *parent_tree _U_, int offset, guint16 *bcp,
+               gboolean *trunc)
 {
 /*XXX im lazy. i havnt implemented this */
        offset += *bcp;
@@ -10650,7 +12073,7 @@ dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
        if(!*bcp){
                return offset;
        }
-       
+
        si = (smb_info_t *)pinfo->private_data;
        switch(si->info_level){
        case 1:         /*Info Standard*/
@@ -10661,7 +12084,7 @@ dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
                offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
                    trunc);
                break;
-       case 3:         /*Info Query EAs From List same as 
+       case 3:         /*Info Query EAs From List same as
                                InfoQueryEASize*/
                offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
                    trunc);
@@ -10695,7 +12118,7 @@ dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
 
 
 static int
-dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -10727,10 +12150,10 @@ dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
        offset += 4;
        return offset;
 }
+
 
 static int
-dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -10763,8 +12186,33 @@ dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pa
        return offset;
 }
 
-
 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
+
+static const true_false_string tfs_smb_mac_access_ctrl = {
+  "Macintosh Access Control Supported",
+  "Macintosh Access Control Not Supported"
+};
+
+static const true_false_string tfs_smb_mac_getset_comments = {
+  "Macintosh Get & Set Comments Supported",
+  "Macintosh Get & Set Comments Not Supported"
+};
+
+static const true_false_string tfs_smb_mac_desktopdb_calls = {
+  "Macintosh Get & Set Desktop Database Info Supported",
+  "Macintosh Get & Set Desktop Database Info Supported"
+};
+
+static const true_false_string tfs_smb_mac_unique_ids = {
+  "Macintosh Unique IDs Supported",
+  "Macintosh Unique IDs Not Supported"
+};
+
+static const true_false_string tfs_smb_mac_streams = {
+  "Macintosh and Streams Extensions Not Supported",
+  "Macintosh and Streams Extensions Supported"
+};
+
 static int
 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
     int offset, guint16 *bcp)
@@ -10772,11 +12220,14 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
        smb_info_t *si;
        int fn_len, vll, fnl;
        const char *fn;
+       guint support = 0;
+       proto_item *item = NULL;
+       proto_tree *ti = NULL;
 
        if(!*bcp){
                return offset;
        }
-       
+
        si = (smb_info_t *)pinfo->private_data;
        switch(si->info_level){
        case 1:         /* SMB_INFO_ALLOCATION */
@@ -10818,7 +12269,24 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                COUNT_BYTES_TRANS_SUBR(1);
 
                /* label */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
+               CHECK_STRING_TRANS_SUBR(fn);
+               proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
+                       fn);
+               COUNT_BYTES_TRANS_SUBR(fn_len);
+
+               break;
+       case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
+       case 1001:      /* SMB_FS_LABEL_INFORMATION */
+               /* volume label length */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               vll = tvb_get_letohl(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* label */
+               fn_len = vll;
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
                CHECK_STRING_TRANS_SUBR(fn);
                proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
                        fn);
@@ -10826,12 +12294,13 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                break;
        case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
+       case 1002:      /* SMB_FS_VOLUME_INFORMATION */
                /* create time */
                CHECK_BYTE_COUNT_TRANS_SUBR(8);
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_create_time);
                *bcp -= 8;
-       
+
                /* volume serial number */
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
                proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
@@ -10850,7 +12319,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                /* label */
                fn_len = vll;
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
                CHECK_STRING_TRANS_SUBR(fn);
                proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
                        fn);
@@ -10858,14 +12327,160 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                break;
        case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
+       case 1003:      /* SMB_FS_SIZE_INFORMATION */
+               /* allocation size */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* free allocation units */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* sectors per unit */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* bytes per sector */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               break;
+       case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
+       case 1004:      /* SMB_FS_DEVICE_INFORMATION */
+               /* device type */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* device characteristics */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               offset = dissect_device_characteristics(tvb, tree, offset);
+               *bcp -= 4;
+
+               break;
+       case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
+       case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
+               /* FS attributes */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               offset = dissect_fs_attributes(tvb, tree, offset);
+               *bcp -= 4;
+
+               /* max name len */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* fs name length */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               fnl = tvb_get_letohl(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* label */
+               fn_len = fnl;
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
+               CHECK_STRING_TRANS_SUBR(fn);
+               proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
+                       fn);
+               COUNT_BYTES_TRANS_SUBR(fn_len);
+
+               break;
+       case 0x301:     /* MAC_QUERY_FS_INFO */
+               /* Create time */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
+               *bcp -= 8;
+               /* Modify Time */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
+               *bcp -= 8;
+               /* Backup Time */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
+               *bcp -= 8;
+               /* Allocation blocks */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
+                                   offset,
+                                   4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Allocation Block Size */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Free Block Count */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Finder Info ... */
+               CHECK_BYTE_COUNT_TRANS_SUBR(32);
+               proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
+                                           offset, 32,
+                                           tvb_get_ptr(tvb, offset,32),
+                                           "Finder Info: %s",
+                                           tvb_format_text(tvb, offset, 32));
+               COUNT_BYTES_TRANS_SUBR(32);
+               /* Number Files */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Number of Root Directories */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Number of files */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Dir Count */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Mac Support Flags */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               support = tvb_get_ntohl(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);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
+                                      tvb, offset, 4, support);
+               COUNT_BYTES_TRANS_SUBR(4);
+               break;
+       case 1006:      /* QUERY_FS_QUOTA_INFO */
+               offset = dissect_nt_quota(tvb, tree, offset, bcp);
+               break;
+       case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
                /* allocation size */
                CHECK_BYTE_COUNT_TRANS_SUBR(8);
                proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
                COUNT_BYTES_TRANS_SUBR(8);
 
-               /* free allocation units */
+               /* caller free allocation units */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* actual free allocation units */
                CHECK_BYTE_COUNT_TRANS_SUBR(8);
-               proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
+               proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
                COUNT_BYTES_TRANS_SUBR(8);
 
                /* sectors per unit */
@@ -10877,51 +12492,12 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
                proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
                COUNT_BYTES_TRANS_SUBR(4);
-
-               break;
-       case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
-               /* device type */
-               CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
-               COUNT_BYTES_TRANS_SUBR(4);
-               /* device characteristics */
-               CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
-               *bcp -= 4;
-       
-               break;
-       case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
-               /* FS attributes */
-               CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
-               *bcp -= 4;
-       
-               /* max name len */
-               CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
-               COUNT_BYTES_TRANS_SUBR(4);
-
-               /* fs name length */
-               CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               fnl = tvb_get_letohl(tvb, offset);
-               proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
-               COUNT_BYTES_TRANS_SUBR(4);
-
-               /* label */
-               fn_len = fnl;
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
-               CHECK_STRING_TRANS_SUBR(fn);
-               proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
-                       fn);
-               COUNT_BYTES_TRANS_SUBR(fn_len);
-
                break;
        }
+
        return offset;
 }
+
 static int
 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *parent_tree)
@@ -10947,7 +12523,7 @@ 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, 
+                               val_to_str(t2i->subcmd, trans2_cmd_vals,
                                        "Unknown (0x%02x)"));
                        tree = proto_item_add_subtree(item, ett_smb_transaction_data);
                } else {
@@ -11014,15 +12590,49 @@ dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
                break;
        case 0x09:      /*TRANS2_FSCTL*/
                /* XXX dont know how to dissect this one (yet)*/
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "File system specific return data block".
+                * (That means we may not be able to dissect it in any
+                * case.)
+                */
                break;
        case 0x0a:      /*TRANS2_IOCTL2*/
                /* XXX dont know how to dissect this one (yet)*/
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "Device/function specific return data block".
+                * (That means we may not be able to dissect it in any
+                * case.)
+                */
                break;
        case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
                /* XXX dont know how to dissect this one (yet)*/
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains "the level
+                * dependent information about the changes which
+                * occurred".
+                */
                break;
        case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
                /* XXX dont know how to dissect this one (yet)*/
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains "the level
+                * dependent information about the changes which
+                * occurred".
+                */
                break;
        case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
                /* no data in this response */
@@ -11080,7 +12690,7 @@ 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, 
+                               val_to_str(t2i->subcmd, trans2_cmd_vals,
                                                "Unknown (0x%02x)"));
                        tree = proto_item_add_subtree(item, ett_smb_transaction_params);
                } else {
@@ -11100,12 +12710,26 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
+               /*
+                * XXX - Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990 says that the file attributes, create
+                * time (which it says is the last modification time),
+                * data size, granted access, file type, and IPC state
+                * are returned only if bit 0 is set in the open flags,
+                * and that the EA length is returned only if bit 3
+                * is set in the open flags.  Does that mean that,
+                * at least in that SMB dialect, those fields are not
+                * present in the reply parameters if the bits in
+                * question aren't set?
+                */
+
                /* File Attributes */
-               offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_file_attributes(tvb, tree, offset, 2);
 
                /* create time */
-               offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
-                       hf_smb_create_time, 
+               offset = dissect_smb_datetime(tvb, tree, offset,
+                       hf_smb_create_time,
                        hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
 
                /* data size */
@@ -11113,20 +12737,20 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                offset += 4;
 
                /* granted access */
-               offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+               offset = dissect_access(tvb, tree, offset, "Granted");
 
                /* File Type */
                proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
                offset += 2;
 
                /* IPC State */
-               offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+               offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
                /* open_action */
-               offset = dissect_open_action(tvb, pinfo, tree, offset);
+               offset = dissect_open_action(tvb, tree, offset);
 
-               /* 4 reserved bytes */
-               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+               /* server unique file ID */
+               proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
                offset += 4;
 
                /* ea error offset, only a 16 bit integer here */
@@ -11175,7 +12799,7 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
                offset += 2;
 
-               /* ea error offset , only a 16 bit integer here*/
+               /* ea_error_offset, only a 16 bit integer here*/
                proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
                offset += 2;
 
@@ -11189,28 +12813,84 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                /* no parameter block here */
                break;
        case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
-               /* no parameter block here */
+               /* ea_error_offset, only a 16 bit integer here*/
+               proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+               offset += 2;
+
                break;
        case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
-               /* no parameter block here */
+               /* ea_error_offset, only a 16 bit integer here*/
+               proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+               offset += 2;
+
                break;
        case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
-               /* no parameter block here */
+               /* ea_error_offset, only a 16 bit integer here*/
+               proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+               offset += 2;
+
                break;
        case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
-               /* no parameter block here */
+               /* ea_error_offset, only a 16 bit integer here*/
+               proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+               offset += 2;
+
                break;
        case 0x09:      /*TRANS2_FSCTL*/
                /* XXX dont know how to dissect this one (yet)*/
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "File system specific return parameter block".
+                * (That means we may not be able to dissect it in any
+                * case.)
+                */
                break;
        case 0x0a:      /*TRANS2_IOCTL2*/
                /* XXX dont know how to dissect this one (yet)*/
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "Device/function specific return parameter block".
+                * (That means we may not be able to dissect it in any
+                * case.)
+                */
                break;
        case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
-               /* XXX dont know how to dissect this one (yet)*/
+               /* Find Notify information level */
+               proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
+
+               /* Monitor handle */
+               proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
+               offset += 2;
+
+               /* Change count */
+               si->info_count = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
+               offset += 2;
+
+               /* ea_error_offset, only a 16 bit integer here*/
+               proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+               offset += 2;
+
                break;
        case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
-               /* XXX dont know how to dissect this one (yet)*/
+               /* Find Notify information level */
+               proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
+
+               /* Change count */
+               si->info_count = tvb_get_letohs(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
+               offset += 2;
+
+               /* ea_error_offset, only a 16 bit integer here*/
+               proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+               offset += 2;
+
                break;
        case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
                /* ea error offset, only a 16 bit integer here */
@@ -11245,11 +12925,10 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
 
 
 static int
-dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 sc, wc;
        guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
-       gboolean reassembled = FALSE;
        smb_info_t *si;
        smb_transact2_info_t *t2i = NULL;
        guint16 bc;
@@ -11298,7 +12977,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                                if (check_col(pinfo->cinfo, COL_INFO)) {
                                        col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
                                                val_to_str(t2i->subcmd,
-                                                       trans2_cmd_vals, 
+                                                       trans2_cmd_vals,
                                                        "<unknown (0x%02x)>"));
                                }
                        }
@@ -11387,44 +13066,33 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        save_fragmented = pinfo->fragmented;
        /* do we need reassembly? */
        if( (td!=dc) || (tp!=pc) ){
-               /* oh yeah, either data or parameter section needs 
+               /* oh yeah, either data or parameter section needs
                   reassembly
                */
                pinfo->fragmented = TRUE;
                if(smb_trans_reassembly){
                        /* ...and we were told to do reassembly */
                        if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
-                               r_fd = smb_trans_defragment(tree, pinfo, tvb, 
+                               r_fd = smb_trans_defragment(tree, pinfo, tvb,
                                                             po, pc, pd, td+tp);
-                               
+
                        }
                        if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
-                               r_fd = smb_trans_defragment(tree, pinfo, tvb, 
+                               r_fd = smb_trans_defragment(tree, pinfo, tvb,
                                                             od, dc, dd+tp, td+tp);
                        }
                }
        }
 
        /* if we got a reassembled fd structure from the reassembly routine we must
-          create pd_tvb from it 
+          create pd_tvb from it
        */
        if(r_fd){
-               proto_tree *tr;
-               proto_item *it;
-               fragment_data *fd;
-               
-               it = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
-               tr = proto_item_add_subtree(it, ett_smb_segments);
-               for(fd=r_fd->next;fd;fd=fd->next){
-                       proto_tree_add_text(tr, tvb, 0, 0, "Frame:%u Data:%u-%u",
-                                           fd->frame, fd->offset, fd->offset+fd->len-1);
-               }
-               
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
-                                            r_fd->datalen, "Reassembled SMB");
+                                            r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, pd_tvb);
-               pinfo->fragmented = FALSE;
+               add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+               show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
        }
 
 
@@ -11438,7 +13106,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                }
        } else {
                /* It was not reassembled. Do as best as we can.
-                * in this case we always try to dissect the stuff if 
+                * in this case we always try to dissect the stuff if
                 * data and param displacement is 0. i.e. for the first
                 * (and maybe only) packet.
                 */
@@ -11530,7 +13198,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                        switch(tri->subcmd){
 
                        case TRANSACTION_PIPE:
-                               /* This function is safe to call for 
+                               /* This function is safe to call for
                                   s_tvb==sp_tvb==NULL, i.e. if we don't
                                   know them at this point.
                                   It's also safe to call if "p_tvb"
@@ -11542,7 +13210,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                                                d_tvb, NULL, pinfo, top_tree);
                                }
                                break;
-                               
+
                        case TRANSACTION_MAILSLOT:
                                /* This one should be safe to call
                                   even if s_tvb and sp_tvb is NULL
@@ -11557,8 +13225,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                }
                if (!dissected_trans) {
                        /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
-                       dissect_trans_data(s_tvb, p_tvb, d_tvb,
-                                          pinfo, tree);
+                       dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
                }
        }
 
@@ -11577,26 +13244,50 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 }
 
 
+static int
+dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint8 wc;
+       guint16 bc;
+
+       WORD_COUNT;
+
+       /* Monitor handle */
+       proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       END_OF_SMB
+
+       return offset;
+}
+
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    END Transaction/Transaction2 Primary and secondary requests
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
 
 static int
-dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
 
        WORD_COUNT;
-       if (wc != 0)
+
+       if (wc != 0) {
                proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
+               offset += wc*2;
+       }
 
        BYTE_COUNT;
 
-       if (bc != 0)
+       if (bc != 0) {
                proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
+               offset += bc;
+               bc = 0;
+       }
 
        END_OF_SMB
 
@@ -11608,7 +13299,7 @@ typedef struct _smb_function {
        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
 } smb_function;
 
-smb_function smb_dissector[256] = {
+static smb_function smb_dissector[256] = {
   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
@@ -11638,10 +13329,10 @@ smb_function smb_dissector[256] = {
   /* 0x19 */  {dissect_unknown, dissect_unknown},
   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
-  /* 0x1c */  {dissect_unknown, dissect_unknown},
+  /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
-  /* 0x1f */  {dissect_unknown, dissect_unknown},
+  /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
 
   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
   /* 0x21 */  {dissect_unknown, dissect_unknown},
@@ -11649,11 +13340,11 @@ smb_function smb_dissector[256] = {
   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
   /* 0x25 Transaction*/                {dissect_transaction_request, dissect_transaction_response},
-  /* 0x26 Transaction Secondary */  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
-  /* 0x27 */  {dissect_unknown, dissect_unknown},
-  /* 0x28 */  {dissect_unknown, dissect_unknown},
-  /* 0x29 */  {dissect_unknown, dissect_unknown},
-  /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
+  /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
+  /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
+  /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
+  /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
+  /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
@@ -11661,11 +13352,11 @@ smb_function smb_dissector[256] = {
   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
 
   /* 0x30 */  {dissect_unknown, dissect_unknown},
-  /* 0x31 */  {dissect_unknown, dissect_unknown},
+  /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
   /* 0x32 Transaction2*/               {dissect_transaction_request, dissect_transaction_response},
   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
-  /* 0x35 */  {dissect_unknown, dissect_unknown},
+  /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
   /* 0x36 */  {dissect_unknown, dissect_unknown},
   /* 0x37 */  {dissect_unknown, dissect_unknown},
   /* 0x38 */  {dissect_unknown, dissect_unknown},
@@ -11747,9 +13438,9 @@ smb_function smb_dissector[256] = {
 
   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
-  /* 0x82 */  {dissect_unknown, dissect_unknown},
-  /* 0x83 */  {dissect_unknown, dissect_unknown},
-  /* 0x84 */  {dissect_unknown, dissect_unknown},
+  /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
+  /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
+  /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
   /* 0x85 */  {dissect_unknown, dissect_unknown},
   /* 0x86 */  {dissect_unknown, dissect_unknown},
   /* 0x87 */  {dissect_unknown, dissect_unknown},
@@ -11778,12 +13469,13 @@ smb_function smb_dissector[256] = {
   /* 0x9d */  {dissect_unknown, dissect_unknown},
   /* 0x9e */  {dissect_unknown, dissect_unknown},
   /* 0x9f */  {dissect_unknown, dissect_unknown},
+
   /* 0xa0 NT Transaction*/     {dissect_nt_transaction_request, dissect_nt_transaction_response},
   /* 0xa1 NT Trans secondary*/ {dissect_nt_transaction_request, dissect_nt_transaction_response},
   /* 0xa2 NT CreateAndX*/              {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
   /* 0xa3 */  {dissect_unknown, dissect_unknown},
   /* 0xa4 NT Cancel*/          {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
-  /* 0xa5 */  {dissect_unknown, dissect_unknown},
+  /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
   /* 0xa6 */  {dissect_unknown, dissect_unknown},
   /* 0xa7 */  {dissect_unknown, dissect_unknown},
   /* 0xa8 */  {dissect_unknown, dissect_unknown},
@@ -11811,6 +13503,7 @@ smb_function smb_dissector[256] = {
   /* 0xbd */  {dissect_unknown, dissect_unknown},
   /* 0xbe */  {dissect_unknown, dissect_unknown},
   /* 0xbf */  {dissect_unknown, dissect_unknown},
+
   /* 0xc0 Open Print File*/    {dissect_open_print_file_request, dissect_fid},
   /* 0xc1 Write Print File*/   {dissect_write_print_file_request, dissect_empty},
   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
@@ -11828,17 +13521,17 @@ smb_function smb_dissector[256] = {
   /* 0xce */  {dissect_unknown, dissect_unknown},
   /* 0xcf */  {dissect_unknown, dissect_unknown},
 
-  /* 0xd0 */  {dissect_unknown, dissect_unknown},
-  /* 0xd1 */  {dissect_unknown, dissect_unknown},
-  /* 0xd2 */  {dissect_unknown, dissect_unknown},
-  /* 0xd3 */  {dissect_unknown, dissect_unknown},
-  /* 0xd4 */  {dissect_unknown, dissect_unknown},
-  /* 0xd5 */  {dissect_unknown, dissect_unknown},
-  /* 0xd6 */  {dissect_unknown, dissect_unknown},
-  /* 0xd7 */  {dissect_unknown, dissect_unknown},
-  /* 0xd8 */  {dissect_unknown, dissect_unknown},
-  /* 0xd9 */  {dissect_unknown, dissect_unknown},
-  /* 0xda */  {dissect_unknown, dissect_unknown},
+  /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
+  /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
+  /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
+  /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
+  /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
+  /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
+  /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
+  /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
+  /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
+  /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
+  /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
   /* 0xdb */  {dissect_unknown, dissect_unknown},
   /* 0xdc */  {dissect_unknown, dissect_unknown},
   /* 0xdd */  {dissect_unknown, dissect_unknown},
@@ -11881,11 +13574,11 @@ smb_function smb_dissector[256] = {
 };
 
 static int
-dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
+dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
 {
        int old_offset = offset;
        smb_info_t *si;
+
        si = pinfo->private_data;
        if(cmd!=0xff){
                proto_item *cmd_item;
@@ -11893,14 +13586,22 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int
                int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
-                       col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
-                               decode_smb_name(cmd),
-                               (si->request)? "Request" : "Response");
+                       if(first_pdu){
+                               col_append_fstr(pinfo->cinfo, COL_INFO,
+                                       "%s %s",
+                                       decode_smb_name(cmd),
+                                       (si->request)? "Request" : "Response");
+                       } else {
+                               col_append_fstr(pinfo->cinfo, COL_INFO,
+                                       "; %s",
+                                       decode_smb_name(cmd));
+                       }
+
                }
 
                cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
                        "%s %s (0x%02x)",
-                       decode_smb_name(cmd), 
+                       decode_smb_name(cmd),
                        (si->request)?"Request":"Response",
                        cmd);
 
@@ -11917,7 +13618,7 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int
 
 
 /* NOTE: this value_string array will also be used to access data directly by
- * index instead of val_to_str() since 
+ * index instead of val_to_str() since
  * 1, the array will always span every value from 0x00 to 0xff and
  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
  * This means that this value_string array MUST always
@@ -11956,7 +13657,7 @@ static const value_string smb_cmd_vals[] = {
   { 0x1C, "Read MPX Secondary" },
   { 0x1D, "Write Raw" },
   { 0x1E, "Write MPX" },
-  { 0x1F, "SMBwriteBs" },
+  { 0x1F, "Write MPX Secondary" },
   { 0x20, "Write Complete" },
   { 0x21, "unknown-0x21" },
   { 0x22, "Set Information2" },
@@ -11974,7 +13675,7 @@ static const value_string smb_cmd_vals[] = {
   { 0x2E, "Read AndX" },
   { 0x2F, "Write AndX" },
   { 0x30, "unknown-0x30" },
-  { 0x31, "Close And Tree Discover" },
+  { 0x31, "Close And Tree Disconnect" },
   { 0x32, "Transaction2" },
   { 0x33, "Transaction2 Secondary" },
   { 0x34, "Find Close2" },
@@ -12057,7 +13758,7 @@ static const value_string smb_cmd_vals[] = {
   { 0x81, "Search" },
   { 0x82, "Find" },
   { 0x83, "Find Unique" },
-  { 0x84, "SMBfclose" },
+  { 0x84, "Find Close" },
   { 0x85, "unknown-0x85" },
   { 0x86, "unknown-0x86" },
   { 0x87, "unknown-0x87" },
@@ -12090,7 +13791,7 @@ static const value_string smb_cmd_vals[] = {
   { 0xA2, "NT Create AndX" },
   { 0xA3, "unknown-0xA3" },
   { 0xA4, "NT Cancel" },
-  { 0xA5, "unknown-0xA5" },
+  { 0xA5, "NT Rename" },
   { 0xA6, "unknown-0xA6" },
   { 0xA7, "unknown-0xA7" },
   { 0xA8, "unknown-0xA8" },
@@ -12133,14 +13834,14 @@ static const value_string smb_cmd_vals[] = {
   { 0xCD, "unknown-0xCD" },
   { 0xCE, "unknown-0xCE" },
   { 0xCF, "unknown-0xCF" },
-  { 0xD0, "SMBsends" },
-  { 0xD1, "SMBsendb" },
-  { 0xD2, "SMBfwdname" },
-  { 0xD3, "SMBcancelf" },
-  { 0xD4, "SMBgetmac" },
-  { 0xD5, "SMBsendstrt" },
-  { 0xD6, "SMBsendend" },
-  { 0xD7, "SMBsendtxt" },
+  { 0xD0, "Send Single Block Message" },
+  { 0xD1, "Send Broadcast Message" },
+  { 0xD2, "Forward User Name" },
+  { 0xD3, "Cancel Forward" },
+  { 0xD4, "Get Machine Name" },
+  { 0xD5, "Send Start of Multi-block Message" },
+  { 0xD6, "Send End of Multi-block Message" },
+  { 0xD7, "Send Text of Multi-block Message" },
   { 0xD8, "SMBreadbulk" },
   { 0xD9, "SMBwritebulk" },
   { 0xDA, "SMBwritebulkdata" },
@@ -12188,7 +13889,7 @@ static char *decode_smb_name(unsigned char cmd)
 {
   return(smb_cmd_vals[cmd].strptr);
 }
+
 
 
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -12197,7 +13898,7 @@ static char *decode_smb_name(unsigned char cmd)
 
 
 static void
-free_hash_tables(gpointer ctarg, gpointer user_data)
+free_hash_tables(gpointer ctarg, gpointer user_data _U_)
 {
        conv_tables_t *ct = ctarg;
 
@@ -12207,6 +13908,8 @@ free_hash_tables(gpointer ctarg, gpointer user_data)
                g_hash_table_destroy(ct->matched);
        if (ct->dcerpc_fid_to_frame)
                g_hash_table_destroy(ct->dcerpc_fid_to_frame);
+       if (ct->tid_service)
+               g_hash_table_destroy(ct->tid_service);
 }
 
 static void
@@ -12269,159 +13972,6 @@ smb_init_protocol(void)
            G_ALLOC_ONLY);
 }
 
-/* Max string length for displaying Unicode strings.  */
-#define        MAX_UNICODE_STR_LEN     256
-
-
-/* Turn a little-endian Unicode '\0'-terminated string into a string we
-   can display.
-   XXX - for now, we just handle the ISO 8859-1 characters.
-   If exactlen==TRUE then us_lenp contains the exact len of the string in
-   bytes. It might not be null terminated !
-   bc specifies the number of bytes in the byte parameters; Windows 2000,
-   at least, appears, in some cases, to put only 1 byte of 0 at the end
-   of a Unicode string if the byte count
-*/
-static gchar *
-unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
-                  guint16 bc)
-{
-  static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
-  static gchar *cur;
-  gchar        *p;
-  guint16       uchar;
-  int           len;
-  int           us_len;
-  int           overflow = 0;
-
-  if (cur == &str[0][0]) {
-    cur = &str[1][0];
-  } else if (cur == &str[1][0]) {  
-    cur = &str[2][0];
-  } else {  
-    cur = &str[0][0];
-  }
-  p = cur;
-  len = MAX_UNICODE_STR_LEN;
-  us_len = 0;
-  for (;;) {
-    if (bc == 0)
-      break;
-    if (bc == 1) {
-      /* XXX - explain this */
-      if (!exactlen)
-        us_len += 1;   /* this is a one-byte null terminator */
-      break;
-    }
-    uchar = tvb_get_letohs(tvb, offset);
-    if (uchar == 0) {
-      us_len += 2;     /* this is a two-byte null terminator */
-      break;
-    }
-    if (len > 0) {
-      if ((uchar & 0xFF00) == 0)
-        *p++ = uchar;  /* ISO 8859-1 */
-      else
-        *p++ = '?';    /* not 8859-1 */
-      len--;
-    } else
-      overflow = 1;
-    offset += 2;
-    bc -= 2;
-    us_len += 2;
-    if(exactlen){
-      if(us_len>= *us_lenp){
-        break;
-      }
-    }
-  }
-  if (overflow) {
-    /* Note that we're not showing the full string.  */
-    *p++ = '.';
-    *p++ = '.';
-    *p++ = '.';
-  }
-  *p = '\0';
-  *us_lenp = us_len;
-  return cur;
-}
-
-/* nopad == TRUE : Do not add any padding before this string
- * exactlen == TRUE : len contains the exact len of the string in bytes.
- * bc: pointer to variable with amount of data left in the byte parameters
- *   region
- */
-static const gchar *
-get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
-    packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
-    guint16 *bcp)
-{
-  static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
-  static gchar *cur;
-  const gchar *string;
-  int string_len;
-  smb_info_t *si;
-  int copylen;
-
-  if (*bcp == 0) {
-    /* Not enough data in buffer */
-    return NULL;
-  }
-  si = pinfo->private_data;
-  if (si->unicode) {
-    if ((!nopad) && (*offsetp % 2)) {
-      /*
-       * XXX - this should be an offset relative to the beginning of the SMB,
-       * not an offset relative to the beginning of the frame; if the stuff
-       * before the SMB has an odd number of bytes, an offset relative to
-       * the beginning of the frame will give the wrong answer.
-       */
-      (*offsetp)++;   /* Looks like a pad byte there sometimes */
-      (*bcp)--;
-      if (*bcp == 0) {
-        /* Not enough data in buffer */
-        return NULL;
-      }
-    }
-    if(exactlen){
-      string_len = *len;
-      string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
-    } else {
-      string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
-    }
-  } else {
-    if(exactlen){
-      /*
-       * The string we return must be null-terminated.
-       */
-      if (cur == &str[0][0]) {
-        cur = &str[1][0];
-      } else if (cur == &str[1][0]) {  
-        cur = &str[2][0];
-      } else {  
-        cur = &str[0][0];
-      }
-      copylen = *len;
-      if (copylen > MAX_UNICODE_STR_LEN)
-        copylen = MAX_UNICODE_STR_LEN;
-      tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
-      cur[copylen] = '\0';
-      if (copylen > MAX_UNICODE_STR_LEN)
-        strcat(cur, "...");
-      string_len = *len;
-      string = cur;
-    } else {
-      string_len = tvb_strsize(tvb, *offsetp);
-      string = tvb_get_ptr(tvb, *offsetp, string_len);
-    }
-  }
-  *len = string_len;
-  return string;
-}
-
-
-
 static const value_string errcls_types[] = {
   { SMB_SUCCESS, "Success"},
   { SMB_ERRDOS, "DOS Error"},
@@ -12445,7 +13995,7 @@ const value_string DOS_errors[] = {
   {SMBE_badenv, "Invalid environment"},
   {SMBE_badaccess, "Invalid open mode"},
   {SMBE_baddata, "Invalid data (only from ioctl call)"},
-  {SMBE_res, "Reserved error code?"}, 
+  {SMBE_res, "Reserved error code?"},
   {SMBE_baddrive, "Invalid drive"},
   {SMBE_remcd, "Attempt to delete current directory"},
   {SMBE_diffdevice, "Rename/move across different filesystems"},
@@ -12456,7 +14006,8 @@ const value_string DOS_errors[] = {
   {SMBE_nosuchshare, "Requested share does not exist"},
   {SMBE_filexists, "File in operation already exists"},
   {SMBE_cannotopen, "Cannot open the file specified"},
-  {SMBE_unknownlevel, "Unknown level??"},
+  {SMBE_unknownlevel, "Unknown info level"},
+  {SMBE_invalidname, "Invalid name"},
   {SMBE_badpipe, "Named pipe invalid"},
   {SMBE_pipebusy, "All instances of pipe are busy"},
   {SMBE_pipeclosing, "Named pipe close in progress"},
@@ -12476,6 +14027,10 @@ const value_string DOS_errors[] = {
   {SMBE_invalidenvironment, "Invalid environment"},
   {SMBE_printerdriverinuse, "Printer driver in use"},
   {SMBE_invalidparam, "Invalid parameter"},
+  {SMBE_invalidformsize, "Invalid form size"},
+  {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
+  {SMBE_invalidowner, "Invalid owner"},
+  {SMBE_nomoreitems, "No more items"},
   {0, NULL}
   };
 
@@ -12526,18 +14081,18 @@ static const value_string HRD_errors[] = {
   {SMBE_badcmd, "Unknown command"},
   {SMBE_data, "Data (CRC) error"},
   {SMBE_badreq, "Bad request structure length"},
-  {SMBE_seek, "Seek error???"},
-  {SMBE_badmedia, "Bad media???"},
-  {SMBE_badsector, "Bad sector???"},
-  {SMBE_nopaper, "No paper in printer???"},
-  {SMBE_write, "Write error???"},
-  {SMBE_read, "Read error???"},
-  {SMBE_general, "General error???"},
+  {SMBE_seek, "Seek error"},
+  {SMBE_badmedia, "Unknown media type"},
+  {SMBE_badsector, "Sector not found"},
+  {SMBE_nopaper, "Printer out of paper"},
+  {SMBE_write, "Write fault"},
+  {SMBE_read, "Read fault"},
+  {SMBE_general, "General failure"},
   {SMBE_badshare, "A open conflicts with an existing open"},
-  {SMBE_lock, "Lock/unlock error"},
-  {SMBE_wrongdisk,  "Wrong disk???"},
-  {SMBE_FCBunavail, "FCB unavailable???"},
-  {SMBE_sharebufexc, "Share buffer excluded???"},
+  {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
+  {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
+  {SMBE_FCBunavail, "No FCBs are available to process request"},
+  {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
   {SMBE_diskfull, "Disk full???"},
   {0, NULL}
 };
@@ -12575,6 +14130,131 @@ static char *decode_smb_error(guint8 errcls, guint16 errcode)
 
 }
 
+
+/* These are the MS country codes from
+
+       http://www.unicode.org/unicode/onlinedat/countries.html
+
+   For countries that share the same number, I choose to use only the
+   name of the largest country. Apologies for this. If this offends you,
+   here is the table to change that.
+
+   This also includes the code of 0 for "Default", which isn't in
+   that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
+   header file.  Presumably it means "don't override the setting
+   on the user's machine".
+
+   Future versions of Microsoft's "winnls.h" header file might include
+   additional codes; the current version matches the Unicode Consortium's
+   table.
+*/
+const value_string ms_country_codes[] = {
+       {  0,   "Default"},
+       {  1,   "USA"},
+       {  2,   "Canada"},
+       {  7,   "Russia"},
+       { 20,   "Egypt"},
+       { 27,   "South Africa"},
+       { 30,   "Greece"},
+       { 31,   "Netherlands"},
+       { 32,   "Belgium"},
+       { 33,   "France"},
+       { 34,   "Spain"},
+       { 36,   "Hungary"},
+       { 39,   "Italy"},
+       { 40,   "Romania"},
+       { 41,   "Switzerland"},
+       { 43,   "Austria"},
+       { 44,   "United Kingdom"},
+       { 45,   "Denmark"},
+       { 46,   "Sweden"},
+       { 47,   "Norway"},
+       { 48,   "Poland"},
+       { 49,   "Germany"},
+       { 51,   "Peru"},
+       { 52,   "Mexico"},
+       { 54,   "Argentina"},
+       { 55,   "Brazil"},
+       { 56,   "Chile"},
+       { 57,   "Colombia"},
+       { 58,   "Venezuela"},
+       { 60,   "Malaysia"},
+       { 61,   "Australia"},
+       { 62,   "Indonesia"},
+       { 63,   "Philippines"},
+       { 64,   "New Zealand"},
+       { 65,   "Singapore"},
+       { 66,   "Thailand"},
+       { 81,   "Japan"},
+       { 82,   "South Korea"},
+       { 84,   "Viet Nam"},
+       { 86,   "China"},
+       { 90,   "Turkey"},
+       { 91,   "India"},
+       { 92,   "Pakistan"},
+       {212,   "Morocco"},
+       {213,   "Algeria"},
+       {216,   "Tunisia"},
+       {218,   "Libya"},
+       {254,   "Kenya"},
+       {263,   "Zimbabwe"},
+       {298,   "Faroe Islands"},
+       {351,   "Portugal"},
+       {352,   "Luxembourg"},
+       {353,   "Ireland"},
+       {354,   "Iceland"},
+       {355,   "Albania"},
+       {358,   "Finland"},
+       {359,   "Bulgaria"},
+       {370,   "Lithuania"},
+       {371,   "Latvia"},
+       {372,   "Estonia"},
+       {374,   "Armenia"},
+       {375,   "Belarus"},
+       {380,   "Ukraine"},
+       {381,   "Serbia"},
+       {385,   "Croatia"},
+       {386,   "Slovenia"},
+       {389,   "Macedonia"},
+       {420,   "Czech Republic"},
+       {421,   "Slovak Republic"},
+       {501,   "Belize"},
+       {502,   "Guatemala"},
+       {503,   "El Salvador"},
+       {504,   "Honduras"},
+       {505,   "Nicaragua"},
+       {506,   "Costa Rica"},
+       {507,   "Panama"},
+       {591,   "Bolivia"},
+       {593,   "Ecuador"},
+       {595,   "Paraguay"},
+       {598,   "Uruguay"},
+       {673,   "Brunei Darussalam"},
+       {852,   "Hong Kong"},
+       {853,   "Macau"},
+       {886,   "Taiwan"},
+       {960,   "Maldives"},
+       {961,   "Lebanon"},
+       {962,   "Jordan"},
+       {963,   "Syria"},
+       {964,   "Iraq"},
+       {965,   "Kuwait"},
+       {966,   "Saudi Arabia"},
+       {967,   "Yemen"},
+       {968,   "Oman"},
+       {971,   "United Arab Emirates"},
+       {972,   "Israel"},
+       {973,   "Bahrain"},
+       {974,   "Qatar"},
+       {976,   "Mongolia"},
+       {981,   "Iran"},
+       {994,   "Azerbaijan"},
+       {995,   "Georgia"},
+       {996,   "Kyrgyzstan"},
+
+       {0,     NULL}
+};
+
 /*
  * NT error codes.
  *
@@ -12690,6 +14370,7 @@ const value_string NT_errors[] = {
   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
   { 0x80000026, "STATUS_LONGJUMP" },
+  { 0x80040111, "MAPI_E_LOGON_FAILED" },
   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
   { 0x80090301, "SEC_E_INVALID_HANDLE" },
   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
@@ -13465,7 +15146,7 @@ static const true_false_string tfs_smb_flags_response = {
 };
 
 static int
-dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -13497,7 +15178,7 @@ dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, in
 }
 
 
+
 static const true_false_string tfs_smb_flags2_long_names_allowed = {
        "Long file names are allowed in the response",
        "Long file names are not allowed in the response"
@@ -13535,7 +15216,7 @@ static const true_false_string tfs_smb_flags2_string = {
        "Strings are ASCII"
 };
 static int
-dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -13589,12 +15270,12 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        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;
-       guint16 uid, pid, tid, mid;
+       guint32 nt_status = 0;
+       guint8 errclass = 0;
+       guint16 errcode = 0;
        guint32 pid_mid;
        conversation_t *conversation;
+       nstime_t ns;
 
        top_tree=parent_tree;
 
@@ -13608,7 +15289,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
            || (tvb_get_guint8(tvb, 3) != 'B') ){
                return FALSE;
        }
-        
+
        if (check_col(pinfo->cinfo, COL_PROTOCOL)){
                col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
        }
@@ -13627,20 +15308,20 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        } else {
                si.unicode = FALSE;
        }
-       tid = tvb_get_letohs(tvb, offset+24);
-       pid = tvb_get_letohs(tvb, offset+26);
-       uid = tvb_get_letohs(tvb, offset+28);
-       mid = tvb_get_letohs(tvb, offset+30);
-       pid_mid = (pid << 16) | mid;
+       si.tid = tvb_get_letohs(tvb, offset+24);
+       si.pid = tvb_get_letohs(tvb, offset+26);
+       si.uid = tvb_get_letohs(tvb, offset+28);
+       si.mid = tvb_get_letohs(tvb, offset+30);
+       pid_mid = (si.pid << 16) | si.mid;
        si.info_level = -1;
        si.info_count = -1;
 
        if (parent_tree) {
-               item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
+               item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
                        -1, FALSE);
                tree = proto_item_add_subtree(item, ett_smb);
 
-               hitem = proto_tree_add_text(tree, tvb, offset, 32, 
+               hitem = proto_tree_add_text(tree, tvb, offset, 32,
                        "SMB Header");
 
                htree = proto_item_add_subtree(hitem, ett_smb_hdr);
@@ -13649,38 +15330,41 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
        offset += 4;  /* Skip the marker */
 
-       /* find which conversation we are part of and get the tables for that 
+       /* find which conversation we are part of and get the tables for that
           conversation*/
        conversation = find_conversation(&pinfo->src, &pinfo->dst,
                 pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
-       if(conversation){
-               si.ct=conversation_get_proto_data(conversation, proto_smb);
-       } else {
-               /* OK this is a new conversation, we must create it
-                  and attach appropriate data (matched and unmatched 
-                  table for this conversation)
-               */
-               conversation = conversation_new(&pinfo->src, &pinfo->dst, 
+       if(!conversation){
+               /* OK this is a new conversation so lets create it */
+               conversation = conversation_new(&pinfo->src, &pinfo->dst,
                        pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+       }
+       /* 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 = g_mem_chunk_alloc(conv_tables_chunk);
                conv_tables = g_slist_prepend(conv_tables, si.ct);
-               si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
+               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, 
+               si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
                        smb_saved_info_equal_unmatched);
                si.ct->dcerpc_fid_to_frame=g_hash_table_new(
-                       smb_saved_info_hash_unmatched, 
+                       smb_saved_info_hash_unmatched,
+                       smb_saved_info_equal_unmatched);
+               si.ct->tid_service=g_hash_table_new(
+                       smb_saved_info_hash_unmatched,
                        smb_saved_info_equal_unmatched);
                conversation_add_proto_data(conversation, proto_smb, si.ct);
        }
 
        if( (si.request)
-           &&  (mid==0)
-           &&  (uid==0)
-           &&  (pid==0)
-           &&  (tid==0) ){
+           &&  (si.mid==0)
+           &&  (si.uid==0)
+           &&  (si.pid==0)
+           &&  (si.tid==0) ){
                /* this is a broadcast SMB packet, there will not be a reply.
-                  We dont need to do anything 
+                  We dont need to do anything
                */
                si.unidir = TRUE;
        } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
@@ -13699,7 +15383,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                   request/response matching to get messed up.
 
                   The only thing we do in this case is trying to find which original
-                  request we match with and insert an entry for this "special" 
+                  request we match with and insert an entry for this "special"
                   request for later reference. We continue to reference the original
                   requests smb_saved_info_t but we dont touch it or change anything
                   in it.
@@ -13708,7 +15392,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                si.unidir = TRUE;  /*we dont expect an answer to this one*/
 
                if(!pinfo->fd->flags.visited){
-                       /* try to find which original call we match and if we 
+                       /* try to find which original call we match and if we
                           find it add us to the matched table. Dont touch
                           anything else since we dont want this one to mess
                           up the request/response matching. We still consider
@@ -13748,13 +15432,13 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                if(sip && sip->frame_req){
                        switch(si.cmd){
                        case SMB_COM_NT_CANCEL:
-                               proto_tree_add_uint(htree, hf_smb_cancel_to, 
+                               proto_tree_add_uint(htree, hf_smb_cancel_to,
                                                    tvb, 0, 0, sip->frame_req);
                                break;
                        case SMB_COM_TRANSACTION_SECONDARY:
                        case SMB_COM_TRANSACTION2_SECONDARY:
                        case SMB_COM_NT_TRANSACT_SECONDARY:
-                               proto_tree_add_uint(htree, hf_smb_continuation_to, 
+                               proto_tree_add_uint(htree, hf_smb_continuation_to,
                                                    tvb, 0, 0, sip->frame_req);
                                break;
                        }
@@ -13776,46 +15460,70 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                si.unidir = FALSE;
 
                if(!pinfo->fd->flags.visited){
-                       /* first see if we find an unmatched smb "equal" to 
-                          the current one 
+                       /* first see if we find an unmatched smb "equal" to
+                          the current one
                        */
                        sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
                        if(sip!=NULL){
-                               if(si.request){
-                                       /* ok, we are processing an SMB
-                                          request but there was already
-                                          another "identical" smb resuest
-                                          we had not matched yet.
-                                          This must mean that either we have
-                                          a retransmission or that the
-                                          response to the previous one was
-                                          lost and the client has reused
-                                          the MID for this conversation.
-                                          In either case it's not much more
-                                          we can do than forget the old
-                                          request and concentrate on the 
+                               gboolean cmd_match=FALSE;
+
+                               /*
+                                * Make sure the SMB we found was the
+                                * same command, or a different command
+                                * that's another valid type of reply
+                                * to that command.
+                                */
+                               if(si.cmd==sip->cmd){
+                                       cmd_match=TRUE;
+                               }
+                               else if(si.cmd==SMB_COM_NT_CANCEL){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY)
+                                    && (sip->cmd==SMB_COM_TRANSACTION)){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY)
+                                    && (sip->cmd==SMB_COM_TRANSACTION2)){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)
+                                    && (sip->cmd==SMB_COM_NT_TRANSACT)){
+                                       cmd_match=TRUE;
+                               }
+
+                               if( (si.request) || (!cmd_match) ) {
+                                       /* If we are processing an SMB request but there was already
+                                          another "identical" smb resuest we had not matched yet.
+                                          This must mean that either we have a retransmission or that the
+                                          response to the previous one was lost and the client has reused
+                                          the MID for this conversation. In either case it's not much more
+                                          we can do than forget the old request and concentrate on the
                                           present one instead.
+
+                                          We also do this cleanup if we see that the cmd in the original
+                                          request in sip->cmd is not compatible with the current cmd.
+                                          This is to prevent matching errors such as if there were two
+                                          SMBs of different cmds but with identical MID and PID values and
+                                          if ethereal lost the first reply and the second request.
                                        */
                                        g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
+                                       sip=NULL; /* XXX should free it as well */
                                } else {
                                        /* we have found a response to some request we have seen earlier.
                                           What we do now depends on whether this is the first response
-                                          to that request we see (id frame_res==0) or not. 
+                                          to that request we see (id frame_res==0) or not.
                                        */
                                        if(sip->frame_res==0){
                                                /* ok it is the first response we have seen to this packet */
                                                sip->frame_res = pinfo->fd->num;
                                                new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
-                                               new_key->frame = sip->frame_req;
-                                               new_key->pid_mid = pid_mid;
-                                               g_hash_table_insert(si.ct->matched, new_key, sip);
-                                               new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
                                                new_key->frame = sip->frame_res;
                                                new_key->pid_mid = pid_mid;
                                                g_hash_table_insert(si.ct->matched, new_key, sip);
                                        } else {
                                                /* we have already seen another response to this one, but
-                                                  register it anyway so we see which request it matches 
+                                                  register it anyway so we see which request it matches
                                                */
                                                new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
                                                new_key->frame = pinfo->fd->num;
@@ -13828,8 +15536,20 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                sip = g_mem_chunk_alloc(smb_saved_info_chunk);
                                sip->frame_req = pinfo->fd->num;
                                sip->frame_res = 0;
+                               sip->req_time.secs=pinfo->fd->abs_secs;
+                               sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
+                               sip->flags = 0;
+                               if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
+                                   == (void *)TID_IPC) {
+                                       sip->flags |= SMB_SIF_TID_IS_IPC;
+                               }
+                               sip->cmd = si.cmd;
                                sip->extra_info = NULL;
                                g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
+                               new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
+                               new_key->frame = sip->frame_req;
+                               new_key->pid_mid = pid_mid;
+                               g_hash_table_insert(si.ct->matched, new_key, sip);
                        }
                } else {
                        /* we have seen this packet before; check the
@@ -13861,8 +15581,17 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                        if (sip->frame_res != 0)
                                proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
                } else {
-                       if (sip->frame_req != 0)
+                       if (sip->frame_req != 0) {
                                proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
+                               ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
+                               ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
+                               if(ns.nsecs<0){
+                                       ns.nsecs+=1000000000;
+                                       ns.secs--;
+                               }
+                               proto_tree_add_time(htree, hf_smb_time, tvb,
+                                   0, 0, &ns);
+                       }
                }
        }
 
@@ -13903,10 +15632,10 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        }
 
        /* flags */
-       offset = dissect_smb_flags(tvb, pinfo, htree, offset);
+       offset = dissect_smb_flags(tvb, htree, offset);
 
        /* flags2 */
-       offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
+       offset = dissect_smb_flags2(tvb, htree, offset);
 
        /*
         * The document at
@@ -13942,23 +15671,23 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        offset += 12;
 
        /* TID */
-       proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
+       proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
        offset += 2;
 
        /* PID */
-       proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
+       proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
        offset += 2;
 
        /* UID */
-       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
+       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
        offset += 2;
 
        /* MID */
-       proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, mid);
+       proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
        offset += 2;
 
        pinfo->private_data = &si;
-        dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
+        dissect_smb_command(tvb, pinfo, offset, tree, si.cmd, TRUE);
 
        /* Append error info from this packet to info string. */
        if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
@@ -13967,13 +15696,14 @@ 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 != 0) {
+                       if ((nt_status & 0xC0000000) == 0xC0000000) {
                                /*
                                 * Yes.
                                 */
                                col_append_fstr(
                                        pinfo->cinfo, COL_INFO, ", Error: %s",
-                                       val_to_str(nt_status, NT_errors, "%s"));
+                                       val_to_str(nt_status, NT_errors,
+                                           "Unknown (0x%08X)"));
                        }
                } else {
                        /*
@@ -14014,6 +15744,10 @@ proto_register_smb(void)
                { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
                NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
 
+       { &hf_smb_time,
+               { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
+               NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
+
        { &hf_smb_response_in,
                { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
                NULL, 0, "The response to this packet is in this packet", HFILL }},
@@ -14162,6 +15896,10 @@ proto_register_smb(void)
                { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
                NULL, 0, "The server's primary domain", HFILL }},
 
+       { &hf_smb_server,
+               { "Server", "smb.server", FT_STRING, BASE_NONE,
+               NULL, 0, "The name of the DC/server", HFILL }},
+
        { &hf_smb_max_raw_buf_size,
                { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
                NULL, 0, "Maximum raw buffer size", HFILL }},
@@ -14358,10 +16096,38 @@ proto_register_smb(void)
                { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
                TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
 
-       { &hf_smb_move_files_moved,
-               { "Files Moved", "smb.move.files_moved", FT_UINT16, BASE_DEC,
+       { &hf_smb_files_moved,
+               { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
                NULL, 0, "Number of files moved", HFILL }},
 
+       { &hf_smb_copy_flags_file,
+               { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
+               TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
+
+       { &hf_smb_copy_flags_dir,
+               { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
+               TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
+
+       { &hf_smb_copy_flags_dest_mode,
+               { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
+               TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
+
+       { &hf_smb_copy_flags_source_mode,
+               { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
+               TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
+
+       { &hf_smb_copy_flags_verify,
+               { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
+               TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
+
+       { &hf_smb_copy_flags_tree_copy,
+               { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
+               TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
+
+       { &hf_smb_copy_flags_ea_action,
+               { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
+               TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
+
        { &hf_smb_count,
                { "Count", "smb.count", FT_UINT32, BASE_DEC,
                NULL, 0, "Count number of items/bytes", HFILL }},
@@ -14384,87 +16150,87 @@ proto_register_smb(void)
 
        { &hf_smb_file_attr_read_only_16bit,
                { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
+               TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_attr_read_only_8bit,
                { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
-               TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
+               TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_attr_hidden_16bit,
                { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
+               TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_attr_hidden_8bit,
                { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
-               TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
+               TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_attr_system_16bit,
                { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
+               TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_attr_system_8bit,
                { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
-               TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
+               TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_attr_volume_16bit,
                { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
+               TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
 
        { &hf_smb_file_attr_volume_8bit,
                { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
-               TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
+               TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
 
        { &hf_smb_file_attr_directory_16bit,
                { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
+               TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_attr_directory_8bit,
                { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
-               TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
+               TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_attr_archive_16bit,
                { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
+               TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_attr_archive_8bit,
                { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
-               TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
+               TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_attr_device,
                { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
+               TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
 
        { &hf_smb_file_attr_normal,
                { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
+               TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
 
        { &hf_smb_file_attr_temporary,
                { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
+               TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
 
        { &hf_smb_file_attr_sparse,
                { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
+               TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
 
        { &hf_smb_file_attr_reparse,
                { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
+               TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
 
        { &hf_smb_file_attr_compressed,
                { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
+               TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
 
        { &hf_smb_file_attr_offline,
                { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
+               TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
 
        { &hf_smb_file_attr_not_content_indexed,
                { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
+               TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
 
        { &hf_smb_file_attr_encrypted,
                { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
-               TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
+               TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
 
        { &hf_smb_file_size,
                { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
@@ -14472,27 +16238,27 @@ proto_register_smb(void)
 
        { &hf_smb_search_attribute_read_only,
                { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
-               TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
+               TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
 
        { &hf_smb_search_attribute_hidden,
                { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
-               TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
+               TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
 
        { &hf_smb_search_attribute_system,
                { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
-               TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
+               TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
 
        { &hf_smb_search_attribute_volume,
                { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
-               TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
+               TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
 
        { &hf_smb_search_attribute_directory,
                { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
-               TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
+               TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
 
        { &hf_smb_search_attribute_archive,
                { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
-               TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
+               TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
 
        { &hf_smb_access_mode,
                { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
@@ -14518,6 +16284,66 @@ proto_register_smb(void)
                { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
                NULL, 0, "Creation Time", HFILL }},
 
+       { &hf_smb_modify_time,
+               { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
+                 NULL, 0, "Modification Time", HFILL }},
+
+       { &hf_smb_backup_time,
+               { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
+                 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}},
+
+       { &hf_smb_mac_alloc_block_size,
+               { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
+                 NULL, 0, "Allocation Block Size", HFILL}},
+
+       { &hf_smb_mac_free_block_count,
+               { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
+                 NULL, 0, "Free Block Count", HFILL}},
+
+       { &hf_smb_mac_root_file_count,
+               { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
+               NULL, 0, "Root File Count", HFILL}},
+
+       { &hf_smb_mac_root_dir_count,
+         { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
+           NULL, 0, "Root Directory Count", HFILL}},
+
+       { &hf_smb_mac_file_count,
+         { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
+           NULL, 0, "File Count", HFILL}},
+
+       { &hf_smb_mac_dir_count,
+         { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
+           NULL, 0, "Directory Count", HFILL}},
+
+       { &hf_smb_mac_support_flags,
+         { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
+           NULL, 0, "Mac Support Flags", HFILL}},
+
+       { &hf_smb_mac_sup_access_ctrl,
+         { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
+           TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
+
+       { &hf_smb_mac_sup_getset_comments,
+         { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
+           TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
+
+       { &hf_smb_mac_sup_desktopdb_calls,
+         { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
+           TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
+
+       { &hf_smb_mac_sup_unique_ids,
+         { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
+           TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
+
+       { &hf_smb_mac_sup_streams,
+         { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
+           TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
+
        { &hf_smb_create_dos_date,
                { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
                NULL, 0, "Create Date, SMB_DATE format", HFILL }},
@@ -14558,6 +16384,10 @@ proto_register_smb(void)
                { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
                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}},
+
        { &hf_smb_total_data_len,
                { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
                NULL, 0, "Total length of data", HFILL }},
@@ -14666,6 +16496,10 @@ proto_register_smb(void)
                { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
                NULL, 0, "Resume Key length", 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,
                NULL, 0, "Cookie, must not be modified by the client", HFILL }},
@@ -15179,91 +17013,63 @@ proto_register_smb(void)
 
        { &hf_smb_file_eattr_read_only,
                { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
+               TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_eattr_hidden,
                { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
+               TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_eattr_system,
                { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
+               TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_eattr_volume,
                { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
+               TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
 
        { &hf_smb_file_eattr_directory,
                { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
+               TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_eattr_archive,
                { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
+               TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_eattr_device,
                { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
+               TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
 
        { &hf_smb_file_eattr_normal,
                { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
+               TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
 
        { &hf_smb_file_eattr_temporary,
                { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
+               TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
 
        { &hf_smb_file_eattr_sparse,
                { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
+               TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
 
        { &hf_smb_file_eattr_reparse,
                { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
+               TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
 
        { &hf_smb_file_eattr_compressed,
                { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
+               TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
 
        { &hf_smb_file_eattr_offline,
                { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
+               TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
 
        { &hf_smb_file_eattr_not_content_indexed,
                { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
+               TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
 
        { &hf_smb_file_eattr_encrypted,
                { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
-
-       { &hf_smb_file_eattr_write_through,
-               { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
-
-       { &hf_smb_file_eattr_no_buffering,
-               { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
-
-       { &hf_smb_file_eattr_random_access,
-               { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
-
-       { &hf_smb_file_eattr_sequential_scan,
-               { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
-
-       { &hf_smb_file_eattr_delete_on_close,
-               { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
-
-       { &hf_smb_file_eattr_backup_semantics,
-               { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
-
-       { &hf_smb_file_eattr_posix_semantics,
-               { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
-               TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
+               TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
 
        { &hf_smb_sec_desc_len,
                { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
@@ -15297,6 +17103,10 @@ proto_register_smb(void)
                { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
                VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
 
+       { &hf_smb_file_id,
+               { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
+               NULL, 0, "Server unique file ID", HFILL }},
+
        { &hf_smb_ea_error_offset,
                { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
                NULL, 0, "Offset into EA list if EA error", HFILL }},
@@ -15323,7 +17133,7 @@ proto_register_smb(void)
 
        { &hf_smb_setup_len,
                { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
-               NULL, 0, "Length of prionter setup data", HFILL }},
+               NULL, 0, "Length of printer setup data", HFILL }},
 
        { &hf_smb_print_mode,
                { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
@@ -15369,6 +17179,34 @@ proto_register_smb(void)
                { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
                NULL, 0, "First queue entry to return", HFILL }},
 
+       { &hf_smb_originator_name,
+               { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Name of sender of message", HFILL }},
+
+       { &hf_smb_destination_name,
+               { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Name of recipient of message", HFILL }},
+
+       { &hf_smb_message_len,
+               { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
+               NULL, 0, "Length of message", HFILL }},
+
+       { &hf_smb_message,
+               { "Message", "smb.message", FT_STRING, BASE_NONE,
+               NULL, 0, "Message text", HFILL }},
+
+       { &hf_smb_mgid,
+               { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
+               NULL, 0, "Message group ID for multi-block messages", HFILL }},
+
+       { &hf_smb_forwarded_name,
+               { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Recipient name being forwarded", HFILL }},
+
+       { &hf_smb_machine_name,
+               { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Name of target machine", HFILL }},
+
        { &hf_smb_cancel_to,
                { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
                NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
@@ -15407,7 +17245,7 @@ proto_register_smb(void)
 
        { &hf_smb_ff2_resume,
                { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
-               TFS(&tfs_ff2_resume), 0x0004, "Return resume keys for each entry found", HFILL }},
+               TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
 
        { &hf_smb_ff2_close_eos,
                { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
@@ -15425,6 +17263,16 @@ proto_register_smb(void)
                { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
                VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
 
+#if 0
+       { &hf_smb_sfi_writetru,
+               { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
+               TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
+
+       { &hf_smb_sfi_caching,
+               { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
+               TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
+#endif
+
        { &hf_smb_storage_type,
                { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
                NULL, 0, "Type of storage", HFILL }},
@@ -15438,9 +17286,17 @@ proto_register_smb(void)
                NULL, 0, "Latest referral version number understood", HFILL }},
 
        { &hf_smb_qfsi_information_level,
-               { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
+               { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
                VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
 
+       { &hf_smb_nt_rename_level,
+               { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
+               VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
+
+       { &hf_smb_cluster_count,
+               { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
+               NULL, 0, "Number of clusters", HFILL }},
+
        { &hf_smb_ea_size,
                { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
                NULL, 0, "Size of file's EA information", HFILL }},
@@ -15573,6 +17429,18 @@ proto_register_smb(void)
                { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
                NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
 
+       { &hf_smb_fn_information_level,
+               { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
+               NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
+
+       { &hf_smb_monitor_handle,
+               { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
+               NULL, 0, "Handle for Find Notify operations", HFILL }},
+
+       { &hf_smb_change_count,
+               { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
+               NULL, 0, "Number of changes to wait for", HFILL }},
+
        { &hf_smb_file_index,
                { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
                NULL, 0, "File index", HFILL }},
@@ -15621,6 +17489,26 @@ proto_register_smb(void)
                { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
                NULL, 0, "Number of free allocation units", HFILL }},
 
+       { &hf_smb_caller_free_alloc_units64,
+               { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
+               NULL, 0, "Number of caller free allocation units", HFILL }},
+
+       { &hf_smb_actual_free_alloc_units64,
+               { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
+               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 }},
+
+       { &hf_smb_hard_quota_limit,
+               { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
+               NULL, 0, "Hard Quota limit", HFILL }},
+
+       { &hf_smb_user_quota_used,
+               { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
+               NULL, 0, "How much Quota is used by this user", HFILL }},
+
        { &hf_smb_max_name_len,
                { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
                NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
@@ -15713,6 +17601,10 @@ proto_register_smb(void)
                { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
                NULL, 0, "Number of ACE structures for this ACL", HFILL }},
 
+       { &hf_smb_user_quota_offset,
+               { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
+               NULL, 0, "Relative offset to next user quota structure", HFILL }},
+
        { &hf_smb_ace_type,
                { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
                VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
@@ -15750,7 +17642,7 @@ proto_register_smb(void)
                TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
 
        { &hf_smb_sec_desc_type_owner_defaulted,
-               { "Onwer Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
+               { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
                TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
 
        { &hf_smb_sec_desc_type_group_defaulted,
@@ -15801,6 +17693,49 @@ proto_register_smb(void)
                { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
                TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
 
+       { &hf_smb_quota_flags_deny_disk,
+               { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
+
+       { &hf_smb_quota_flags_log_limit,
+               { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
+
+       { &hf_smb_quota_flags_log_warning,
+               { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
+
+       { &hf_smb_quota_flags_enabled,
+               { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
+
+       { &hf_smb_segment_overlap,
+               { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Fragment overlaps with other fragments", HFILL }},
+
+       { &hf_smb_segment_overlap_conflict,
+               { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Overlapping fragments contained conflicting data", HFILL }},
+
+       { &hf_smb_segment_multiple_tails,
+               { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Several tails were found when defragmenting the packet", HFILL }},
+
+       { &hf_smb_segment_too_long_fragment,
+               { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Fragment contained data past end of packet", HFILL }},
+
+       { &hf_smb_segment_error,
+               { "Defragmentation error", "smb.segment.error", FT_NONE, BASE_NONE, NULL, 0x0,
+                       "Defragmentation error due to illegal fragments", HFILL }},
+
+       { &hf_smb_segment,
+               { "SMB Segment", "smb.segment", FT_NONE, BASE_NONE, NULL, 0x0,
+                       "SMB Segment", HFILL }},
+
+       { &hf_smb_segments,
+               { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
+                       "SMB Segments", HFILL }},
        };
        static gint *ett[] = {
                &ett_smb,
@@ -15826,7 +17761,7 @@ proto_register_smb(void)
                &ett_smb_ssetupandxaction,
                &ett_smb_optionsup,
                &ett_smb_time_date,
-               &ett_smb_move_flags,
+               &ett_smb_move_copy_flags,
                &ett_smb_file_attributes,
                &ett_smb_search_resume_key,
                &ett_smb_search_dir_info,
@@ -15846,6 +17781,8 @@ proto_register_smb(void)
                &ett_smb_nt_share_access,
                &ett_smb_nt_security_flags,
                &ett_smb_nt_trans_setup,
+               &ett_smb_nt_trans_data,
+               &ett_smb_nt_trans_param,
                &ett_smb_nt_notify_completion_filter,
                &ett_smb_nt_ioctl_flags,
                &ett_smb_security_information_mask,
@@ -15853,6 +17790,9 @@ proto_register_smb(void)
                &ett_smb_transaction_flags,
                &ett_smb_transaction_params,
                &ett_smb_find_first2_flags,
+#if 0
+               &ett_smb_ioflag,
+#endif
                &ett_smb_transaction_data,
                &ett_smb_stream_info,
                &ett_smb_dfs_referrals,
@@ -15863,12 +17803,16 @@ proto_register_smb(void)
                &ett_smb_device_characteristics,
                &ett_smb_fs_attributes,
                &ett_smb_segments,
+               &ett_smb_segment,
                &ett_smb_sec_desc,
                &ett_smb_sid,
                &ett_smb_acl,
                &ett_smb_ace,
                &ett_smb_ace_flags,
                &ett_smb_sec_desc_type,
+               &ett_smb_quotaflags,
+               &ett_smb_secblob,
+               &ett_smb_mac_support_flags,
        };
        module_t *smb_module;
 
@@ -15880,11 +17824,11 @@ proto_register_smb(void)
        smb_module = prefs_register_protocol(proto_smb, NULL);
        prefs_register_bool_preference(smb_module, "trans_reassembly",
                "Reassemble SMB Transaction payload",
-               "Whether the dissector should do reassembly the payload of SMB Transaction commands spanning multiple SMB PDUs",
+               "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
                &smb_trans_reassembly);
        prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
                "Reassemble DCERPC over SMB",
-               "Whether the dissector should do reassembly of DCERPC over SMB commands",
+               "Whether the dissector should reassemble DCERPC over SMB commands",
                &smb_dcerpc_reassembly);
        register_init_routine(smb_trans_reassembly_init);
        register_init_routine(smb_dcerpc_reassembly_init);
@@ -15894,4 +17838,6 @@ void
 proto_reg_handoff_smb(void)
 {
        heur_dissector_add("netbios", dissect_smb, proto_smb);
+       gssapi_handle = find_dissector("gssapi");
+       ntlmssp_handle = find_dissector("ntlmssp");
 }