- some radcom files seem to have a different magic key than the one we
[obnox/wireshark/wip.git] / packet-smb.c
index b9fc18a3768c9acda5366304610a9592c07a21be..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.257 2002/05/10 22:09:24 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"
 
@@ -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;
@@ -399,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;
@@ -442,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;
@@ -460,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;
@@ -474,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;
@@ -511,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;
@@ -523,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;
@@ -550,6 +579,13 @@ 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;
@@ -574,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;
@@ -603,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;
@@ -613,6 +653,7 @@ 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;
@@ -620,14 +661,30 @@ 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, 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.
@@ -735,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;
@@ -755,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.
@@ -775,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){
@@ -784,7 +841,7 @@ smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
                return NULL;
        }
 }
-               
+
 
 
 
@@ -964,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>
@@ -1019,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.
                         */
@@ -1090,7 +1147,7 @@ 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,
@@ -1108,7 +1165,7 @@ dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
 
        proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
        offset += 4;
+
        return offset;
 }
 
@@ -1138,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;
@@ -1152,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;
 
@@ -1175,8 +1232,8 @@ dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
        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 
+          0x40000000 00000000
+          the meaning of this one is yet unknown
        */
        if (tree) {
                filetime_low = tvb_get_letohl(tvb, offset);
@@ -1193,7 +1250,7 @@ dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
                        proto_tree_add_text(tree, tvb, offset, 8,
                            "%s: Infinity (absolute time)",
                            proto_registrar_get_name(hf_date));
-               } else {                        
+               } else {
                        if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
                                proto_tree_add_time(tree, hf_date, tvb,
                                    offset, 8, &ts);
@@ -1371,61 +1428,22 @@ dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
        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",
@@ -1487,34 +1505,55 @@ 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, 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;
 }
@@ -1544,20 +1583,6 @@ dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
         * 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,
@@ -1671,7 +1696,7 @@ dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
        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,
@@ -2034,8 +2059,9 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 }
 
 static int
-dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2205,7 +2231,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
                 * 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,
@@ -2215,8 +2241,6 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
 
        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){
@@ -2228,18 +2252,35 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
 
                        /* 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? */
@@ -2248,15 +2289,47 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
                                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;
        }
@@ -2270,13 +2343,14 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
 static int
 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 */
@@ -2285,7 +2359,7 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        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;
@@ -2307,9 +2381,9 @@ dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offse
 {
        guint8 wc;
        guint16 bc;
+
        WORD_COUNT;
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -2369,15 +2443,16 @@ dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, i
 }
 
 static int
-dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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 */
@@ -2387,7 +2462,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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,
@@ -2418,7 +2493,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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,
@@ -2437,7 +2512,7 @@ dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        guint16 bc;
 
        WORD_COUNT;
+
        /* Maximum Buffer Size */
        proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
        offset += 2;
@@ -2452,7 +2527,7 @@ dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 
        return offset;
 }
+
 
 static const true_false_string tfs_of_create = {
        "Create file if it does not exist",
@@ -2493,7 +2568,7 @@ dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 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"
@@ -2514,9 +2589,9 @@ dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int 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_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,
@@ -2529,9 +2604,57 @@ dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
        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 _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2560,7 +2683,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, in
        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;
@@ -2578,7 +2701,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, in
        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;
@@ -2596,8 +2719,76 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, in
 }
 
 static int
-dissect_move_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2606,7 +2797,7 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, i
        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;
@@ -2617,7 +2808,7 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo _U_, 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;
@@ -2631,8 +2822,9 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, i
 }
 
 static int
-dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2654,7 +2846,7 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
        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;
@@ -2695,11 +2887,11 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       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;
@@ -2736,8 +2928,9 @@ dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
 }
 
 static int
-dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2746,7 +2939,7 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* creation time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
@@ -2759,7 +2952,7 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, 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;
@@ -2800,8 +2993,9 @@ dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 }
 
 static int
-dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2820,7 +3014,7 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, 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;
@@ -2838,8 +3032,9 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 }
 
 static int
-dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2858,7 +3053,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        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;
@@ -2876,7 +3071,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, 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;
@@ -2894,8 +3089,9 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 }
 
 static int
-dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+dissect_nt_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;
@@ -2905,7 +3101,7 @@ dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 
        /* 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;
 
@@ -2920,7 +3116,7 @@ dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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;
@@ -2938,7 +3134,7 @@ dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, 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;
@@ -2957,8 +3153,9 @@ dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 
 
 static int
-dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -2974,7 +3171,7 @@ dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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;
@@ -2990,7 +3187,7 @@ dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t
 
        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_)
 {
@@ -3000,7 +3197,7 @@ dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
        WORD_COUNT;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* Last Write Time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
@@ -3021,8 +3218,9 @@ dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
 }
 
 static int
-dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -3031,7 +3229,7 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* last write time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
@@ -3048,7 +3246,7 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        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;
@@ -3069,7 +3267,8 @@ static int
 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;
 
@@ -3086,13 +3285,20 @@ dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
        }
 
        /* 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;
@@ -3273,8 +3479,8 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        offset += 4;
 
        if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s at offset %d", cnt, 
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s at offset %u", cnt,
                                (cnt == 1) ? "" : "s", ofs);
 
        /* remaining */
@@ -3309,7 +3515,7 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        return offset;
 }
+
 static int
 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -3324,8 +3530,8 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        offset += 2;
 
        if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
 
        BYTE_COUNT;
 
@@ -3363,8 +3569,9 @@ dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, in
 }
 
 static int
-dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -3387,7 +3594,7 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
        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;
@@ -3405,8 +3612,9 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
 }
 
 static int
-dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -3427,7 +3635,7 @@ dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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;
@@ -3493,7 +3701,7 @@ dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        return offset;
 }
+
 static int
 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -3561,7 +3769,7 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto
        offset += 4;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        BYTE_COUNT;
 
@@ -3595,7 +3803,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 
        /* 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);
@@ -3608,7 +3816,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        CHECK_BYTE_COUNT(1);
        proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
        COUNT_BYTES(1);
-       
+
        offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
        bc = 0; /* XXX */
 
@@ -3616,7 +3824,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 
        return offset;
 }
+
 static int
 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -3922,7 +4130,7 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
 
        return offset;
 }
+
 static int
 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -3979,7 +4187,7 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
        /* 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);
@@ -4000,7 +4208,7 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
 
        return offset;
 }
+
 static int
 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -4012,7 +4220,7 @@ dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        /* response mask */
        proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
        offset += 4;
-       
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -4041,10 +4249,12 @@ dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset,
 
 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];
@@ -4062,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 */
@@ -4072,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);
@@ -4088,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];
@@ -4103,7 +4326,8 @@ 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;
 
@@ -4127,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 */
@@ -4143,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 _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -4169,7 +4396,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        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;
@@ -4195,7 +4422,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        /* resume key */
        if(rkl){
                offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
-                   &bc, &trunc);
+                   &bc, &trunc, has_find_id);
                if (trunc)
                        goto endofcommand;
        }
@@ -4206,7 +4433,33 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 }
 
 static int
-dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -4234,7 +4487,7 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 
        while(count--){
                offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
-                   &bc, &trunc);
+                   &bc, &trunc, has_find_id);
                if (trunc)
                        goto endofcommand;
        }
@@ -4244,13 +4497,66 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        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"},
-       {0, NULL}
-};
+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 const true_false_string tfs_lock_type_large = {
+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"},
+       {0, NULL}
+};
+
+static const true_false_string tfs_lock_type_large = {
        "Large file locking format requested",
        "Large file locking format not requested"
 };
@@ -4367,7 +4673,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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);
@@ -4392,7 +4698,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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);
@@ -4428,7 +4734,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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);
@@ -4453,7 +4759,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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);
@@ -4486,7 +4792,7 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
        }
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4523,7 +4829,7 @@ dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4630,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;
 
@@ -4663,11 +4970,11 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset = dissect_search_attributes(tvb, tree, offset);
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
 
        /* creation time */
        offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
-       
+
        /* open function */
        offset = dissect_open_function(tvb, tree, offset);
 
@@ -4682,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;
@@ -4697,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4791,11 +5098,11 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, tree, offset);
+       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;
@@ -4826,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4881,8 +5188,8 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 2;
 
        if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s at offset %d", maxcnt, 
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s at offset %u", maxcnt,
                                (maxcnt == 1) ? "" : "s", ofs);
 
        /* min count */
@@ -4908,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4931,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;
@@ -4966,8 +5273,8 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        if (check_col(pinfo->cinfo, COL_INFO))
-               col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s", datalen, 
+               col_append_fstr(pinfo->cinfo, COL_INFO,
+                               ", %u byte%s", datalen,
                                (datalen == 1) ? "" : "s");
 
        /* data offset */
