Removed trailing whitespaces from .h and .c files using the
[obnox/wireshark/wip.git] / packet-smb.c
index 6138c60d17a5ab7ccaf5a3b29bd9a16c28b96462..e4efc4e4749b0fe49e9e94d933409425e1949fa5 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
  *
- * $Id: packet-smb.c,v 1.261 2002/05/25 12:33:59 guy Exp $
+ * $Id: packet-smb.c,v 1.283 2002/08/25 22:57:26 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 
 #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;
@@ -442,6 +461,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;
@@ -481,6 +501,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;
@@ -518,6 +542,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;
@@ -559,6 +586,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;
@@ -583,7 +617,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;
@@ -612,6 +646,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;
@@ -622,6 +660,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;
@@ -629,14 +668,29 @@ 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_gssapi = -1;
+
+static dissector_handle_t gssapi_handle = NULL;
+
+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.
@@ -744,7 +798,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;
@@ -2043,8 +2097,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;
@@ -2214,7 +2269,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,
@@ -2224,8 +2279,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){
@@ -2237,18 +2290,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? */
@@ -2257,13 +2327,25 @@ 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(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_gssapi);
+
+                               gssapi_tvb = tvb_new_subset(
+                                       tvb, offset, bc, bc);
+
+                               call_dissector(
+                                       gssapi_handle, gssapi_tvb, pinfo, 
+                                       gssapi_tree);
+
                                COUNT_BYTES(bc);
                        }
                }
@@ -2279,6 +2361,7 @@ 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;
@@ -2294,7 +2377,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;
@@ -2378,8 +2461,9 @@ 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;
@@ -2396,7 +2480,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,
@@ -2427,7 +2511,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,
@@ -2502,7 +2586,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"
@@ -2523,7 +2607,7 @@ 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,
@@ -2538,9 +2622,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;
@@ -2569,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;
@@ -2587,7 +2719,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;
@@ -2605,8 +2737,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;
@@ -2615,7 +2815,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;
@@ -2626,7 +2826,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;
@@ -2640,8 +2840,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;
@@ -2663,7 +2864,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;
@@ -2745,8 +2946,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;
@@ -2768,7 +2970,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;
@@ -2809,8 +3011,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;
@@ -2829,7 +3032,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;
@@ -2847,8 +3050,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;
@@ -2867,7 +3071,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;
@@ -2885,7 +3089,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;
@@ -2903,8 +3107,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;
@@ -2929,7 +3134,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;
@@ -2947,7 +3152,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;
@@ -2966,8 +3171,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;
@@ -2983,7 +3189,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;
@@ -3030,8 +3236,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;
@@ -3057,7 +3264,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;
@@ -3283,7 +3490,7 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        if (check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s at offset %d", cnt, 
+                               ", %u byte%s at offset %u", cnt, 
                                (cnt == 1) ? "" : "s", ofs);
 
        /* remaining */
@@ -3334,7 +3541,7 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 
        if (check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
+                               ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
 
        BYTE_COUNT;
 
@@ -3372,8 +3579,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;
@@ -3396,7 +3604,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;
@@ -3414,8 +3622,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;
@@ -3436,7 +3645,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;
@@ -4050,10 +4259,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];
@@ -4071,7 +4282,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 */
@@ -4081,10 +4292,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);
@@ -4097,10 +4319,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];
@@ -4112,7 +4336,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;
 
@@ -4136,7 +4361,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 */
@@ -4152,8 +4377,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;
@@ -4178,7 +4406,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;
@@ -4204,7 +4432,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;
        }
@@ -4215,7 +4443,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;
@@ -4243,7 +4497,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;
        }
@@ -4253,6 +4507,59 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        return offset;
 }
 