@@ -5010,13 +5317,13 @@ 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);
                                }
                        }
                }
@@ -5041,7 +5348,7 @@ dissect_read_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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5114,7 +5421,11 @@ 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: add byte/offset to COL_INFO */
+       /* 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 */
@@ -5151,13 +5462,13 @@ 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);
                                }
                        }
                }
@@ -5180,7 +5491,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5189,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;
@@ -5202,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;
@@ -5220,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;
@@ -5236,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5268,7 +5585,7 @@ dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 
        return offset;
 }
+
 
 static int
 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
@@ -5276,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;
@@ -5377,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,
@@ -5405,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,
@@ -5418,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,
@@ -5431,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);
                        }
@@ -5442,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);
                        }
@@ -5450,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);
                        }
@@ -5460,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,
@@ -5473,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,
@@ -5484,16 +5832,16 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
 
                        if (!dn[0] && !an[0])
-                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               col_append_fstr(pinfo->cinfo, COL_INFO,
                                                "anonymous");
                        else
-                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               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,
@@ -5508,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,
@@ -5519,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5530,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;
 
@@ -5566,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;
+
+                       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,
@@ -5589,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,
@@ -5599,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,
@@ -5610,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, 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)
 {
@@ -5648,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, 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"
@@ -5722,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;
 
@@ -5757,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,
@@ -5792,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5806,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;
 
@@ -5886,7 +6260,6 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        /* 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){
-               smb_info_t *si = (smb_info_t *)pinfo->private_data;
                /* 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);
@@ -5907,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,
@@ -5919,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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -6178,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[] = {
@@ -6320,7 +6694,7 @@ dissect_nt_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
        }
 
        /*
-        * Some of these bits come from 
+        * Some of these bits come from
         *
         *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
         *
@@ -6509,7 +6883,7 @@ dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 
        return offset;
 }
+
 static int
 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
@@ -6524,7 +6898,7 @@ dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int
                        "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,
@@ -6553,7 +6927,7 @@ dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int
        offset += 4;
        return offset;
 }
+
 static int
 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
@@ -6665,7 +7039,7 @@ dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
        offset += 1;
 
        switch(revision){
-       case 1:  
+       case 1:
        case 2:  /* Not sure what the different revision numbers mean */
          /* number of authorities*/
          num_auth = tvb_get_guint8(tvb, offset);
@@ -6687,7 +7061,7 @@ dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
           sa_offset = offset;
 
           gstr = g_string_new("");
-          
+
          CLEANUP_PUSH(free_g_string, gstr);
 
          /* sub authorities, leave RID to last */
@@ -6715,7 +7089,7 @@ dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
            offset+=4;
          }
          else {
-           proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
+           proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);
          }
 
          CLEANUP_CALL_AND_POP;
@@ -6825,7 +7199,7 @@ dissect_nt_v2_ace(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
        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: ");
@@ -7242,11 +7616,11 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                /* nt access mask */
                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, tree, offset);
                bc -= 4;
@@ -7254,7 +7628,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                /* share access */
                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);
@@ -7281,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, 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);
@@ -7361,7 +7735,7 @@ 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;
@@ -7421,7 +7795,7 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                /* not decoded yet */
                break;
        }
+
        return old_offset+len;
 }
 
@@ -7464,7 +7838,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        /* 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;
@@ -7484,7 +7858,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        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);
@@ -7545,7 +7919,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
                ntd.subcmd = subcmd;
                if (!si->unidir) {
                        if(!pinfo->fd->flags.visited){
-                               /* 
+                               /*
                                 * Allocate a new smb_nt_transact_info_t
                                 * structure.
                                 */
@@ -7576,7 +7950,7 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
        }
 
        BYTE_COUNT;
-       
+
        /* parameters */
        if(po>(guint32)offset){
                /* We have some initial padding bytes.
@@ -7617,7 +7991,9 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 
 
 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;
@@ -7686,9 +8062,11 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 
        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;
@@ -7736,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);
@@ -7753,19 +8131,19 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                /* create time */
                offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_create_time);
-       
+
                /* access time */
                offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_access_time);
-       
+
                /* last write time */
                offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_last_write_time);
-       
+
                /* last change time */
                offset = dissect_smb_64bit_time(tvb, tree, offset,
                        hf_smb_change_time);