+static int
+dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
+           FALSE);
+}
+
+static int
+dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
+           TRUE);
+}
+
+static int
+dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint8 wc;
+       guint16 bc;
+       guint16 data_len;
+
+       WORD_COUNT;
+
+       /* reserved */
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* data len */
+       CHECK_BYTE_COUNT(2);
+       data_len = tvb_get_ntohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
+       COUNT_BYTES(2);
+
+       if (data_len != 0) {
+               CHECK_BYTE_COUNT(data_len);
+               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
+                   data_len, TRUE);
+               COUNT_BYTES(data_len);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
 static const value_string locking_ol_vals[] = {
        {0,     "Client is not holding oplock on this file"},
        {1,     "Level 2 oplock currently held by client"},
@@ -4495,7 +4802,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;
 }
@@ -4532,7 +4839,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;
 }
@@ -4639,6 +4946,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;
 
@@ -4691,7 +4999,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;
@@ -4706,7 +5014,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;
 }
@@ -4835,7 +5143,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;
 }
@@ -4891,7 +5199,7 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 
        if (check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s at offset %d", maxcnt, 
+                               ", %u byte%s at offset %u", maxcnt, 
                                (maxcnt == 1) ? "" : "s", ofs);
 
        /* min count */
@@ -4917,7 +5225,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;
 }
@@ -4976,7 +5284,7 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        if (check_col(pinfo->cinfo, COL_INFO))
                col_append_fstr(pinfo->cinfo, COL_INFO, 
-                               ", %d byte%s", datalen, 
+                               ", %u byte%s", datalen, 
                                (datalen == 1) ? "" : "s");
 
        /* data offset */
@@ -5050,7 +5358,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;
 }
@@ -5189,7 +5497,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;
 }
@@ -5245,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;
 }
@@ -5285,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;
@@ -5386,20 +5695,34 @@ 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);
+
                if(sbloblen){
-                       CHECK_BYTE_COUNT(sbloblen);
-                       proto_tree_add_item(tree, hf_smb_security_blob,
-                               tvb, offset, sbloblen, TRUE);
+                       tvbuff_t *gssapi_tvb;
+                       proto_tree *gssapi_tree;
+                       
+                        CHECK_BYTE_COUNT(sbloblen);
+                       
+                       gssapi_tree = proto_item_add_subtree(
+                               blob_item, ett_smb_gssapi);
+
+                       gssapi_tvb = tvb_new_subset(
+                               tvb, offset, sbloblen, sbloblen);
+
+                       call_dissector(
+                               gssapi_handle, gssapi_tvb, pinfo, gssapi_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,
@@ -5414,7 +5737,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,
@@ -5427,7 +5750,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,
@@ -5469,7 +5792,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,
@@ -5482,7 +5805,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,
@@ -5502,7 +5825,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 
                /* 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,
@@ -5517,7 +5840,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,
@@ -5528,7 +5851,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;
 }
@@ -5539,6 +5862,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;
 
@@ -5575,21 +5899,35 @@ 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 *gssapi_tvb;
+                       proto_tree *gssapi_tree;
+
+                        CHECK_BYTE_COUNT(sbloblen);
+                       
+                       gssapi_tree = proto_item_add_subtree(
+                               blob_item, ett_smb_gssapi);
+
+                       gssapi_tvb = tvb_new_subset(
+                               tvb, offset, sbloblen, sbloblen);
+                       
+                       call_dissector(
+                               gssapi_handle, gssapi_tvb, pinfo, gssapi_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,
@@ -5598,7 +5936,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,
@@ -5608,7 +5946,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,
@@ -5619,7 +5957,7 @@ 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;
 }
@@ -5657,7 +5995,7 @@ 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;
 }
@@ -5731,6 +6069,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;
 
@@ -5772,7 +6111,7 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, 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,
@@ -5801,7 +6140,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;
 }
@@ -5815,6 +6154,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;
 
@@ -5895,7 +6235,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);
@@ -5916,7 +6255,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,
@@ -5928,7 +6268,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;
 }
@@ -6187,7 +6527,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[] = {
@@ -7296,7 +7636,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                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);
@@ -7626,7 +7966,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;
@@ -7697,7 +8039,9 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 }
  
 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;
@@ -7829,7 +8173,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,
@@ -7888,7 +8232,9 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
 }
  
 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;
@@ -8070,24 +8416,12 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
           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);
        }
 
 
@@ -8149,8 +8483,9 @@ static const value_string print_mode_vals[] = {
 };
  
 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;
@@ -8174,7 +8509,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,
@@ -8262,6 +8597,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;
 
@@ -8300,7 +8636,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);
@@ -8577,6 +8913,7 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0;
        guint16 bc;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
@@ -8646,7 +8983,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,
@@ -8660,7 +8997,7 @@ 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;
 }
@@ -8748,7 +9085,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;
 }
@@ -8905,6 +9242,7 @@ static const value_string qfsi_vals[] = {
        { 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"},
@@ -9068,6 +9406,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)
@@ -9106,10 +9471,10 @@ 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);
@@ -9140,7 +9505,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);
@@ -9150,8 +9515,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 */
@@ -9183,7 +9546,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);
@@ -9194,8 +9557,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 */
@@ -9227,7 +9588,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);
@@ -9264,7 +9625,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                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);
@@ -9291,7 +9652,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                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);
@@ -9339,41 +9700,125 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                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*/
-       case 0x0a:      /*TRANS2_IOCTL2*/
-               /* these calls have no parameter block in the request */
-               break;
-       case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
-       case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
-               /* XXX unknown structure*/
+               /* 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 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
-               /* 4 reserved bytes */
-               CHECK_BYTE_COUNT_TRANS(4);
-               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
-               COUNT_BYTES_TRANS(4);
+       case 0x0a:      /*TRANS2_IOCTL2*/
+               /* this call has no parameter block in the request */
 