-       
+
                /* Extended File Attributes */
                offset = dissect_file_ext_attr(tvb, tree, offset);
 
@@ -7803,7 +8181,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                        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);
@@ -7820,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,
@@ -7877,9 +8255,11 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
 
        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;
@@ -7983,7 +8363,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        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);
@@ -7993,7 +8373,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        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);
@@ -8024,7 +8404,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        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;
@@ -8039,46 +8419,34 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        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;
-               
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
                                             r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
-               pinfo->fragmented = FALSE;
-
-               it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
-               tr = proto_item_add_subtree(it, ett_smb_segments);
-               for(fd=r_fd->next;fd;fd=fd->next){
-                       proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
-                                           "Frame:%u Data:%u-%u",
-                                           fd->frame, fd->offset,
-                                           fd->offset+fd->len-1);
-               }
+               add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+
+               show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
        }
 
 
@@ -8088,7 +8456,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
                                          &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){
@@ -8105,7 +8473,7 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
            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.
@@ -8138,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 _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+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;
@@ -8165,7 +8534,7 @@ dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
        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,
@@ -8223,7 +8592,7 @@ 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 _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
@@ -8253,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;
 
@@ -8291,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);
@@ -8347,12 +8717,228 @@ dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 
+static int
+dissect_send_single_block_message_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;
+       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);
+
+       /* 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);
+
+       /* 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_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;
+
+       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);
+
+       /* 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;
 
@@ -8422,7 +9008,7 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        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,
@@ -8436,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, 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)
@@ -8486,17 +9072,17 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
        /* create time */
        offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
-       
+
        /* access time */
        offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
-       
+
        /* last write time */
        offset = dissect_smb_64bit_time(tvb, tree, offset,
                hf_smb_last_write_time);
 
        /* last change time */
        offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
-       
+
        /* Extended File Attributes */
        offset = dissect_file_ext_attr(tvb, tree, offset);
 
@@ -8524,7 +9110,7 @@ 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, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -8537,7 +9123,7 @@ dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
        guint16 bc;
 
        WORD_COUNT;
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -8631,23 +9217,64 @@ 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}
 };
 
@@ -8804,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)
@@ -8825,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);
        }
@@ -8842,14 +9496,14 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                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, tree, offset);
+               offset = dissect_file_attributes(tvb, tree, offset, 2);
                bc -= 2;
 
                /* create time */
@@ -8876,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);
@@ -8886,8 +9540,6 @@ 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 */
@@ -8919,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);
@@ -8930,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 */
@@ -8963,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);
@@ -8993,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);
@@ -9020,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);
@@ -9055,7 +9705,7 @@ 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*/
@@ -9074,22 +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);
@@ -9097,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,
@@ -9108,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*/
@@ -9119,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);
@@ -9135,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);
@@ -9184,7 +9918,7 @@ dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 
        return mask;
 }
+
 
 static int
 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
@@ -9240,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;
 
@@ -9265,7 +10000,7 @@ dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
        *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);
@@ -9280,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;
@@ -9343,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);
@@ -9371,7 +10107,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
 
                        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);
@@ -9418,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);
@@ -9428,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;
@@ -9437,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);
@@ -9447,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;
@@ -9456,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);
@@ -9549,7 +10285,7 @@ dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
        *bcp -= 2;
 
        /* ea size */
@@ -9584,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);
@@ -9609,27 +10346,27 @@ dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        CHECK_BYTE_COUNT_SUBR(8);
        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, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        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, tree, offset, hf_smb_change_time);
        *bcp -= 8;
-       
+
        /* File Attributes */
-       CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, tree, offset);
-       *bcp -= 2;
+       CHECK_BYTE_COUNT_SUBR(4);
+       offset = dissect_file_attributes(tvb, tree, offset, 4);
+       *bcp -= 4;
 
        *trunc = FALSE;
        return offset;
@@ -9696,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;
 
@@ -9705,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);
@@ -9724,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);
@@ -9736,7 +10476,7 @@ 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 */
@@ -9763,7 +10503,7 @@ dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        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;
@@ -9780,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;
@@ -9800,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);
@@ -9818,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);
 
@@ -9864,22 +10605,22 @@ dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, 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);
@@ -9902,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*/
@@ -9920,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;
@@ -9961,7 +10711,7 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                /* XXX add this from the SNIA doc */
                break;
        }
-       
+
        return offset;
 }
 