-               /* dir name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
-                       FALSE, FALSE, &bc);
-               CHECK_STRING_TRANS(fn);
-               proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
+               /*
+                * 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*/
+               /* 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, ", Dir: %s",
+                       col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
                        fn);
                }
 
-               /* XXX optional FEAList, unknown what FEAList looks like*/
+               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);
+               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS(4);
+
+               /* dir 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_dir_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, ", Dir: %s",
+                       fn);
+               }
                break;
        case 0x0e:      /*TRANS2_SESSION_SETUP*/
                /* XXX unknown structure*/
@@ -9385,7 +9830,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                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);
@@ -9399,7 +9844,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);
@@ -9504,6 +9949,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;
 
@@ -9529,7 +9975,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);
@@ -9544,6 +9990,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;
@@ -9635,7 +10082,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);
@@ -9682,7 +10129,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);
@@ -9701,7 +10148,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);
@@ -9720,7 +10167,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);
@@ -9848,11 +10295,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);
@@ -9960,6 +10408,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;
 
@@ -9969,7 +10418,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);
@@ -9986,13 +10435,15 @@ static int
 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
-
+       
        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);
@@ -10000,7 +10451,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 */
@@ -10044,6 +10495,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;
@@ -10082,7 +10534,7 @@ 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);
@@ -10341,13 +10793,13 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
 
        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 */
@@ -10357,30 +10809,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 */
@@ -10626,7 +11128,10 @@ 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);
@@ -10648,7 +11153,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:
@@ -10668,7 +11178,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                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,
@@ -10940,7 +11450,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);
@@ -11039,7 +11549,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);
@@ -11141,7 +11651,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);
@@ -11259,7 +11769,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);
@@ -11389,14 +11899,14 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        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);
@@ -11473,7 +11983,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);
@@ -11507,8 +12017,9 @@ dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 }
  
 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;
@@ -11641,6 +12152,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)
@@ -11648,6 +12185,9 @@ 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;
@@ -11694,7 +12234,7 @@ 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);
@@ -11711,7 +12251,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);
@@ -11744,7 +12284,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);
@@ -11807,13 +12347,88 @@ 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;
@@ -11940,15 +12555,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 */
@@ -12026,6 +12675,20 @@ 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);
 