@@ -10061,20 +10811,20 @@ 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 */
@@ -10084,30 +10834,80 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
                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 */
@@ -10214,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;
@@ -10233,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);
@@ -10243,7 +11043,7 @@ 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);
@@ -10312,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);
@@ -10342,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;
 
@@ -10353,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.
@@ -10375,7 +11178,12 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                                t2i->resume_keys = FALSE;
                                                si->sip->extra_info = t2i;
                                        }
-                               }     
+                               }
+
+                               /*
+                                * XXX - process TRANS2_FSCTL and
+                                * TRANS2_IOCTL setup words here.
+                                */
                                break;
 
                        case SMB_COM_TRANSACTION:
@@ -10388,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,
@@ -10471,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;
@@ -10507,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.
                                         */
@@ -10558,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;
@@ -10585,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,
@@ -10653,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, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
        *bcp -= 2;
 
        /* file name len */
@@ -10667,7 +11485,7 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                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);
@@ -10677,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);
 
@@ -10717,7 +11535,7 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                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, tree, offset,
@@ -10751,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, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset, 2);
        *bcp -= 2;
 
        /* ea size */
@@ -10766,7 +11584,7 @@ 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);
@@ -10819,7 +11637,7 @@ dissect_4_3_4_4(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);
-       
+
        /* file index */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
@@ -10829,23 +11647,23 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        CHECK_BYTE_COUNT_SUBR(8);
        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, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        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, 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);
@@ -10868,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);
@@ -10932,7 +11750,7 @@ dissect_4_3_4_5(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);
-       
+
        /* file index */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
@@ -10942,23 +11760,23 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        CHECK_BYTE_COUNT_SUBR(8);
        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, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        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, 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);
@@ -10986,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);
@@ -11051,7 +11869,7 @@ dissect_4_3_4_6(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);
-       
+
        /* file index */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
@@ -11061,23 +11879,23 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        CHECK_BYTE_COUNT_SUBR(8);
        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, tree, offset, hf_smb_access_time);
        *bcp -= 8;
-       
+
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        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, 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);
@@ -11114,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);
@@ -11187,7 +12005,7 @@ dissect_4_3_4_7(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);
-       
+
        /* file index */
        CHECK_BYTE_COUNT_SUBR(4);
        proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
@@ -11200,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);
@@ -11232,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;
@@ -11254,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*/
@@ -11265,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);
@@ -11331,7 +12150,7 @@ dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
        offset += 4;
        return offset;
 }
+
 
 static int
 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
@@ -11368,6 +12187,32 @@ dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offse
 }
 
 /*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)
@@ -11375,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 */
@@ -11421,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);
@@ -11429,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, 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);
@@ -11453,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);
@@ -11461,6 +12327,7 @@ 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);
@@ -11483,23 +12350,25 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                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);
@@ -11513,20 +12382,122 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                /* label */
                fn_len = fnl;
-               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_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);
+
+               /* 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_actual_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;
        }
+
        return offset;
 }
+
 static int
 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *parent_tree)
@@ -11552,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 {
@@ -11619,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 */
@@ -11685,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 {
@@ -11705,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, tree, offset);
+               offset = dissect_file_attributes(tvb, tree, offset, 2);
 
                /* create time */
                offset = dissect_smb_datetime(tvb, tree, offset,
-                       hf_smb_create_time, 
+                       hf_smb_create_time,
                        hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
 
                /* data size */
@@ -11730,8 +12749,8 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                /* open_action */
                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 */
@@ -11780,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;
 
@@ -11794,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 */
@@ -11902,7 +12977,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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)>"));
                                }
                        }
@@ -11991,46 +13066,33 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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;
-
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
                                             r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
-               pinfo->fragmented = FALSE;
-
-               it = proto_tree_add_text(tree, pd_tvb, 0, -1, "Fragments");
-               tr = proto_item_add_subtree(it, ett_smb_segments);
-               for(fd=r_fd->next;fd;fd=fd->next){
-                       proto_tree_add_text(tr, pd_tvb, fd->offset, fd->len,
-                                           "Frame:%u Data:%u-%u",
-                                           fd->frame, fd->offset,
-                                           fd->offset+fd->len-1);
-               }
+               add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+               show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
        }
 
 
@@ -12044,7 +13106,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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.
                 */
@@ -12136,7 +13198,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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"
@@ -12148,7 +13210,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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
@@ -12182,6 +13244,25 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_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 */
@@ -12194,14 +13275,19 @@ dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int off
        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
 
@@ -12243,10 +13329,10 @@ static 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},
@@ -12254,11 +13340,11 @@ static 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},
@@ -12266,11 +13352,11 @@ static 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},
@@ -12352,9 +13438,9 @@ static 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},
@@ -12383,12 +13469,13 @@ static 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_nt_rename_file_request, dissect_empty},
+  /* 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},
@@ -12416,6 +13503,7 @@ static 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},
@@ -12433,17 +13521,17 @@ static 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},
@@ -12486,11 +13574,11 @@ static smb_function smb_dissector[256] = {
 };
 
 static int
-dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, 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;
@@ -12498,14 +13586,22 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *s
                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);
 
@@ -12522,7 +13618,7 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *s
 
 
 /* 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
@@ -12561,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" },
@@ -12579,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" },
@@ -12662,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" },
@@ -12738,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" },
@@ -12793,7 +13889,7 @@ static char *decode_smb_name(unsigned char cmd)
 {
   return(smb_cmd_vals[cmd].strptr);
 }
+
 
 
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -12876,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;
-  unsigned 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"},
@@ -13052,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"},
@@ -13087,6 +14030,7 @@ const value_string DOS_errors[] = {
   {SMBE_invalidformsize, "Invalid form size"},
   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
   {SMBE_invalidowner, "Invalid owner"},
+  {SMBE_nomoreitems, "No more items"},
   {0, NULL}
   };
 
@@ -13137,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}
 };
@@ -13426,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" },
@@ -14233,7 +15178,7 @@ dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 }
 
 
+
 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"
@@ -14325,11 +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;
+       guint32 nt_status = 0;
+       guint8 errclass = 0;
+       guint16 errcode = 0;
        guint32 pid_mid;
        conversation_t *conversation;
+       nstime_t ns;
 
        top_tree=parent_tree;
 
@@ -14343,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");
        }
@@ -14371,11 +15317,11 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        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);
@@ -14384,30 +15330,30 @@ 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_hash_unmatched,
                        smb_saved_info_equal_unmatched);
                conversation_add_proto_data(conversation, proto_smb, si.ct);
        }
@@ -14418,7 +15364,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
            &&  (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 */
@@ -14437,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.
@@ -14446,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
@@ -14486,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;
                        }
@@ -14514,8 +15460,8 @@ 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){
@@ -14533,15 +15479,15 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                else if(si.cmd==SMB_COM_NT_CANCEL){
                                        cmd_match=TRUE;
                                }
-                               else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
+                               else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY)
                                     && (sip->cmd==SMB_COM_TRANSACTION)){
                                        cmd_match=TRUE;
                                }
-                               else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
+                               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) 
+                               else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)
                                     && (sip->cmd==SMB_COM_NT_TRANSACT)){
                                        cmd_match=TRUE;
                                }
@@ -14552,7 +15498,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                           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 
+                                          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
@@ -14566,22 +15512,18 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                } 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;
@@ -14594,6 +15536,8 @@ 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) {
@@ -14602,6 +15546,10 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                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
@@ -14633,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);
+                       }
                }
        }
 
@@ -14730,7 +15687,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        offset += 2;
 
        pinfo->private_data = &si;
-        dissect_smb_command(tvb, pinfo, 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)) {
@@ -14739,7 +15696,7 @@ 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.
                                 */
@@ -14787,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 }},
@@ -14935,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 }},
@@ -15131,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 }},
@@ -15157,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,
@@ -15245,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,
@@ -15291,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 }},
@@ -15331,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 }},
@@ -15439,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 }},
@@ -15952,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,
@@ -16070,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 }},
@@ -16096,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,
@@ -16142,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 }},
@@ -16198,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 }},
@@ -16211,7 +17286,7 @@ 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,
@@ -16354,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 }},
@@ -16402,6 +17489,14 @@ 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 }},
@@ -16614,6 +17709,33 @@ proto_register_smb(void)
                { "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,
@@ -16639,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,
@@ -16668,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,
@@ -16678,6 +17803,7 @@ 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,
@@ -16685,6 +17811,8 @@ proto_register_smb(void)
                &ett_smb_ace_flags,
                &ett_smb_sec_desc_type,
                &ett_smb_quotaflags,
+               &ett_smb_secblob,
+               &ett_smb_mac_support_flags,
        };
        module_t *smb_module;
 
@@ -16710,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");
 }