@@ -12051,8 +12714,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 */
@@ -12101,7 +12764,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;
 
@@ -12115,28 +12778,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 */
@@ -12334,24 +13053,11 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *
           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);
        }
 
 
@@ -12503,6 +13209,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 */
@@ -12516,13 +13241,18 @@ dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int off
 
        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
 
@@ -12564,10 +13294,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},
@@ -12575,11 +13305,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},
@@ -12587,11 +13317,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},
@@ -12673,9 +13403,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},
@@ -12704,12 +13434,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},
@@ -12737,6 +13468,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},
@@ -12754,17 +13486,17 @@ static smb_function smb_dissector[256] = {
   /* 0xce */  {dissect_unknown, dissect_unknown},
   /* 0xcf */  {dissect_unknown, dissect_unknown},
 
-  /* 0xd0 */  {dissect_send_single_block_message_request, dissect_empty},
-  /* 0xd1 */  {dissect_send_single_block_message_request, dissect_empty},
-  /* 0xd2 */  {dissect_forwarded_name, dissect_empty},
-  /* 0xd3 */  {dissect_forwarded_name, dissect_empty},
-  /* 0xd4 */  {dissect_empty, dissect_get_machine_name_response},
-  /* 0xd5 */  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
-  /* 0xd6 */  {dissect_message_group_id, dissect_empty},
-  /* 0xd7 */  {dissect_send_multi_block_message_text_request, dissect_empty},
-  /* 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},
@@ -12807,7 +13539,7 @@ 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;
@@ -12819,9 +13551,17 @@ 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,
@@ -12882,7 +13622,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" },
@@ -12900,7 +13640,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" },
@@ -12983,7 +13723,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" },
@@ -13061,7 +13801,7 @@ static const value_string smb_cmd_vals[] = {
   { 0xCF, "unknown-0xCF" },
   { 0xD0, "Send Single Block Message" },
   { 0xD1, "Send Broadcast Message" },
-  { 0xD2, "Forward User name" },
+  { 0xD2, "Forward User Name" },
   { 0xD3, "Cancel Forward" },
   { 0xD4, "Get Machine Name" },
   { 0xD5, "Send Start of Multi-block Message" },
@@ -13197,157 +13937,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 {
-    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"},
@@ -13406,6 +13995,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}
   };
 
@@ -13456,18 +14046,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}
 };
@@ -14645,11 +15235,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;
 
@@ -14708,15 +15299,15 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
           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)
-               */
+       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, 
@@ -14892,10 +15483,6 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                                /* 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);
@@ -14914,6 +15501,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) {
@@ -14922,6 +15511,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
@@ -14953,8 +15546,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);
+                       }
                }
        }
 
@@ -15050,7 +15652,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)) {
@@ -15107,6 +15709,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 }},
@@ -15255,6 +15861,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 }},
@@ -15451,10 +16061,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 }},
@@ -15611,6 +16249,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 }},
@@ -15651,6 +16349,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 }},
@@ -15759,6 +16461,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 }},
@@ -16390,6 +17096,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 }},
@@ -16546,6 +17256,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 }},
@@ -16559,7 +17279,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,
@@ -16702,6 +17422,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 }},
@@ -16970,6 +17702,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,
@@ -16995,7 +17754,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,
@@ -17024,6 +17783,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,
@@ -17034,6 +17796,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,
@@ -17041,6 +17804,8 @@ proto_register_smb(void)
                &ett_smb_ace_flags,
                &ett_smb_sec_desc_type,
                &ett_smb_quotaflags,
+               &ett_smb_gssapi,
+               &ett_smb_mac_support_flags,
        };
        module_t *smb_module;
 
@@ -17066,4 +17831,5 @@ void
 proto_reg_handoff_smb(void)
 {
        heur_dissector_add("netbios", dissect_smb, proto_smb);
+       gssapi_handle = find_dissector("gssapi");
 }