Removed trailing whitespaces from .h and .c files using the
[obnox/wireshark/wip.git] / packet-smb.c
index 563cdb3625c66b8ff8f46c54a6fd41eb43c02b85..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.196 2002/01/20 22:12:28 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>
 #include <ctype.h>
-#include "packet.h"
-#include "conversation.h"
+#include <epan/packet.h>
+#include <epan/conversation.h>
 #include "smb.h"
 #include "alignment.h"
-#include "strutil.h"
+#include <epan/strutil.h>
 #include "prefs.h"
 #include "reassemble.h"
 
+#include "packet-smb-common.h"
 #include "packet-smb-mailslot.h"
 #include "packet-smb-pipe.h"
 
  *
  *     ftp://ftp.microsoft.com/developr/drg/CIFS/
  *
- * and a CIFS draft from the Storage Networking Industry Association
+ * and a CIFS specification from the Storage Networking Industry Association
  * can be found on a link from the page at
  *
- *     http://www.snia.org/English/Work_Groups/NAS/CIFS/WG_CIFS_Docs.html
+ *     http://www.snia.org/English/Collaterals/Work_Group_Docs/NAS/CIFS/CIFS_Technical_Reference.pdf
  *
  * (it supercedes the document at
  *
@@ -100,6 +93,7 @@ static int hf_smb_tid = -1;
 static int hf_smb_uid = -1;
 static int hf_smb_mid = -1;
 static int hf_smb_response_to = -1;
+static int hf_smb_time = -1;
 static int hf_smb_response_in = -1;
 static int hf_smb_continuation_to = -1;
 static int hf_smb_nt_status = -1;
@@ -135,6 +129,7 @@ static int hf_smb_server_timezone = -1;
 static int hf_smb_encryption_key_length = -1;
 static int hf_smb_encryption_key = -1;
 static int hf_smb_primary_domain = -1;
+static int hf_smb_server = -1;
 static int hf_smb_max_raw_buf_size = -1;
 static int hf_smb_server_guid = -1;
 static int hf_smb_security_blob_len = -1;
@@ -187,7 +182,14 @@ static int hf_smb_service = -1;
 static int hf_smb_move_flags_file = -1;
 static int hf_smb_move_flags_dir = -1;
 static int hf_smb_move_flags_verify = -1;
-static int hf_smb_move_files_moved = -1;
+static int hf_smb_files_moved = -1;
+static int hf_smb_copy_flags_file = -1;
+static int hf_smb_copy_flags_dir = -1;
+static int hf_smb_copy_flags_dest_mode = -1;
+static int hf_smb_copy_flags_source_mode = -1;
+static int hf_smb_copy_flags_verify = -1;
+static int hf_smb_copy_flags_tree_copy = -1;
+static int hf_smb_copy_flags_ea_action = -1;
 static int hf_smb_count = -1;
 static int hf_smb_file_name = -1;
 static int hf_smb_open_function_open = -1;
@@ -227,6 +229,22 @@ static int hf_smb_access_locality = -1;
 static int hf_smb_access_caching = -1;
 static int hf_smb_access_writetru = -1;
 static int hf_smb_create_time = -1;
+static int hf_smb_modify_time = -1;
+static int hf_smb_backup_time = -1;
+static int hf_smb_mac_alloc_block_count = -1;
+static int hf_smb_mac_alloc_block_size = -1;
+static int hf_smb_mac_free_block_count = -1;
+static int hf_smb_mac_fndrinfo = -1;
+static int hf_smb_mac_root_file_count = -1;
+static int hf_smb_mac_root_dir_count = -1;
+static int hf_smb_mac_file_count = -1;
+static int hf_smb_mac_dir_count = -1;
+static int hf_smb_mac_support_flags = -1;
+static int hf_smb_mac_sup_access_ctrl = -1;
+static int hf_smb_mac_sup_getset_comments = -1;
+static int hf_smb_mac_sup_desktopdb_calls = -1;
+static int hf_smb_mac_sup_unique_ids = -1;
+static int hf_smb_mac_sup_streams = -1;
 static int hf_smb_create_dos_date = -1;
 static int hf_smb_create_dos_time = -1;
 static int hf_smb_last_write_time = -1;
@@ -265,6 +283,7 @@ static int hf_smb_write_mode_raw = -1;
 static int hf_smb_write_mode_message_start = -1;
 static int hf_smb_write_mode_connectionless = -1;
 static int hf_smb_resume_key_len = -1;
+static int hf_smb_resume_find_id = -1;
 static int hf_smb_resume_server_cookie = -1;
 static int hf_smb_resume_client_cookie = -1;
 static int hf_smb_andxoffset = -1;
@@ -323,7 +342,9 @@ static int hf_smb_nt_ioctl_function_code = -1;
 static int hf_smb_nt_ioctl_isfsctl = -1;
 static int hf_smb_nt_ioctl_flags_root_handle = -1;
 static int hf_smb_nt_ioctl_data = -1;
+#ifdef SMB_UNUSED_HANDLES
 static int hf_smb_nt_security_information = -1;
+#endif
 static int hf_smb_nt_notify_action = -1;
 static int hf_smb_nt_notify_watch_tree = -1;
 static int hf_smb_nt_notify_stream_write = -1;
@@ -440,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;
@@ -458,6 +480,13 @@ static int hf_smb_print_spool_file_number = -1;
 static int hf_smb_print_spool_file_size = -1;
 static int hf_smb_print_spool_file_name = -1;
 static int hf_smb_start_index = -1;
+static int hf_smb_originator_name = -1;
+static int hf_smb_destination_name = -1;
+static int hf_smb_message_len = -1;
+static int hf_smb_message = -1;
+static int hf_smb_mgid = -1;
+static int hf_smb_forwarded_name = -1;
+static int hf_smb_machine_name = -1;
 static int hf_smb_cancel_to = -1;
 static int hf_smb_trans2_subcmd = -1;
 static int hf_smb_trans_name = -1;
@@ -472,6 +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;
@@ -509,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;
@@ -521,6 +557,8 @@ static int hf_smb_volume_serial_num = -1;
 static int hf_smb_volume_label_len = -1;
 static int hf_smb_volume_label = -1;
 static int hf_smb_free_alloc_units64 = -1;
+static int hf_smb_caller_free_alloc_units64 = -1;
+static int hf_smb_actual_free_alloc_units64 = -1;
 static int hf_smb_max_name_len = -1;
 static int hf_smb_fs_name_len = -1;
 static int hf_smb_fs_name = -1;
@@ -538,6 +576,23 @@ static int hf_smb_fs_attr_fc = -1;
 static int hf_smb_fs_attr_vq = -1;
 static int hf_smb_fs_attr_dim = -1;
 static int hf_smb_fs_attr_vic = -1;
+static int hf_smb_quota_flags_enabled = -1;
+static int hf_smb_quota_flags_deny_disk = -1;
+static int hf_smb_quota_flags_log_limit = -1;
+static int hf_smb_quota_flags_log_warning = -1;
+static int hf_smb_soft_quota_limit = -1;
+static int hf_smb_hard_quota_limit = -1;
+static int hf_smb_user_quota_used = -1;
+static int hf_smb_user_quota_offset = -1;
+static int hf_smb_nt_rename_level = -1;
+static int hf_smb_cluster_count = -1;
+static int hf_smb_segments = -1;
+static int hf_smb_segment = -1;
+static int hf_smb_segment_overlap = -1;
+static int hf_smb_segment_overlap_conflict = -1;
+static int hf_smb_segment_multiple_tails = -1;
+static int hf_smb_segment_too_long_fragment = -1;
+static int hf_smb_segment_error = -1;
 
 static gint ett_smb = -1;
 static gint ett_smb_hdr = -1;
@@ -562,8 +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_64bit_time = -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;
@@ -583,6 +637,8 @@ static gint ett_smb_nt_create_options = -1;
 static gint ett_smb_nt_share_access = -1;
 static gint ett_smb_nt_security_flags = -1;
 static gint ett_smb_nt_trans_setup = -1;
+static gint ett_smb_nt_trans_data = -1;
+static gint ett_smb_nt_trans_param = -1;
 static gint ett_smb_nt_notify_completion_filter = -1;
 static gint ett_smb_nt_ioctl_flags = -1;
 static gint ett_smb_security_information_mask = -1;
@@ -590,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;
@@ -600,20 +660,37 @@ static gint ett_smb_ff2_data = -1;
 static gint ett_smb_device_characteristics = -1;
 static gint ett_smb_fs_attributes = -1;
 static gint ett_smb_segments = -1;
+static gint ett_smb_segment = -1;
 static gint ett_smb_sec_desc = -1;
 static gint ett_smb_sid = -1;
 static gint ett_smb_acl = -1;
 static gint ett_smb_ace = -1;
 static gint ett_smb_ace_flags = -1;
 static gint ett_smb_sec_desc_type = -1;
+static gint ett_smb_quotaflags = -1;
+static gint ett_smb_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, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
-static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
-    int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
-    gboolean exactlen, guint16 *bcp);
+static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
 
 /*
  * Macros for use in the main dissector routines for an SMB.
@@ -721,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;
@@ -859,6 +936,7 @@ static int smb_nt_transact_info_init_count = 200;
 typedef struct {
        int subcmd;
        int info_level;
+       gboolean resume_keys;   /* if "return resume" keys set in T2 FIND_FIRST request */
 } smb_transact2_info_t;
 
 static GMemChunk *smb_transact2_info_chunk = NULL;
@@ -1071,7 +1149,7 @@ LocTimeDiff(time_t lt)
 }
 
 static int
-dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
+dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
 {
        guint32 timeval;
        nstime_t ts;
@@ -1097,32 +1175,106 @@ dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
        return offset;
 }
 
-static int
-dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *str, int hf_date)
+#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
+
+/*
+ * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
+ * to an "nstime_t".
+ * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
+ * midnight "UTC", in 100ns units.
+ * Return TRUE if the conversion succeeds, FALSE otherwise.
+ *
+ * According to the Samba code, it appears to be kludge-GMT (at least for
+ * file listings). This means it's the GMT you get by taking a local time
+ * and adding the server time zone offset.  This is NOT the same as GMT in
+ * some cases.   However, we don't know the server time zone, so we don't
+ * do that adjustment.
+ *
+ * This code is based on the Samba code:
+ *
+ *     Unix SMB/Netbios implementation.
+ *     Version 1.9.
+ *     time handling functions
+ *     Copyright (C) Andrew Tridgell 1992-1998
+ */
+static gboolean
+nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
 {
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-       nstime_t tv;
+       double d;
+       /* The next two lines are a fix needed for the 
+           broken SCO compiler. JRA. */
+       time_t l_time_min = TIME_T_MIN;
+       time_t l_time_max = TIME_T_MAX;
 
-       /* XXXX we need some way to represent this as a time
-          properly. For now we display everything as 8 bytes*/
+       if (filetime_high == 0)
+               return FALSE;
 
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 8,
-                       str);
-               tree = proto_item_add_subtree(item, ett_smb_64bit_time);
-       }
+       /*
+        * Get the time as a double, in seconds and fractional seconds.
+        */
+       d = ((double)filetime_high)*4.0*(double)(1<<30);
+       d += filetime_low;
+       d *= 1.0e-7;
+       /* Now adjust by 369 years, to make the seconds since 1970. */
+       d -= TIME_FIXUP_CONSTANT;
+
+       if (!(l_time_min <= d && d <= l_time_max))
+               return FALSE;
+
+       /*
+        * Get the time as seconds and nanoseconds.
+        */
+       tv->secs = d;
+       tv->nsecs = (d - tv->secs)*1000000000;
 
-       proto_tree_add_bytes_format(tree, hf_smb_unknown, tvb, offset, 8, tvb_get_ptr(tvb, offset, 8), "%s: can't decode this yet", str);
+       return TRUE;
+}
+
+int
+dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
+{
+       guint32 filetime_high, filetime_low;
+       nstime_t ts;
+
+       /* XXX there seems also to be another special time value which is fairly common :
+          0x40000000 00000000  
+          the meaning of this one is yet unknown 
+       */
+       if (tree) {
+               filetime_low = tvb_get_letohl(tvb, offset);
+               filetime_high = tvb_get_letohl(tvb, offset + 4);
+               if (filetime_low == 0 && filetime_high == 0) {
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: No time specified (0)",
+                           proto_registrar_get_name(hf_date));
+               } else if(filetime_low==0 && filetime_high==0x80000000){
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: Infinity (relative time)",
+                           proto_registrar_get_name(hf_date));
+               } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: Infinity (absolute time)",
+                           proto_registrar_get_name(hf_date));
+               } else {                        
+                       if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
+                               proto_tree_add_time(tree, hf_date, tvb,
+                                   offset, 8, &ts);
+                       } else {
+                               proto_tree_add_text(tree, tvb, offset, 8,
+                                   "%s: Time can't be converted",
+                                   proto_registrar_get_name(hf_date));
+                       }
+               }
+       }
 
        offset += 8;
        return offset;
 }
 
 static int
-dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
-    int hf_dos_time, gboolean time_first)
+dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+    int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
 {
        guint16 dos_time, dos_date;
        proto_item *item = NULL;
@@ -1146,8 +1298,8 @@ dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
                dos_time = tvb_get_letohs(tvb, offset+2);
        }
 
-       if ((dos_time == 0xffff && dos_time == 0xffff) ||
-           (dos_time == 0 && dos_time == 0)) {
+       if ((dos_date == 0xffff && dos_time == 0xffff) ||
+           (dos_date == 0 && dos_time == 0)) {
                /*
                 * No date/time specified.
                 */
@@ -1252,7 +1404,7 @@ static const true_false_string tfs_da_writetru = {
        "Write through disabled"
 };
 static int
-dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
+dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1399,7 +1551,7 @@ static const true_false_string tfs_file_attribute_encrypted = {
 };
 
 static int
-dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1432,7 +1584,7 @@ dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
 
 /* 3.11 */
 static int
-dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -1506,7 +1658,7 @@ dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
 }
 
 static int
-dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -1563,7 +1715,7 @@ static const true_false_string tfs_search_attribute_archive = {
 };
 
 static int
-dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1749,7 +1901,7 @@ static const true_false_string tfs_server_cap_extended_security = {
        "Extended security exchanges are not supported"
 };
 static int
-dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -1816,7 +1968,7 @@ static const true_false_string tfs_rm_write = {
 };
 
 static int
-dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -1859,7 +2011,7 @@ static const true_false_string tfs_sm_sig_required = {
 };
 
 static int
-dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
+dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
 {
        guint16 mask = 0;
        proto_item *item = NULL;
@@ -1893,7 +2045,7 @@ dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *par
 }
 
 static int
-dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        proto_item *it = NULL;
        proto_tree *tr = NULL;
@@ -1945,8 +2097,9 @@ dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
 }
 
 static int
-dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        guint8 wc;
        guint16 dialect;
        const char *dn;
@@ -1992,8 +2145,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
        switch(wc){
        case 13:
                /* Security Mode */
-               offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
-                               wc);
+               offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
 
                /* Maximum Transmit Buffer Size */
                proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
@@ -2011,7 +2163,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                offset += 2;
 
                /* raw mode */
-               offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
+               offset = dissect_negprot_rawmode(tvb, tree, offset);
 
                /* session key */
                proto_tree_add_item(tree, hf_smb_session_key,
@@ -2019,7 +2171,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                offset += 4;
 
                /* current time and date at server */
-               offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
+               offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
                    TRUE);
 
                /* time zone */
@@ -2040,7 +2192,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
        case 17:
                /* Security Mode */
-               offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
+               offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
 
                /* Maximum Multiplex Count */
                proto_tree_add_item(tree, hf_smb_max_mpx_count,
@@ -2068,12 +2220,12 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                offset += 4;
 
                /* server capabilities */
-               caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+               caps = dissect_negprot_capabilities(tvb, tree, offset);
                offset += 4;
 
                /* system time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                               "System Time", hf_smb_system_time);
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
+                               hf_smb_system_time);
 
                /* time zone */
                tz = tvb_get_letohs(tvb, offset);
@@ -2102,9 +2254,22 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                        COUNT_BYTES(ekl);
                }
 
-               /* domain */
+               /*
+                * Primary domain.
+                *
+                * XXX - not present if negotiated dialect isn't
+                * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
+                * have to see the request, or assume what dialect strings
+                * were sent, to determine that.
+                *
+                * Is this something other than a primary domain if the
+                * negotiated dialect is Windows for Workgroups 3.1a?
+                * It appears to be 8 bytes of binary data in at least
+                * one capture - is that an encryption key or something
+                * such as that?
+                */
                dn = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &dn_len, FALSE, FALSE, &bc);
+                       si->unicode, &dn_len, FALSE, FALSE, &bc);
                if (dn == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
@@ -2114,8 +2279,6 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
        case 17:
                if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
-                       smb_info_t *si;
-
                        /* challenge/response encryption key */
                        /* XXX - is this aligned on an even boundary? */
                        if(ekl){
@@ -2127,18 +2290,35 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
                        /* domain */
                        /* this string is special, unicode is flagged in caps */
-                       /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
-                       si = pinfo->private_data;
+                       /* This string is NOT padded to be 16bit aligned.
+                          (seen in actual capture)
+                          XXX - I've seen a capture where it appears to be
+                          so aligned, but I've also seen captures where
+                          it is.  The captures where it appeared to be
+                          aligned may have been from buggy servers. */
                        si->unicode = (caps&SERVER_CAP_UNICODE);
                        dn = get_unicode_or_ascii_string(tvb,
-                               &offset, pinfo, &dn_len, TRUE, FALSE,
+                               &offset, si->unicode, &dn_len, TRUE, FALSE,
                                &bc);
                        if (dn == NULL)
                                goto endofcommand;
                        proto_tree_add_string(tree, hf_smb_primary_domain,
                                tvb, offset, dn_len, dn);
                        COUNT_BYTES(dn_len);
+
+                       /* server name, seen in w2k pro capture */
+                       dn = get_unicode_or_ascii_string(tvb,
+                               &offset, si->unicode, &dn_len, TRUE, FALSE,
+                               &bc);
+                       if (dn == NULL)
+                               goto endofcommand;
+                       proto_tree_add_string(tree, hf_smb_server,
+                               tvb, offset, dn_len, dn);
+                       COUNT_BYTES(dn_len);
+
                } else {
+                       proto_item *blob_item;
+
                        /* guid */
                        /* XXX - show it in the standard Microsoft format
                           for GUIDs? */
@@ -2147,13 +2327,25 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
                                tvb, offset, 16, TRUE);
                        COUNT_BYTES(16);
 
+                       blob_item = proto_tree_add_item(
+                               tree, hf_smb_security_blob,
+                               tvb, offset, bc, TRUE);
+
                        /* security blob */
-                       /* XXX - is this ASN.1-encoded?  Is it a Kerberos
-                          data structure, at least in NT 5.0-and-later
-                          server replies? */
                        if(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);
                        }
                }
@@ -2167,8 +2359,9 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
 
 static int
-dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int dn_len;
        const char *dn;
        guint8 wc;
@@ -2184,7 +2377,7 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
        COUNT_BYTES(1);
 
        /* dir name */
-       dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
+       dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
                FALSE, FALSE, &bc);
        if (dn == NULL)
                goto endofcommand;
@@ -2202,7 +2395,7 @@ dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
 }
 
 static int
-dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -2217,7 +2410,7 @@ dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, p
 }
 
 static int
-dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 ec, bc;
        guint8 wc;
@@ -2243,7 +2436,7 @@ dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
 }
 
 static int
-dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 bc;
        guint8 wc;
@@ -2268,8 +2461,9 @@ dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
 }
 
 static int
-dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int an_len, pwlen;
        const char *an;
        guint8 wc;
@@ -2286,7 +2480,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
        /* Path */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_path, tvb,
@@ -2317,7 +2511,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 
        /* Service */
        an = get_unicode_or_ascii_string(tvb, &offset,
-               pinfo, &an_len, FALSE, FALSE, &bc);
+               si->unicode, &an_len, FALSE, FALSE, &bc);
        if (an == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_service, tvb,
@@ -2330,7 +2524,7 @@ dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 }
 
 static int
-dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -2364,7 +2558,7 @@ static const value_string of_open[] = {
        {0, NULL}
 };
 static int
-dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -2392,7 +2586,7 @@ dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
 static const true_false_string tfs_mf_file = {
        "Target must be a file",
        "Target needn't be a file"
- };
+};
 static const true_false_string tfs_mf_dir = {
        "Target must be a directory",
        "Target needn't be a directory"
@@ -2402,7 +2596,7 @@ static const true_false_string tfs_mf_verify = {
        "Don't have to verify writes"
 };
 static int
-dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -2413,7 +2607,7 @@ dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, i
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
-               tree = proto_item_add_subtree(item, ett_smb_move_flags);
+               tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
        }
  
        proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
@@ -2428,9 +2622,57 @@ dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, i
        return offset;
 }
 
+static const true_false_string tfs_cf_mode = {
+       "ASCII",
+       "Binary"
+};
+static const true_false_string tfs_cf_tree_copy = {
+       "Copy is a tree copy",
+       "Copy is a file copy"
+};
+static const true_false_string tfs_cf_ea_action = {
+       "Fail copy",
+       "Discard EAs"
+};
+static int
+dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint16 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       mask = tvb_get_letohs(tvb, offset);
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 2,
+                       "Flags: 0x%04x", mask);
+               tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
+       }
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
+               tvb, offset, 2, mask);
+       proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
+               tvb, offset, 2, mask);
+
+       offset += 2;
+
+       return offset;
+}
+
 static int
-dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        guint16 tid;
        guint16 bc;
@@ -2446,10 +2688,10 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        offset += 2;
 
        /* open function */
-       offset = dissect_open_function(tvb, pinfo, tree, offset);
+       offset = dissect_open_function(tvb, tree, offset);
 
        /* move flags */
-       offset = dissect_move_flags(tvb, pinfo, tree, offset);
+       offset = dissect_move_flags(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2459,7 +2701,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2477,7 +2719,7 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2495,8 +2737,76 @@ dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
 }
 
 static int
-dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       smb_info_t *si = pinfo->private_data;
+       int fn_len;
+       guint16 tid;
+       guint16 bc;
+       guint8 wc;
+       const char *fn;
+
+       WORD_COUNT;
+
+       /* tid */
+       tid = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
+               "TID (target): 0x%04x", tid);
+       offset += 2;
+
+       /* open function */
+       offset = dissect_open_function(tvb, tree, offset);
+
+       /* copy flags */
+       offset = dissect_copy_flags(tvb, tree, offset);
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
+               fn_len, fn, "Source File Name: %s", fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
+       }
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
+               fn_len, fn, "Destination File Name: %s", fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -2505,7 +2815,7 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
        WORD_COUNT;
 
        /* # of files moved */
-       proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
+       proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
        offset += 2;
 
        BYTE_COUNT;
@@ -2516,7 +2826,7 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2530,8 +2840,9 @@ dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
 }
 
 static int
-dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -2540,10 +2851,10 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        WORD_COUNT;
 
        /* desired access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+       offset = dissect_access(tvb, tree, offset, "Desired");
 
        /* Search Attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2553,7 +2864,7 @@ dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2580,7 +2891,7 @@ add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
 }
 
 static int
-dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -2594,17 +2905,17 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
        
        /* File Size */
        proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* granted access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+       offset = dissect_access(tvb, tree, offset, "Granted");
 
        BYTE_COUNT;
 
@@ -2614,7 +2925,7 @@ dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -2635,8 +2946,9 @@ dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, pro
 }
 
 static int
-dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -2645,10 +2957,10 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* creation time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
 
        BYTE_COUNT;
 
@@ -2658,7 +2970,7 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* File Name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2676,19 +2988,20 @@ dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
 
        BYTE_COUNT;
 
@@ -2698,8 +3011,9 @@ dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -2708,7 +3022,7 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* search attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -2718,7 +3032,7 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2736,8 +3050,66 @@ dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       smb_info_t *si = pinfo->private_data;
+       int fn_len;
+       const char *fn;
+       guint8 wc;
+       guint16 bc;
+
+       WORD_COUNT;
+
+       /* search attributes */
+       offset = dissect_search_attributes(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);
+
+       /* old file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
+               fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
+       }
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* file name */
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
+               FALSE, FALSE, &bc);
+       if (fn == NULL)
+               goto endofcommand;
+       proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+               fn);
+       COUNT_BYTES(fn_len);
+
+       if (check_col(pinfo->cinfo, COL_INFO)) {
+               col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+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;
@@ -2746,7 +3118,13 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        WORD_COUNT;
 
        /* search attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
+       proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+       offset += 2;
+
+       proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
+       offset += 4;
 
        BYTE_COUNT;
 
@@ -2756,7 +3134,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* old file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2774,7 +3152,7 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2791,9 +3169,11 @@ dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        return offset;
 }
 
+
 static int
-dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        guint16 bc;
        guint8 wc;
        const char *fn;
@@ -2809,7 +3189,7 @@ dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        COUNT_BYTES(1);
 
        /* File Name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2827,7 +3207,7 @@ dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 }
  
 static int
-dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 bc;
        guint8 wc;
@@ -2835,10 +3215,10 @@ dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        WORD_COUNT;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* Last Write Time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
 
        /* File Size */
        proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
@@ -2856,8 +3236,9 @@ dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 }
 
 static int
-dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -2866,10 +3247,10 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        WORD_COUNT;
 
        /* file attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
 
        /* 10 reserved bytes */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
@@ -2883,7 +3264,7 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -2901,16 +3282,24 @@ dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 }
 
 static int
-dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
+       smb_info_t *si;
+       unsigned int fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
+       if (!pinfo->fd->flags.visited) {
+               /* remember the FID for the processing of the response */
+               si = (smb_info_t *)pinfo->private_data;
+               si->sip->extra_info=(void *)fid;
+       }
 
        /* read count */
        proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
@@ -2932,7 +3321,7 @@ dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 }
 
 int
-dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
+dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
 {
        int tvblen;
 
@@ -2956,10 +3345,37 @@ dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
 }
 
 static int
-dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+    proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
+{
+       int tvblen;
+       tvbuff_t *dcerpc_tvb;
+
+       if(bc>datalen){
+               /* We have some initial padding bytes. */
+               /* XXX - use the data offset here instead? */
+               proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
+                       TRUE);
+               offset += bc-datalen;
+               bc = datalen;
+       }
+       tvblen = tvb_length_remaining(tvb, offset);
+       dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
+       dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
+       if(bc>tvblen)
+               offset += tvblen;
+       else
+               offset += bc;
+       return offset;
+}
+
+static int
+dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 cnt=0, bc;
        guint8 wc;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       int fid=0;
 
        WORD_COUNT;
 
@@ -2972,6 +3388,13 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
        offset += 8;
 
+       /* If we have seen the request, then print which FID this refers to */
+       /* first check if we have seen the request */
+       if(si->sip != NULL && si->sip->frame_req>0){
+               fid=(int)si->sip->extra_info;
+               add_fid(tvb, pinfo, tree, 0, 0, fid);
+       }
+
        BYTE_COUNT;
 
        /* buffer format */
@@ -2984,10 +3407,20 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
        COUNT_BYTES(2);
 
-       if (bc != 0) {
-               /* file data */
-               offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
-               bc = 0;
+       /* another way to transport DCERPC over SMB is to skip Transaction completely and just
+          read write */
+       if(bc){
+               if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, bc, fid);
+               } else {
+                       /* ordinary file data, or we didn't see the request,
+                          so we don't know whether this is a DCERPC call
+                          or not */
+                       offset = dissect_file_data(tvb, tree, offset, bc, bc);
+               }
+               bc = 0;
        }
 
        END_OF_SMB
@@ -2996,7 +3429,7 @@ dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 cnt, bc;
        guint8 wc;
@@ -3031,15 +3464,18 @@ dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 
 static int
-dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
-       guint16 cnt=0, bc;
+       guint32 ofs=0;
+       guint16 cnt=0, bc, fid=0;
        guint8 wc;
+       smb_info_t *si = (smb_info_t *)pinfo->private_data;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* write count */
@@ -3048,9 +3484,15 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %u byte%s at offset %u", cnt, 
+                               (cnt == 1) ? "" : "s", ofs);
+
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
        offset += 2;
@@ -3068,8 +3510,14 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(2);
 
        if (bc != 0) {
-               /* file data */
-               offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
+               if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, bc, fid);
+               } else {
+                       /* ordinary file data */
+                       offset = dissect_file_data(tvb, tree, offset, bc, bc);
+               }
                bc = 0;
        }
 
@@ -3079,17 +3527,22 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
  
 static int
-dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, cnt;
 
        WORD_COUNT;
 
        /* write count */
+       cnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -3098,15 +3551,16 @@ dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* lock count */
@@ -3125,8 +3579,9 @@ dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
 }
 
 static int
-dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -3139,7 +3594,7 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        offset += 2;
 
        /* Creation time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
 
        BYTE_COUNT;
 
@@ -3149,7 +3604,7 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        COUNT_BYTES(1);
 
        /* directory name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -3167,13 +3622,13 @@ dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 static int
-dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
-       guint16 bc;
-       guint16 fid;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
@@ -3190,7 +3645,7 @@ dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -3211,15 +3666,16 @@ static const value_string seek_mode_vals[] = {
 };
 
 static int
-dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* Seek Mode */
@@ -3238,7 +3694,7 @@ dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 }
 
 static int
-dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3257,29 +3713,30 @@ dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
  
 static int
-dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* create time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
 
        /* access time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
 
        /* last write time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
 
@@ -3291,7 +3748,7 @@ dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 static int
-dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3299,17 +3756,17 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        WORD_COUNT;
 
        /* create time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
 
        /* access time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
 
        /* last write time */
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
 
@@ -3322,7 +3779,7 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        offset += 4;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -3332,16 +3789,17 @@ dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
 }
 
 static int
-dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 cnt=0;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* write count */
@@ -3354,7 +3812,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 4;
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
        
        if(wc==12){
                /* 12 reserved bytes */
@@ -3369,7 +3827,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
        COUNT_BYTES(1);
        
-       offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
+       offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
        bc = 0; /* XXX */
 
        END_OF_SMB
@@ -3378,7 +3836,7 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 }
  
 static int
-dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3397,16 +3855,17 @@ dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 static int
-dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
        guint32 to;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* offset */
@@ -3444,7 +3903,7 @@ dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 }
 
 static int
-dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3479,15 +3938,16 @@ dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto
 }
 
 static int
-dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* offset */
@@ -3514,7 +3974,7 @@ dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 }
 
 static int
-dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 datalen=0, bc;
        guint8 wc;
@@ -3553,7 +4013,7 @@ dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        BYTE_COUNT;
 
        /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
        bc = 0;
 
        END_OF_SMB
@@ -3583,7 +4043,7 @@ static const true_false_string tfs_write_mode_connectionless = {
        "Connectionless mode NOT requested"
 };
 static int
-dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
+dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -3623,16 +4083,17 @@ dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, i
 }
 
 static int
-dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint32 to;
-       guint16 datalen=0, bc;
+       guint16 datalen=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* total data length */
@@ -3653,7 +4114,7 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 4;
 
        /* mode */
-       offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
+       offset = dissect_write_mode(tvb, tree, offset, 0x0003);
 
        /* 4 reserved bytes */
        proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
@@ -3672,7 +4133,7 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 
        /* file data */
        /* XXX - use the data offset to determine where the data starts? */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
        bc = 0;
 
        END_OF_SMB
@@ -3681,7 +4142,7 @@ dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 }
  
 static int
-dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3700,16 +4161,17 @@ dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint32 to;
-       guint16 datalen=0, bc;
+       guint16 datalen=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* total data length */
@@ -3730,7 +4192,7 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 4;
 
        /* mode */
-       offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
+       offset = dissect_write_mode(tvb, tree, offset, 0x0083);
 
        /* request mask */
        proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
@@ -3749,7 +4211,7 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 
        /* file data */
        /* XXX - use the data offset to determine where the data starts? */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
+       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
        bc = 0;
 
        END_OF_SMB
@@ -3758,7 +4220,7 @@ dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
 }
  
 static int
-dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3777,7 +4239,7 @@ dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -3797,10 +4259,12 @@ dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, pro
 
 static int
 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
-    proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
+    proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
+    gboolean has_find_id)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        char fname[11+1];
@@ -3818,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 */
@@ -3828,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);
@@ -3844,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];
@@ -3859,18 +4336,19 @@ dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
        }
 
        /* resume key */
-       offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
+       offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
+           trunc, has_find_id);
        if (*trunc)
                return offset;
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(1);
-       offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_dir_info_file_attributes(tvb, tree, offset);
        *bcp -= 1;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
                TRUE);
@@ -3883,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 */
@@ -3899,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, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_,
+    gboolean has_find_id)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint16 rkl;
@@ -3915,7 +4396,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* Search Attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        BYTE_COUNT;
 
@@ -3925,7 +4406,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                TRUE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
@@ -3951,7 +4432,7 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* resume key */
        if(rkl){
                offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
-                   &bc, &trunc);
+                   &bc, &trunc, has_find_id);
                if (trunc)
                        goto endofcommand;
        }
@@ -3962,7 +4443,33 @@ dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 }
 
 static int
-dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_request(tvb, pinfo, tree, offset,
+           smb_tree, FALSE);
+}
+
+static int
+dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_request(tvb, pinfo, tree, offset,
+           smb_tree, TRUE);
+}
+
+static int
+dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_request(tvb, pinfo, tree, offset,
+           smb_tree, TRUE);
+}
+
+static int
+dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_,
+    gboolean has_find_id)
 {
        guint16 count=0;
        guint8 wc;
@@ -3990,7 +4497,7 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        while(count--){
                offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
-                   &bc, &trunc);
+                   &bc, &trunc, has_find_id);
                if (trunc)
                        goto endofcommand;
        }
@@ -4000,6 +4507,59 @@ dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        return offset;
 }
 
+static int
+dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
+           FALSE);
+}
+
+static int
+dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
+           TRUE);
+}
+
+static int
+dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
+    proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint8 wc;
+       guint16 bc;
+       guint16 data_len;
+
+       WORD_COUNT;
+
+       /* reserved */
+       proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* data len */
+       CHECK_BYTE_COUNT(2);
+       data_len = tvb_get_ntohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
+       COUNT_BYTES(2);
+
+       if (data_len != 0) {
+               CHECK_BYTE_COUNT(data_len);
+               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
+                   data_len, TRUE);
+               COUNT_BYTES(data_len);
+       }
+
+       END_OF_SMB
+
+       return offset;
+}
+
 static const value_string locking_ol_vals[] = {
        {0,     "Client is not holding oplock on this file"},
        {1,     "Level 2 oplock currently held by client"},
@@ -4027,10 +4587,10 @@ static const true_false_string tfs_lock_type_shared = {
        "This is an exclusive lock"
 };
 static int
-dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff, lt=0;
-       guint16 andxoffset=0, un=0, ln=0, bc;
+       guint16 andxoffset=0, un=0, ln=0, bc, fid;
        guint32 to;
        proto_item *litem = NULL;
        proto_tree *ltree = NULL;
@@ -4059,7 +4619,8 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        offset += 2;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* lock type */
@@ -4241,13 +4802,13 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        }
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
 
 static int
-dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0;
@@ -4278,7 +4839,7 @@ dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4296,7 +4857,7 @@ static const true_false_string tfs_oa_lock = {
        "File is opened by another user (or mode not supported by server)"
 };
 static int
-dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4337,7 +4898,7 @@ static const true_false_string tfs_open_flags_ealen = {
        "Total length of EAs not requested"
 };
 static int
-dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
+dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4385,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;
 
@@ -4409,22 +4971,22 @@ dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        offset += 2;
 
        /* open flags */
-       offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
+       offset = dissect_open_flags(tvb, tree, offset, 0x0007);
 
        /* desired access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+       offset = dissect_access(tvb, tree, offset, "Desired");
 
        /* Search Attributes */
-       offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_search_attributes(tvb, tree, offset);
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* creation time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
        
        /* open function */
-       offset = dissect_open_function(tvb, pinfo, tree, offset);
+       offset = dissect_open_function(tvb, tree, offset);
 
        /* allocation size */
        proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
@@ -4437,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;
@@ -4452,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4478,8 +5040,8 @@ static const value_string ipc_state_read_mode_vals[] = {
 };
 
 int
-dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
-    int offset, gboolean setstate)
+dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
+    gboolean setstate)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4546,27 +5108,27 @@ dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* File Attributes */
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
 
        /* last write time */
-       offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
+       offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
        
        /* File Size */
        proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* granted access */
-       offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+       offset = dissect_access(tvb, tree, offset, "Granted");
 
        /* File Type */
        proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
        offset += 2;
 
        /* IPC State */
-       offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+       offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
        /* open_action */
-       offset = dissect_open_action(tvb, pinfo, tree, offset);
+       offset = dissect_open_action(tvb, tree, offset);
 
        /* server fid */
        proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
@@ -4581,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4590,7 +5152,8 @@ static int
 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
-       guint16 andxoffset=0, bc;
+       guint16 andxoffset=0, bc, maxcnt = 0;
+       guint32 ofs = 0;
        smb_info_t *si;
        unsigned int fid;
 
@@ -4625,13 +5188,20 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        }
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* max count */
+       maxcnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %u byte%s at offset %u", maxcnt, 
+                               (maxcnt == 1) ? "" : "s", ofs);
+
        /* min count */
        proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
        offset += 2;
@@ -4655,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4666,6 +5236,7 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
        smb_info_t *si = (smb_info_t *)pinfo->private_data;
+       int fid=0;
 
        WORD_COUNT;
 
@@ -4690,7 +5261,8 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* If we have seen the request, then print which FID this refers to */
        /* first check if we have seen the request */
        if(si->sip != NULL && si->sip->frame_req>0){
-               add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
+               fid=(int)si->sip->extra_info;
+               add_fid(tvb, pinfo, tree, 0, 0, fid);
        }
 
        /* remaining */
@@ -4710,6 +5282,11 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %u byte%s", datalen, 
+                               (datalen == 1) ? "" : "s");
+
        /* data offset */
        dataoffset=tvb_get_letohs(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
@@ -4725,11 +5302,13 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* is this part of DCERPC over SMB reassembly?*/
        if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
            && (bc<=tvb_length_remaining(tvb, offset)) ){
-               guint32 frame;
-               if (si->sip != NULL && (frame=(guint32)g_hash_table_lookup(
+               gpointer hash_value;
+               if (si->sip != NULL && (hash_value = g_hash_table_lookup(
                                                si->ct->dcerpc_fid_to_frame,
                                                si->sip->extra_info)) != NULL) {
                        fragment_data *fd_head;
+                       guint32 frame = GPOINTER_TO_UINT(hash_value);
+
                        /* first fragment is always from a SMB Trans command and
                           offset 0 of the following read/write SMB commands start
                           BEYOND the first Trans SMB payload. Look for offset
@@ -4760,14 +5339,26 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                }
        }
 
-       /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
-       bc = 0;
+       /* another way to transport DCERPC over SMB is to skip Transaction completely and just
+          read write */
+       if(bc){
+               if(si->sip != NULL && si->sip->flags&SMB_SIF_TID_IS_IPC){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, datalen, fid);
+               } else {
+                       /* ordinary file data, or we didn't see the request,
+                          so we don't know whether this is a DCERPC call
+                          or not */
+                       offset = dissect_file_data(tvb, tree, offset, bc, datalen);
+               }
+               bc = 0;
+       }
 
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4775,10 +5366,11 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 static int
 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
+       guint32 ofs=0;
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
        smb_info_t *si = (smb_info_t *)pinfo->private_data;
-       unsigned int fid;
+       unsigned int fid=0;
 
        WORD_COUNT;
 
@@ -4810,6 +5402,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
@@ -4818,7 +5411,7 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 4;
 
        /* mode */
-       offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
+       offset = dissect_write_mode(tvb, tree, offset, 0x000f);
 
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
@@ -4838,6 +5431,8 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
        offset += 2;
 
+       /* FIXME: add byte/offset to COL_INFO */
+
        if(wc==14){
                /* high offset */
                proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
@@ -4848,11 +5443,13 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* is this part of DCERPC over SMB reassembly?*/
        if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
-               guint32 frame;
-               frame=(guint32)g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
+               gpointer hash_value;
+               hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
                        si->sip->extra_info);
-               if(frame){
+               if(hash_value){
                        fragment_data *fd_head;
+                       guint32 frame = GPOINTER_TO_UINT(hash_value);
+
                        /* first fragment is always from a SMB Trans command and
                           offset 0 of the following read/write SMB commands start
                           BEYOND the first Trans SMB payload. Look for offset
@@ -4884,13 +5481,23 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
-       bc = 0;
+       if (bc != 0) {
+               if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
+                       /* dcerpc call */
+                       offset = dissect_file_data_dcerpc(tvb, pinfo, tree,
+                           top_tree, offset, bc, datalen, fid);
+               } else {
+                       /* ordinary file data */
+                       offset = dissect_file_data(tvb, tree, offset,
+                           bc, datalen);
+               }
+               bc = 0;
+       }
 
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4946,7 +5553,7 @@ dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -4957,7 +5564,7 @@ static const true_false_string tfs_setup_action_guest = {
        "Not logged in as GUEST"
 };
 static int
-dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -4986,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;
@@ -5055,7 +5663,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                offset += 4;
 
                /* capabilities */
-               dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+               dissect_negprot_capabilities(tvb, tree, offset);
                offset += 4;
 
                break;
@@ -5078,7 +5686,7 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                offset += 4;
 
                /* capabilities */
-               dissect_negprot_capabilities(tvb, pinfo, tree, offset);
+               dissect_negprot_capabilities(tvb, tree, offset);
                offset += 4;
 
                break;
@@ -5087,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,
@@ -5115,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,
@@ -5128,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,
@@ -5170,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,
@@ -5183,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,
@@ -5191,13 +5813,19 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                COUNT_BYTES(dn_len);
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
-                       col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s@%s",
-                       an,dn);
+                       col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
+
+                       if (!dn[0] && !an[0])
+                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                                               "anonymous");
+                       else
+                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                                               "%s\\%s", dn,an);
                }
 
                /* OS */
                an = get_unicode_or_ascii_string(tvb, &offset,
-                       pinfo, &an_len, FALSE, FALSE, &bc);
+                       si->unicode, &an_len, FALSE, FALSE, &bc);
                if (an == NULL)
                        goto endofcommand;
                proto_tree_add_string(tree, hf_smb_os, tvb,
@@ -5212,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,
@@ -5223,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5234,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;
 
@@ -5258,7 +5887,7 @@ dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tre
        offset += 2;
 
        /* flags */
-       offset = dissect_setup_action(tvb, pinfo, tree, offset);
+       offset = dissect_setup_action(tvb, tree, offset);
 
        if(wc==4){
                /* security blob length */
@@ -5270,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,
@@ -5293,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,
@@ -5303,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,
@@ -5314,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5352,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5368,7 +6011,7 @@ static const true_false_string tfs_connect_support_in_dfs = {
 };
 
 static int
-dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -5398,7 +6041,7 @@ static const true_false_string tfs_disconnect_tid = {
 };
 
 static int
-dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -5426,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;
 
@@ -5450,7 +6094,7 @@ dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        offset += 2;
 
        /* flags */
-       offset = dissect_connect_flags(tvb, pinfo, tree, offset);
+       offset = dissect_connect_flags(tvb, tree, offset);
 
        /* password length*/
        pwlen = tvb_get_letohs(tvb, offset);
@@ -5467,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,
@@ -5496,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5510,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;
 
@@ -5541,7 +6186,7 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                goto bytecount;
 
        /* flags */
-       offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
+       offset = dissect_connect_support_bits(tvb, tree, offset);
        wleft--;
 
        /* XXX - I've seen captures where this is 7, but I have no
@@ -5587,6 +6232,21 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                offset, an_len, an);
        COUNT_BYTES(an_len);
 
+       /* Now when we know the service type, store it so that we know it for later commands down
+          this tree */
+       if(!pinfo->fd->flags.visited){
+               /* Remove any previous entry for this TID */
+               if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
+                       g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
+               }
+               if(strcmp(an,"IPC") == 0){
+                       g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
+               } else {
+                       g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
+               }
+       }
+
+
        if(wc==3){
                if (bc != 0) {
                        /*
@@ -5595,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,
@@ -5607,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -5623,13 +6284,17 @@ dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
 #define NT_TRANS_NOTIFY                4
 #define NT_TRANS_RENAME                5
 #define NT_TRANS_QSD           6
+#define NT_TRANS_GET_USER_QUOTA        7
+#define NT_TRANS_SET_USER_QUOTA 8
 static const value_string nt_cmd_vals[] = {
-       {NT_TRANS_CREATE,       "NT CREATE"},
-       {NT_TRANS_IOCTL,        "NT IOCTL"},
-       {NT_TRANS_SSD,          "NT SET SECURITY DESC"},
-       {NT_TRANS_NOTIFY,       "NT NOTIFY"},
-       {NT_TRANS_RENAME,       "NT RENAME"},
-       {NT_TRANS_QSD,          "NT QUERY SECURITY DESC"},
+       {NT_TRANS_CREATE,               "NT CREATE"},
+       {NT_TRANS_IOCTL,                "NT IOCTL"},
+       {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
+       {NT_TRANS_NOTIFY,               "NT NOTIFY"},
+       {NT_TRANS_RENAME,               "NT RENAME"},
+       {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
+       {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
+       {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
        {0, NULL}
 };
 
@@ -5862,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[] = {
@@ -5936,7 +6601,7 @@ typedef struct _nt_trans_data {
 
 
 static int
-dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -5961,7 +6626,7 @@ dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
 }
 
 static int
-dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -5989,7 +6654,7 @@ dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tr
 
 
 static int
-dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6058,7 +6723,7 @@ dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tre
 }
 
 static int
-dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6149,7 +6814,7 @@ static const true_false_string tfs_nt_create_options_delete_on_close = {
 };
 
 static int
-dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6195,7 +6860,7 @@ dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
 }
  
 static int
-dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6239,7 +6904,7 @@ dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tre
 }
  
 static int
-dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -6290,7 +6955,7 @@ static const true_false_string tfs_nt_qsd_sacl = {
 #define NT_QSD_SACL    0x00000008
 
 static int
-dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -6318,16 +6983,24 @@ dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        return offset;
 }
 
-static int
-dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
+static void
+free_g_string(void *arg)
+{
+       g_string_free(arg, TRUE);
+}
+
+int
+dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
-       int old_offset = offset;
+       int old_offset = offset, sa_offset = offset;
+       guint rid;
        guint8 revision;
        guint8 num_auth;
+        guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
        int i;
-       char str[256], *strp;
+       GString *gstr;
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, -1,
@@ -6341,7 +7014,8 @@ dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
        offset += 1;
 
        switch(revision){
-       case 1:  /*only revision of SOD we will se ?*/
+       case 1:  
+       case 2:  /* Not sure what the different revision numbers mean */
          /* number of authorities*/
          num_auth = tvb_get_guint8(tvb, offset);
          proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
@@ -6350,27 +7024,51 @@ dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
          /* XXX perhaps we should have these thing searchable?
             a new FT_xxx thingie? SMB is quite common!*/
          /* identifier authorities */
-         strp=str;
-         *strp=0;
+
          for(i=0;i<6;i++){
-           sprintf(strp,"%s%d-",strp,tvb_get_guint8(tvb, offset));
+           auth = (auth << 8) + tvb_get_guint8(tvb, offset);
+
            offset++;
          }
-         /* sub authorities */
-         for(i=0;i<num_auth;i++){
-           /* XXX should not be letohl but native byteorder according to
-              samba header files. considering that all non-x86 NT ports
-              are dead we can (?) assume that non le byte encodings
-              will be "uncommon"?*/
-           sprintf(strp,"%s%d-",strp,tvb_get_letohl(tvb, offset));
+
+         proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
+
+          sa_offset = offset;
+
+          gstr = g_string_new("");
+          
+         CLEANUP_PUSH(free_g_string, gstr);
+
+         /* sub authorities, leave RID to last */
+         for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
+           /*
+            * XXX should not be letohl but native byteorder according to
+            * Samba header files.
+            *
+            * However, considering that there were never any NT ports
+            * to big-endian platforms (PowerPC and MIPS ran little-endian,
+            * and IA-64 runs little-endian, as does x86-64), we can (?)
+            * assume that non le byte encodings will be "uncommon"?
+            */
+             g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
+                  tvb_get_letohl(tvb, offset));
+             offset+=4;
+         }
+
+          proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
+
+         if (num_auth > 4) {
+           rid = tvb_get_letohl(tvb, offset);
+           proto_tree_add_text(tree, tvb, offset, 4, "RID: %u", rid);
+           proto_item_append_text(item, ": S-1-%u-%s-%u", auth, gstr->str, rid);
            offset+=4;
          }
-         /* strip trailing '-'*/
-         str[strlen(str)-1]=0;
+         else {
+           proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
+         }
+
+         CLEANUP_CALL_AND_POP;
 
-         proto_tree_add_text(tree, tvb, offset-6-num_auth*4, 6+num_auth*4, "SID: %s", str);
-         proto_item_append_text(item, ": %s", str);
-  
        }
 
        proto_item_set_len(item, offset-old_offset);
@@ -6415,51 +7113,54 @@ static const true_false_string tfs_ace_flags_failed_access = {
 };
 
 #define APPEND_ACE_TEXT(flag, item, string) \
-        if(item && flag){                                     \
-                  proto_item_append_text(item, string);       \
-        }
+       if(flag){                                                       \
+               if(item)                                                \
+                       proto_item_append_text(item, string, sep);      \
+               sep = ", ";                                             \
+       }
 
 static int
-dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
+dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        guint8 mask;
+       char *sep = " ";
 
        mask = tvb_get_guint8(tvb, offset);
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
-                                          "NT ACE Flags:0x%02x", mask);
+                                          "NT ACE Flags: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_ace_flags);
        }
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x80, item, "  Failed Access,");
+       APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x40, item, "  Successful Access,");
+       APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x10, item, "  Inherited ACE,");
+       APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x08, item, "  Inherit Only,");
+       APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x04, item, "  No Propagate Inherit,");
+       APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x02, item, "  Container Inherit,");
+       APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x01, item, "  Object Inherit,");
+       APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
 
 
        offset += 1;
@@ -6467,11 +7168,12 @@ dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tre
 }
 
 static int
-dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
+dissect_nt_v2_ace(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        int old_offset = offset;
+       guint16 size;
        
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, -1,
@@ -6487,29 +7189,34 @@ dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *par
        offset += 1;
 
        /* flags */
-       offset = dissect_nt_v2_ace_flags(tvb, pinfo, offset, tree);
+       offset = dissect_nt_v2_ace_flags(tvb, offset, tree);
 
        /* size */
-       proto_tree_add_item(tree, hf_smb_ace_size, tvb, offset, 2, TRUE);
+       size = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
        offset += 2;
 
        /* access mask */
-       offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+       offset = dissect_nt_access_mask(tvb, tree, offset);
 
        /* SID */
-       offset = dissect_nt_sid(tvb, pinfo, offset, tree, "SID");
+       offset = dissect_nt_sid(tvb, offset, tree, "ACE");
 
        proto_item_set_len(item, offset-old_offset);
-       return offset;
+
+       /* Sometimes there is some spare space at the end of the ACE so use
+          the size field to work out where the end is. */
+
+       return old_offset + size;
 }
 
 static int
-dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
+dissect_nt_acl(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        int old_offset = offset;
-       guint16 revision, size;
+       guint16 revision;
        guint32 num_aces;
 
        if(parent_tree){
@@ -6526,6 +7233,7 @@ dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
 
        switch(revision){
        case 2:  /* only version we will ever see of this structure?*/
+       case 3:
          /* size */
          proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
          offset += 2;
@@ -6537,7 +7245,7 @@ dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
          offset += 4;
 
          while(num_aces--){
-           offset=dissect_nt_v2_ace(tvb, pinfo, offset, tree);
+           offset=dissect_nt_v2_ace(tvb, offset, tree);
          }
        }
 
@@ -6600,7 +7308,7 @@ static const true_false_string tfs_sec_desc_type_self_relative = {
 
 
 static int
-dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
+dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -6645,9 +7353,8 @@ dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tr
        return offset;
 }
 
-
-static int
-dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
+int
+dissect_nt_sec_desc(tvbuff_t *tvb, int offset, proto_tree *parent_tree, int len)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -6673,46 +7380,49 @@ dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *p
        switch(revision){
        case 1:  /* only version we will ever see of this structure?*/
          /* type */
-         offset = dissect_nt_sec_desc_type(tvb, pinfo, offset, tree);
+         offset = dissect_nt_sec_desc_type(tvb, offset, tree);
 
          /* offset to owner sid */
          owner_sid_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID : %d", owner_sid_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
          offset += 4;
 
          /* offset to group sid */
          group_sid_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID : %d", group_sid_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
          offset += 4;
 
          /* offset to sacl */
          sacl_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL : %d", sacl_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
          offset += 4;
 
          /* offset to dacl */
          dacl_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL : %d", dacl_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
          offset += 4;
 
          /*owner SID*/
          if(owner_sid_offset){
-           dissect_nt_sid(tvb, pinfo, old_offset+owner_sid_offset, tree, "Owner");
+           if (len == -1)
+             offset = dissect_nt_sid(tvb, offset, tree, "Owner");
+           else
+             dissect_nt_sid(tvb, old_offset+owner_sid_offset, tree, "Owner");
          }
 
          /*group SID*/
          if(group_sid_offset){
-           dissect_nt_sid(tvb, pinfo, old_offset+group_sid_offset, tree, "Group");
+           dissect_nt_sid(tvb, old_offset+group_sid_offset, tree, "Group");
          }
 
          /* sacl */
          if(sacl_offset){
-           dissect_nt_acl(tvb, pinfo, old_offset+sacl_offset, tree, "System (SACL)");
+           dissect_nt_acl(tvb, old_offset+sacl_offset, tree, "System (SACL)");
          }
 
          /* dacl */
          if(dacl_offset){
-           dissect_nt_acl(tvb, pinfo, old_offset+dacl_offset, tree, "User (DACL)");
+           dissect_nt_acl(tvb, old_offset+dacl_offset, tree, "User (DACL)");
          }
 
        }
@@ -6721,26 +7431,83 @@ dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *p
 }
 
 static int
-dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
+dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
+{
+       int old_offset, old_sid_offset;
+       guint32 qsize;
+
+       do {
+               old_offset=offset;
+
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               qsize=tvb_get_letohl(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               /* length of SID */
+               proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* 16 unknown bytes */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* number of bytes for used quota */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* number of bytes for quota warning */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* number of bytes for quota limit */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* SID of the user */
+               old_sid_offset=offset;
+               offset = dissect_nt_sid(tvb, offset, tree, "Quota");
+               *bcp -= (offset-old_sid_offset);
+
+               if(qsize){
+                       offset = old_offset+qsize;
+               }
+       }while(qsize);
+
+
+       return offset;
+}
+
+
+static int
+dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
+       int old_offset = offset;
+       guint16 bcp=bc; /* XXX fixme */
 
        si = (smb_info_t *)pinfo->private_data;
 
        if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, len,
+               item = proto_tree_add_text(parent_tree, tvb, offset, bc,
                                "%s Data",
                                val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
        }
 
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                /* security descriptor */
                if(ntd->sd_len){
-                       offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, ntd->sd_len);
+                       offset = dissect_nt_sec_desc(tvb, offset, tree, ntd->sd_len);
                }
 
                /* extended attributes */
@@ -6752,12 +7519,12 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
                break;
        case NT_TRANS_IOCTL:
                /* ioctl data */
-               proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
-               offset += len;
+               proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
+               offset += bc;
 
                break;
        case NT_TRANS_SSD:
-               offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
+               offset = dissect_nt_sec_desc(tvb, offset, tree, bc);
                break;
        case NT_TRANS_NOTIFY:
                break;
@@ -6766,6 +7533,28 @@ dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pro
                break;
        case NT_TRANS_QSD:
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               /* unknown 4 bytes */
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 4, TRUE);
+               offset += 4;
+
+               /* length of SID */
+               proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
+               offset +=4;
+
+               offset = dissect_nt_sid(tvb, offset, tree, "Quota");
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
+               break;
+       }
+
+       /* ooops there were data we didnt know how to process */
+       if((offset-old_offset) < bc){
+               proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
+                   bc - (offset-old_offset), TRUE);
+               offset += bc - (offset-old_offset);
        }
 
        return offset;
@@ -6786,13 +7575,13 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "%s Parameters",
                                val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
        }
 
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                /* Create flags */
-               offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
+               offset = dissect_nt_create_bits(tvb, tree, offset);
                bc -= 4;
 
                /* root directory fid */
@@ -6800,7 +7589,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(4);
 
                /* nt access mask */
-               offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+               offset = dissect_nt_access_mask(tvb, tree, offset);
                bc -= 4;
        
                /* allocation size */
@@ -6808,11 +7597,11 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(8);
        
                /* Extended File Attributes */
-               offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+               offset = dissect_file_ext_attr(tvb, tree, offset);
                bc -= 4;
 
                /* share access */
-               offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
+               offset = dissect_nt_share_access(tvb, tree, offset);
                bc -= 4;
        
                /* create disposition */
@@ -6820,7 +7609,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(4);
 
                /* create options */
-               offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
+               offset = dissect_nt_create_options(tvb, tree, offset);
                bc -= 4;
 
                /* sd length */
@@ -6843,11 +7632,11 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                COUNT_BYTES(4);
        
                /* security flags */
-               offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
+               offset = dissect_nt_security_flags(tvb, tree, offset);
                bc -= 1;
 
                /* file name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
                if (fn != NULL) {
                        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                                fn);
@@ -6857,9 +7646,12 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                break;
        case NT_TRANS_IOCTL:
                break;
-       case NT_TRANS_SSD:
+       case NT_TRANS_SSD: {
+               guint16 fid;
+
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* 2 reserved bytes */
@@ -6867,16 +7659,20 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 2;
 
                /* security information */
-               offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
+               offset = dissect_security_information_mask(tvb, tree, offset);
                break;
+       }
        case NT_TRANS_NOTIFY:
                break;
        case NT_TRANS_RENAME:
                /* XXX not documented */
                break;
-       case NT_TRANS_QSD:
+       case NT_TRANS_QSD: {
+               guint16 fid;
+
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* 2 reserved bytes */
@@ -6884,7 +7680,14 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 2;
 
                /* security information */
-               offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
+               offset = dissect_security_information_mask(tvb, tree, offset);
+               break;
+       }
+       case NT_TRANS_GET_USER_QUOTA:
+               /* not decoded yet */
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
                break;
        }
 
@@ -6911,13 +7714,16 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                break;
-       case NT_TRANS_IOCTL:
+       case NT_TRANS_IOCTL: {
+               guint16 fid;
+
                /* function code */
                proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
                offset += 4;
 
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* isfsctl */
@@ -6925,17 +7731,21 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 1;
 
                /* isflags */
-               offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
+               offset = dissect_nt_ioctl_flags(tvb, tree, offset);
 
                break;
+       }
        case NT_TRANS_SSD:
                break;
-       case NT_TRANS_NOTIFY:
+       case NT_TRANS_NOTIFY: {
+               guint16 fid;
+
                /* completion filter */
-               offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
+               offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
 
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* watch tree */
@@ -6947,11 +7757,18 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 1;
 
                break;
+       }
        case NT_TRANS_RENAME:
                /* XXX not documented */
                break;
        case NT_TRANS_QSD:
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               /* not decoded yet */
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
+               break;
        }
  
        return old_offset+len;
@@ -6959,7 +7776,7 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
 
 
 static int
-dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc, sc;
        guint32 pc=0, po=0, pd, dc=0, od=0, dd;
@@ -7149,12 +7966,15 @@ dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 
 
 static int
-dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
+dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, 
+                              int offset, proto_tree *parent_tree, int len, 
+                              nt_trans_data *ntd _U_)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
        smb_nt_transact_info_t *nti;
+       guint16 bcp;
 
        si = (smb_info_t *)pinfo->private_data;
        if (si->sip != NULL)
@@ -7175,7 +7995,7 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "Unknown NT Transaction Data (matching request not seen)");
                }
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
        }
 
        if (nti == NULL) {
@@ -7204,7 +8024,14 @@ dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                 * which may be documented in the Win32 documentation
                 * somewhere.
                 */
-               offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
+               offset = dissect_nt_sec_desc(tvb, offset, tree, len);
+               break;
+       case NT_TRANS_GET_USER_QUOTA:
+               bcp=len;
+               offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
                break;
        }
 
@@ -7212,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;
@@ -7221,8 +8050,11 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
        smb_info_t *si;
        smb_nt_transact_info_t *nti;
        guint16 fid;
-
-       si = (smb_info_t *)pinfo->private_data;
+       int old_offset;
+       guint32 neo;
+       int padcnt;
+
+       si = (smb_info_t *)pinfo->private_data;
        if (si->sip != NULL)
                nti = si->sip->extra_info;
        else
@@ -7241,7 +8073,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                        item = proto_tree_add_text(parent_tree, tvb, offset, len,
                                "Unknown NT Transaction Parameters (matching request not seen)");
                }
-               tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
+               tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
        }
 
        if (nti == NULL) {
@@ -7272,23 +8104,23 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                offset += 4;
 
                /* create time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Create Time", hf_smb_create_time);
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
+                       hf_smb_create_time);
        
                /* access time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Access Time", hf_smb_access_time);
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
+                       hf_smb_access_time);
        
                /* last write time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Write Time", hf_smb_last_write_time);
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
+                       hf_smb_last_write_time);
        
                /* last change time */
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Change Time", hf_smb_change_time);
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
+                       hf_smb_change_time);
        
                /* Extended File Attributes */
-               offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+               offset = dissect_file_ext_attr(tvb, tree, offset);
 
                /* allocation size */
                proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
@@ -7303,7 +8135,7 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                offset += 2;
 
                /* device state */
-               offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+               offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
                /* is directory */
                proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
@@ -7315,8 +8147,11 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                break;
        case NT_TRANS_NOTIFY:
                while(len){
+                       old_offset = offset;
+
                        /* next entry offset */
-                       proto_tree_add_item(tree, hf_smb_next_entry_offset, tvb, offset, 4, TRUE);
+                       neo = tvb_get_letohl(tvb, offset);
+                       proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
                        COUNT_BYTES(4);
                        len -= 4;
                        /* broken implementations */
@@ -7338,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,
@@ -7348,6 +8183,23 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                        /* broken implementations */
                        if(len<0)break;
 
+                       if (neo == 0)
+                               break;  /* no more structures */
+
+                       /* skip to next structure */
+                       padcnt = (old_offset + neo) - offset;
+                       if (padcnt < 0) {
+                               /*
+                                * XXX - this is bogus; flag it?
+                                */
+                               padcnt = 0;
+                       }
+                       if (padcnt != 0) {
+                               COUNT_BYTES(padcnt);
+                               len -= padcnt;
+                               /* broken implementations */
+                               if(len<0)break;
+                       }
                }
                break;
        case NT_TRANS_RENAME:
@@ -7366,13 +8218,23 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
                offset += 4;
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
+                       tvb_get_letohl(tvb, offset));
+               offset += 4;
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
+               break;
        }
 
        return offset;
 }
  
 static int
-dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
+dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, 
+                               int offset, proto_tree *parent_tree, 
+                               int len, nt_trans_data *ntd _U_)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
@@ -7419,13 +8281,19 @@ dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
                break;
        case NT_TRANS_QSD:
                break;
+       case NT_TRANS_GET_USER_QUOTA:
+               /* not decoded yet */
+               break;
+       case NT_TRANS_SET_USER_QUOTA:
+               /* not decoded yet */
+               break;
        }
 
        return offset;
 }
 
 static int
-dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc, sc;
        guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
@@ -7548,22 +8416,12 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
           must create pd_tvb from it 
        */
        if(r_fd){
-               proto_tree *tr;
-               proto_item *it;
-               fragment_data *fd;
-               
-               it = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
-               tr = proto_item_add_subtree(it, ett_smb_segments);
-               for(fd=r_fd->next;fd;fd=fd->next){
-                       proto_tree_add_text(tr, tvb, 0, 0, "Frame:%u Data:%u-%u",
-                                           fd->frame, fd->offset, fd->offset+fd->len-1);
-               }
-               
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
-                                            r_fd->datalen, "Reassembled SMB");
+                                            r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, pd_tvb);
-               pinfo->fragmented = FALSE;
+               add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+
+               show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
        }
 
 
@@ -7625,8 +8483,9 @@ static const value_string print_mode_vals[] = {
 };
  
 static int
-dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
        guint8 wc;
@@ -7650,7 +8509,7 @@ dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        COUNT_BYTES(1);
 
        /* print identifier */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
@@ -7664,16 +8523,17 @@ dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
 
 static int
-dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        int cnt;
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        BYTE_COUNT;
@@ -7690,7 +8550,7 @@ dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        COUNT_BYTES(2);
 
        /* file data */
-       offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
+       offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
 
        END_OF_SMB
 
@@ -7709,7 +8569,7 @@ static const value_string print_status_vals[] = {
 };
  
 static int
-dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -7737,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;
 
@@ -7748,7 +8609,7 @@ dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
 
        /* queued time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_print_queue_date,
                hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
        *bcp -= 4;
@@ -7775,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);
@@ -7786,7 +8647,7 @@ dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
 }
 
 static int
-dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint16 cnt=0, len;
        guint8 wc;
@@ -7831,12 +8692,228 @@ dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 }
 
 
+static int
+dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
+       guint16 message_len;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* originator name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* destination name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* message len */
+       CHECK_BYTE_COUNT(2);
+       message_len = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
+           message_len);
+       COUNT_BYTES(2);
+
+       /* message */
+       CHECK_BYTE_COUNT(message_len);
+       proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
+           TRUE);
+       COUNT_BYTES(message_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* originator name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* destination name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       /* message group ID */
+       proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint16 bc;
+       guint8 wc;
+       guint16 message_len;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* message len */
+       CHECK_BYTE_COUNT(2);
+       message_len = tvb_get_letohs(tvb, offset);
+       proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
+           message_len);
+       COUNT_BYTES(2);
+
+       /* message */
+       CHECK_BYTE_COUNT(message_len);
+       proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
+           TRUE);
+       COUNT_BYTES(message_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* forwarded name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+static int
+dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       int name_len;
+       guint16 bc;
+       guint8 wc;
+
+       WORD_COUNT;
+
+       BYTE_COUNT;
+
+       /* buffer format */
+       CHECK_BYTE_COUNT(1);
+       proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
+       COUNT_BYTES(1);
+
+       /* machine name */
+       /* XXX - what if this runs past bc? */
+       name_len = tvb_strsize(tvb, offset);
+       CHECK_BYTE_COUNT(name_len);
+       proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
+           name_len, TRUE);
+       COUNT_BYTES(name_len);
+
+       END_OF_SMB
+
+       return offset;
+}
+
+
 static int
 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
        guint16 andxoffset=0;
        guint16 bc;
+       smb_info_t *si = pinfo->private_data;
        int fn_len;
        const char *fn;
 
@@ -7870,43 +8947,43 @@ dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        offset += 2;
 
        /* Create flags */
-       offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
+       offset = dissect_nt_create_bits(tvb, tree, offset);
 
        /* root directory fid */
        proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* nt access mask */
-       offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+       offset = dissect_nt_access_mask(tvb, tree, offset);
 
        /* allocation size */
        proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
        offset += 8;
 
        /* Extended File Attributes */
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
 
        /* share access */
-       offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
+       offset = dissect_nt_share_access(tvb, tree, offset);
 
        /* create disposition */
        proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* create options */
-       offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
+       offset = dissect_nt_create_options(tvb, tree, offset);
 
        /* impersonation level */
        proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* security flags */
-       offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
+       offset = dissect_nt_security_flags(tvb, tree, offset);
 
        BYTE_COUNT;
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
        if (fn == NULL)
                goto endofcommand;
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
@@ -7920,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, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
@@ -7969,23 +9046,20 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 4;
 
        /* create time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        
        /* access time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        
        /* last write time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
-       
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
+               hf_smb_last_write_time);
+
        /* last change time */
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        
        /* Extended File Attributes */
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
 
        /* allocation size */
        proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
@@ -8000,7 +9074,7 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        offset += 2;
 
        /* IPC State */
-       offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+       offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
        /* is directory */
        proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
@@ -8011,14 +9085,14 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        END_OF_SMB
 
        /* call AndXCommand (if there are any) */
-       dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
+       dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
 
        return offset;
 }
 
 
 static int
-dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
@@ -8042,6 +9116,7 @@ static const value_string trans2_cmd_vals[] = {
        { 0x01,         "FIND_FIRST2" },
        { 0x02,         "FIND_NEXT2" },
        { 0x03,         "QUERY_FS_INFORMATION" },
+       { 0x04,         "SET_FS_QUOTA" },
        { 0x05,         "QUERY_PATH_INFORMATION" },
        { 0x06,         "SET_PATH_INFORMATION" },
        { 0x07,         "QUERY_FILE_INFORMATION" },
@@ -8117,25 +9192,73 @@ static const value_string qpi_loi_vals[] = {
        { 0x0103,       "Query File EA Info  (4.2.14.6)"},
        { 0x0104,       "Query File Name Info  (4.2.14.7)"},
        { 0x0107,       "Query File All Info  (4.2.14.8)"},
-       { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
+       { 0x0108,       "Query File Alt Name Info  (4.2.14.7)"},
        { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
        { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
        { 0x0200,       "Set File Unix Basic"},
        { 0x0201,       "Set File Unix Link"},
        { 0x0202,       "Set File Unix HardLink"},
+       { 1004,         "Query File Basic Info  (4.2.14.4)"},
+       { 1005,         "Query File Standard Info  (4.2.14.5)"},
+       { 1006,         "Query File Internal Info  (4.2.14.?)"},
+       { 1007,         "Query File EA Info  (4.2.14.6)"},
+       { 1009,         "Query File Name Info  (4.2.14.7)"},
+       { 1010,         "Query File Rename Info  (4.2.14.?)"},
+       { 1011,         "Query File Link Info  (4.2.14.?)"},
+       { 1012,         "Query File Names Info  (4.2.14.?)"},
+       { 1013,         "Query File Disposition Info  (4.2.14.?)"},
+       { 1014,         "Query File Position Info  (4.2.14.?)"},
+       { 1015,         "Query File Full EA Info  (4.2.14.?)"},
+       { 1016,         "Query File Mode Info  (4.2.14.?)"},
+       { 1017,         "Query File Alignment Info  (4.2.14.?)"},
+       { 1018,         "Query File All Info  (4.2.14.8)"},
+       { 1019,         "Query File Allocation Info  (4.2.14.?)"},
+       { 1020,         "Query File End of File Info  (4.2.14.?)"},
+       { 1021,         "Query File Alt Name Info  (4.2.14.7)"},
+       { 1022,         "Query File Stream Info  (4.2.14.10)"},
+       { 1023,         "Query File Pipe Info  (4.2.14.?)"},
+       { 1024,         "Query File Pipe Local Info  (4.2.14.?)"},
+       { 1025,         "Query File Pipe Remote Info  (4.2.14.?)"},
+       { 1026,         "Query File Mailslot Query Info  (4.2.14.?)"},
+       { 1027,         "Query File Mailslot Set Info  (4.2.14.?)"},
+       { 1028,         "Query File Compression Info  (4.2.14.11)"},
+       { 1029,         "Query File ObjectID Info  (4.2.14.?)"},
+       { 1030,         "Query File Completion Info  (4.2.14.?)"},
+       { 1031,         "Query File Move Cluster Info  (4.2.14.?)"},
+       { 1032,         "Query File Quota Info  (4.2.14.?)"},
+       { 1033,         "Query File Reparsepoint Info  (4.2.14.?)"},
+       { 1034,         "Query File Network Open Info  (4.2.14.?)"},
+       { 1035,         "Query File Attribute Tag Info  (4.2.14.?)"},
+       { 1036,         "Query File Tracking Info  (4.2.14.?)"},
+       { 1037,         "Query File Maximum Info  (4.2.14.?)"},
        {0, NULL}
 };
 
 static const value_string qfsi_vals[] = {
        { 1,            "Info Allocation"},
        { 2,            "Info Volume"},
+       { 0x0101,       "Query FS Label Info"},
        { 0x0102,       "Query FS Volume Info"},
        { 0x0103,       "Query FS Size Info"},
        { 0x0104,       "Query FS Device Info"},
        { 0x0105,       "Query FS Attribute Info"},
+       { 0x0301,       "Mac Query FS INFO"},
+       { 1001,         "Query FS Label Info"},
+       { 1002,         "Query FS Volume Info"},
+       { 1003,         "Query FS Size Info"},
+       { 1004,         "Query FS Device Info"},
+       { 1005,         "Query FS Attribute Info"},
+       { 1006,         "Query FS Quota Info"},
+       { 1007,         "Query Full FS Size Info"},
        {0, NULL}
 };
 
+static const value_string nt_rename_vals[] = {
+       { 0x0103,       "Create Hard Link"},
+       {0, NULL}
+};
+
+
 static const value_string delete_pending_vals[] = {
        {0,     "Normal, no pending delete"},
        {1,     "This object has DELETE PENDING"},
@@ -8239,7 +9362,7 @@ static const true_false_string tfs_fs_attr_vic = {
        "This FS is NOT on a compressed volume"
 };
 
-
+#define FF2_RESUME     0x0004
 
 static int
 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
@@ -8247,9 +9370,20 @@ dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, in
        guint16 mask;
        proto_item *item = NULL;
        proto_tree *tree = NULL;
+       smb_info_t *si;
+       smb_transact2_info_t *t2i;
 
        mask = tvb_get_letohs(tvb, offset);
 
+       si = (smb_info_t *)pinfo->private_data;
+       if (si->sip != NULL) {
+               t2i = si->sip->extra_info;
+               if (t2i != NULL) {
+                       if (!pinfo->fd->flags.visited)
+                               t2i->resume_keys = (mask & FF2_RESUME);
+               }
+       }
+
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 2,
                        "Flags: 0x%04x", mask);
@@ -8272,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)
@@ -8302,27 +9463,27 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
        case 0x00:      /*TRANS2_OPEN2*/
                /* open flags */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
+               offset = dissect_open_flags(tvb, tree, offset, 0x000f);
                bc -= 2;
 
                /* desired access */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
+               offset = dissect_access(tvb, tree, offset, "Desired");
                bc -= 2;
 
-               /* 2 reserved bytes */
+               /* Search Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
-               COUNT_BYTES_TRANS(2);
+               offset = dissect_search_attributes(tvb, tree, offset);
+               bc -= 2;
 
                /* File Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_file_attributes(tvb, tree, offset);
                bc -= 2;
 
                /* create time */
                CHECK_BYTE_COUNT_TRANS(4);
-               offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+               offset = dissect_smb_datetime(tvb, tree, offset,
                        hf_smb_create_time,
                        hf_smb_create_dos_date, hf_smb_create_dos_time,
                        TRUE);
@@ -8330,7 +9491,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
 
                /* open function */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_open_function(tvb, pinfo, tree, offset);
+               offset = dissect_open_function(tvb, tree, offset);
                bc -= 2;
 
                /* allocation size */
@@ -8344,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);
@@ -8354,13 +9515,11 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
                        fn);
                }
-
-               /* XXX dont know how to decode FEAList */
                break;
        case 0x01:      /*TRANS2_FIND_FIRST2*/
                /* Search Attributes */
                CHECK_BYTE_COUNT_TRANS(2);
-               offset = dissect_search_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_search_attributes(tvb, tree, offset);
                bc -= 2;
 
                /* search count */
@@ -8387,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);
@@ -8398,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 */
@@ -8431,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);
@@ -8468,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);
@@ -8495,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);
@@ -8507,10 +9664,13 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                }
 
                break;
-       case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
+       case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
+               guint16 fid;
+
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -8522,10 +9682,14 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(2);
                
                break;
-       case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
+       }
+       case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
+               guint16 fid;
+
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -8536,20 +9700,107 @@ 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*/
+               /* this call has no parameter block in the request */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "File system specific parameter block".  (That means
+                * we may not be able to dissect it in any case.)
+                */
+               break;
        case 0x0a:      /*TRANS2_IOCTL2*/
-               /* these calls have no parameter block in the request */
+               /* this call has no parameter block in the request */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "Device/function specific parameter block".  (That
+                * means we may not be able to dissect it in any case.)
+                */
                break;
-       case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
-       case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
-               /* XXX unknown structure*/
+       case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
+               /* Search Attributes */
+               CHECK_BYTE_COUNT_TRANS(2);
+               offset = dissect_search_attributes(tvb, tree, offset);
+               bc -= 2;
+
+               /* Number of changes to wait for */
+               CHECK_BYTE_COUNT_TRANS(2);
+               proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
+               COUNT_BYTES_TRANS(2);
+
+               /* Find Notify information level */
+               CHECK_BYTE_COUNT_TRANS(2);
+               si->info_level = tvb_get_letohs(tvb, offset);
+               if (!pinfo->fd->flags.visited)
+                       t2i->info_level = si->info_level;
+               proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
+               COUNT_BYTES_TRANS(2);
+
+               /* 4 reserved bytes */
+               CHECK_BYTE_COUNT_TRANS(4);
+               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS(4);
+
+               /* file name */
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
+               CHECK_STRING_TRANS(fn);
+               proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
+                       fn);
+               COUNT_BYTES_TRANS(fn_len);
+
+               if (check_col(pinfo->cinfo, COL_INFO)) {
+                       col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
+                       fn);
+               }
+
+               break;
+       }
+       case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
+               /* Monitor handle */
+               CHECK_BYTE_COUNT_TRANS(2);
+               proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
+               COUNT_BYTES_TRANS(2);
+
+               /* Number of changes to wait for */
+               CHECK_BYTE_COUNT_TRANS(2);
+               proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
+               COUNT_BYTES_TRANS(2);
+
                break;
+       }
        case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
                /* 4 reserved bytes */
                CHECK_BYTE_COUNT_TRANS(4);
@@ -8557,7 +9808,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(4);
 
                /* dir name */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
                        FALSE, FALSE, &bc);
                CHECK_STRING_TRANS(fn);
                proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
@@ -8568,8 +9819,6 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                        col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
                        fn);
                }
-
-               /* XXX optional FEAList, unknown what FEAList looks like*/
                break;
        case 0x0e:      /*TRANS2_SESSION_SETUP*/
                /* XXX unknown structure*/
@@ -8581,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);
@@ -8595,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);
@@ -8623,7 +9872,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
  * XXX - just use "dissect_connect_flags()" here?
  */
 static guint16
-dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -8647,7 +9896,7 @@ dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_
  
 
 static int
-dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -8671,7 +9920,7 @@ dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
 }
 
 static int
-dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -8700,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;
 
@@ -8721,11 +9971,11 @@ dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
 
        /* referral flags */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
+       offset = dissect_dfs_referral_flags(tvb, tree, offset);
        *bcp -= 2;
 
        /* node name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
        CHECK_STRING_TRANS_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
                fn);
@@ -8740,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;
@@ -8767,7 +10018,7 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
 
        /* get dfs flags */
        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-       offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
+       offset = dissect_get_dfs_flags(tvb, tree, offset);
        *bcp -= 2;
 
        /* XXX - in at least one capture there appears to be 2 bytes
@@ -8824,14 +10075,14 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
 
                        /* referral flags */
                        CHECK_BYTE_COUNT_TRANS_SUBR(2);
-                       offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
+                       offset = dissect_dfs_referral_flags(tvb, rt, offset);
                        *bcp -= 2;
 
                        switch(version){
 
                        case 1:
                                /* node name */
-                               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+                               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
                                CHECK_STRING_TRANS_SUBR(fn);
                                proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
                                        fn);
@@ -8878,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);
@@ -8897,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);
@@ -8916,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);
@@ -8973,26 +10224,26 @@ dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
    as described in 4.2.14.1
 */
 static int
-dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* create time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
                FALSE);
        *bcp -= 4;
 
        /* access time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
                FALSE);
        *bcp -= 4;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
                FALSE);
        *bcp -= 4;
@@ -9009,7 +10260,7 @@ dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        /* ea size */
@@ -9025,7 +10276,7 @@ dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.2
 */
 static int
-dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* list length */
@@ -9044,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);
@@ -9062,36 +10314,33 @@ dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.4
 */
 static int
-dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create", hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
        
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        *trunc = FALSE;
@@ -9102,7 +10351,7 @@ dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.5
 */
 static int
-dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* allocation size */
@@ -9138,7 +10387,7 @@ dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
    as described in 4.2.14.6
 */
 static int
-dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* ea size */
@@ -9159,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;
 
@@ -9168,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);
@@ -9185,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);
@@ -9199,12 +10451,12 @@ dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        COUNT_BYTES_SUBR(8);
 
        offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
-       if (trunc)
+       if (*trunc)
                return offset;
 
        /* access flags */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
+       offset = dissect_nt_access_mask(tvb, tree, offset);
        COUNT_BYTES_SUBR(4);
 
        /* index number */
@@ -9219,7 +10471,7 @@ dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* mode */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
+       offset = dissect_nt_create_options(tvb, tree, offset);
        *bcp -= 4;
 
        /* alignment */
@@ -9243,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;
@@ -9281,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);
@@ -9315,7 +10568,7 @@ dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
    as described in 4.2.14.11
 */
 static int
-dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
     int offset, guint16 *bcp, gboolean *trunc)
 {
        /* compressed file size */
@@ -9383,34 +10636,43 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                    &trunc);
                break;
        case 0x0101:    /*Query File Basic Info*/
+       case 1004:      /* SMB_FILE_BASIC_INFORMATION */
                offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0102:    /*Query File Standard Info*/
+       case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
                offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0103:    /*Query File EA Info*/
+       case 1007:      /* SMB_FILE_EA_INFORMATION */
                offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0104:    /*Query File Name Info*/
+       case 1009:      /* SMB_FILE_NAME_INFORMATION */
                offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0107:    /*Query File All Info*/
+       case 1018:      /* SMB_FILE_ALL_INFORMATION */
                offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x0108:    /*Query File Alt File Info*/
+       case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
                offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
+       case 1022:      /* SMB_FILE_STREAM_INFORMATION */
+               ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
        case 0x0109:    /*Query File Stream Info*/
                offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
        case 0x010b:    /*Query File Compression Info*/
+       case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
                offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
                    &trunc);
                break;
@@ -9429,6 +10691,88 @@ dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 }
 
 
+static const true_false_string tfs_quota_flags_deny_disk = {
+       "DENY DISK SPACE for users exceeding quota limit",
+       "Do NOT deny disk space for users exceeding quota limit"
+};
+static const true_false_string tfs_quota_flags_log_limit = {
+       "LOG EVENT when a user exceeds their QUOTA LIMIT",
+       "Do NOT log event when a user exceeds their quota limit"
+};
+static const true_false_string tfs_quota_flags_log_warning = {
+       "LOG EVENT when a user exceeds their WARNING LEVEL",
+       "Do NOT log event when a user exceeds their warning level"
+};
+static const true_false_string tfs_quota_flags_enabled = {
+       "Quotas are ENABLED of this fs",
+       "Quotas are NOT enabled on this fs"
+};
+static void
+dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
+{
+       guint8 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       mask = tvb_get_guint8(tvb, offset);
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 1,
+                       "Quota Flags: 0x%02x %s", mask,
+                       mask?"Enabled":"Disabled");
+               tree = proto_item_add_subtree(item, ett_smb_quotaflags);
+       }
+
+       proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
+               tvb, offset, 1, mask);
+       proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
+               tvb, offset, 1, mask);
+       proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
+               tvb, offset, 1, mask);
+
+       if(mask && (!(mask&0x01))){
+               proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
+                       tvb, offset, 1, 0x01);
+       } else {
+               proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
+                       tvb, offset, 1, mask);
+       }
+
+}
+
+static int
+dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
+{
+       /* first 24 bytes are unknown */
+       CHECK_BYTE_COUNT_TRANS_SUBR(24);
+       proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                   offset, 24, TRUE);
+       COUNT_BYTES_TRANS_SUBR(24);
+
+       /* number of bytes for quota warning */
+       CHECK_BYTE_COUNT_TRANS_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
+       COUNT_BYTES_TRANS_SUBR(8);
+
+       /* number of bytes for quota limit */
+       CHECK_BYTE_COUNT_TRANS_SUBR(8);
+       proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
+       COUNT_BYTES_TRANS_SUBR(8);
+
+       /* one byte of quota flags */
+       CHECK_BYTE_COUNT_TRANS_SUBR(1);
+       dissect_quota_flags(tvb, tree, offset);
+       COUNT_BYTES_TRANS_SUBR(1);
+
+       /* these 7 bytes are unknown */
+       CHECK_BYTE_COUNT_TRANS_SUBR(7);
+       proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                   offset, 7, TRUE);
+       COUNT_BYTES_TRANS_SUBR(7);
+
+       return offset;
+}
+
 static int
 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
@@ -9449,43 +10793,96 @@ 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 */
                break;
+       case 0x04:      /* TRANS2_SET_QUOTA */
+               offset = dissect_nt_quota(tvb, tree, offset, &dc);
+               break;
        case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
                /* no data field in this request */
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says there may be "Additional
+                * FileInfoLevel dependent information" here.
+                *
+                * Was that just a cut-and-pasteo?
+                * TRANS2_SET_PATH_INFORMATION *does* have that information
+                * here.
+                */
                break;
        case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
                offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
                break;
        case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
                /* no data field in this request */
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says there may be "Additional
+                * FileInfoLevel dependent information" here.
+                *
+                * Was that just a cut-and-pasteo?
+                * TRANS2_SET_FILE_INFORMATION *does* have that information
+                * here.
+                */
                break;
        case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
                offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
                break;
        case 0x09:      /*TRANS2_FSCTL*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "File system specific data block".  (That means we
+                * may not be able to dissect it in any case.)
+                */
                break;
        case 0x0a:      /*TRANS2_IOCTL2*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains a
+                * "Device/function specific data block".  (That
+                * means we may not be able to dissect it in any case.)
+                */
                break;
        case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains "additional
+                * level dependent match data".
+                */
                break;
        case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
                /*XXX dont know how to decode this yet */
+
+               /*
+                * XXX - "Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990" says this this contains "additional
+                * level dependent monitor information".
+                */
                break;
        case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
-               /* no data block for this one */
+               /* XXX optional FEAList, unknown what FEAList looks like*/
                break;
        case 0x0e:      /*TRANS2_SESSION_SETUP*/
                /*XXX dont know how to decode this yet */
@@ -9510,7 +10907,7 @@ dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
 
 static void
 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
-    packet_info *pinfo, proto_tree *tree)
+    proto_tree *tree)
 {
        int i;
        int offset;
@@ -9563,7 +10960,7 @@ dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
    Transaction2 Secondary 0x33
 */
 static int
-dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc, sc=0;
        int so=offset;
@@ -9628,8 +11025,12 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                offset += 2;
 
                if(si->cmd==SMB_COM_TRANSACTION2){
+                       guint16 fid;
+
                        /* fid */
-                       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+                       fid = tvb_get_letohs(tvb, offset);
+                       add_fid(tvb, pinfo, tree, offset, 2, fid);
+
                        offset += 2;
                }
 
@@ -9665,7 +11066,7 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                offset += 1;
 
                /* transaction flags */
-               tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
+               tf = dissect_transaction_flags(tvb, tree, offset);
                offset += 2;
 
                /* timeout */
@@ -9727,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);
@@ -9746,9 +11150,15 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                                t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
                                                t2i->subcmd = subcmd;
                                                t2i->info_level = -1;
+                                               t2i->resume_keys = FALSE;
                                                si->sip->extra_info = t2i;
                                        }
-                               }     
+                               }
+
+                               /*
+                                * XXX - process TRANS2_FSCTL and
+                                * TRANS2_IOCTL setup words here.
+                                */
                                break;
 
                        case SMB_COM_TRANSACTION:
@@ -9768,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,
@@ -9943,10 +11353,8 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                dissected_trans = dissect_mailslot_smb(sp_tvb,
                                    s_tvb, d_tvb, an+10, pinfo, top_tree);
                        }
-                       if (!dissected_trans) {
-                               dissect_trans_data(s_tvb, p_tvb, d_tvb,
-                                   pinfo, tree);
-                       }
+                       if (!dissected_trans)
+                               dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
                } else {
                        if(check_col(pinfo->cinfo, COL_INFO)){
                                col_append_str(pinfo->cinfo, COL_INFO,
@@ -9972,8 +11380,15 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
+       smb_transact2_info_t *t2i;
+       gboolean resume_keys = FALSE;
 
        si = (smb_info_t *)pinfo->private_data;
+       if (si->sip != NULL) {
+               t2i = si->sip->extra_info;
+               if (t2i != NULL)
+                       resume_keys = t2i->resume_keys;
+       }
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
@@ -9981,23 +11396,30 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
 
+       if (resume_keys) {
+               /* resume key */
+               CHECK_BYTE_COUNT_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
+               COUNT_BYTES_SUBR(4);
+       }
+
        /* create time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
        *bcp -= 4;
 
        /* access time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
        *bcp -= 4;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
        *bcp -= 4;
@@ -10014,7 +11436,7 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        /* file name len */
@@ -10022,9 +11444,13 @@ dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        fn_len = tvb_get_guint8(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
        COUNT_BYTES_SUBR(1);
+       if (si->unicode)
+               fn_len += 2;    /* include terminating '\0' */
+       else
+               fn_len++;       /* include terminating '\0' */
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                fn);
@@ -10052,32 +11478,46 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        smb_info_t *si;
+       smb_transact2_info_t *t2i;
+       gboolean resume_keys = FALSE;
 
        si = (smb_info_t *)pinfo->private_data;
+       if (si->sip != NULL) {
+               t2i = si->sip->extra_info;
+               if (t2i != NULL)
+                       resume_keys = t2i->resume_keys;
+       }
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
                    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
+
+       if (resume_keys) {
+               /* resume key */
+               CHECK_BYTE_COUNT_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
+               COUNT_BYTES_SUBR(4);
+       }
  
        /* create time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_create_time,
                hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
        *bcp -= 4;
 
        /* access time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_access_time,
                hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
        *bcp -= 4;
 
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+       offset = dissect_smb_datetime(tvb, tree, offset,
                hf_smb_last_write_time,
                hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
        *bcp -= 4;
@@ -10094,7 +11534,7 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* File Attributes */
        CHECK_BYTE_COUNT_SUBR(2);
-       offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+       offset = dissect_file_attributes(tvb, tree, offset);
        *bcp -= 2;
 
        /* ea size */
@@ -10109,11 +11549,15 @@ dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        COUNT_BYTES_SUBR(1);
 
        /* file name */
-       fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+       fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
        CHECK_STRING_SUBR(fn);
        proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
                fn);
        COUNT_BYTES_SUBR(fn_len);
+       if (si->unicode)
+               fn_len += 2;    /* include terminating '\0' */
+       else
+               fn_len++;       /* include terminating '\0' */
 
        if (check_col(pinfo->cinfo, COL_INFO)) {
                col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
@@ -10148,6 +11592,11 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
 
+       /*
+        * We assume that the presence of a next entry offset implies the
+        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        */
+
        /* next entry offset */
        CHECK_BYTE_COUNT_SUBR(4);
        neo = tvb_get_letohl(tvb, offset);
@@ -10161,26 +11610,23 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
        
        /* end of file */
@@ -10195,7 +11641,7 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* Extended File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* file name len */
@@ -10205,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);
@@ -10259,6 +11705,11 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
 
+       /*
+        * We assume that the presence of a next entry offset implies the
+        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        */
+
        /* next entry offset */
        CHECK_BYTE_COUNT_SUBR(4);
        neo = tvb_get_letohl(tvb, offset);
@@ -10272,26 +11723,23 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
        
        /* end of file */
@@ -10306,7 +11754,7 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* Extended File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* file name len */
@@ -10321,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);
@@ -10375,6 +11823,12 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
 
+       /*
+        * XXX - I have not seen any of these that contain a resume
+        * key, even though some of the requests had the "return resume
+        * key" flag set.
+        */
+
        /* next entry offset */
        CHECK_BYTE_COUNT_SUBR(4);
        neo = tvb_get_letohl(tvb, offset);
@@ -10388,26 +11842,23 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset,
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
-       offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+       offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
        *bcp -= 8;
        
        /* end of file */
@@ -10422,7 +11873,7 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
 
        /* Extended File Attributes */
        CHECK_BYTE_COUNT_SUBR(4);
-       offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
+       offset = dissect_file_ext_attr(tvb, tree, offset);
        *bcp -= 4;
 
        /* file name len */
@@ -10448,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);
@@ -10508,7 +11959,12 @@ dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
                    val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
                tree = proto_item_add_subtree(item, ett_smb_ff2_data);
        }
+
+       /*
+        * We assume that the presence of a next entry offset implies the
+        * absence of a resume key, as appears to be the case for 4.3.4.6.
+        */
+
        /* next entry offset */
        CHECK_BYTE_COUNT_SUBR(4);
        neo = tvb_get_letohl(tvb, offset);
@@ -10527,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);
@@ -10561,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;
@@ -10626,7 +12083,7 @@ dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
 
 
 static int
-dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -10661,7 +12118,7 @@ dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree
  
 
 static int
-dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint32 mask;
        proto_item *item = NULL;
@@ -10694,8 +12151,33 @@ dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pa
        return offset;
 }
 
-
 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
+
+static const true_false_string tfs_smb_mac_access_ctrl = {
+  "Macintosh Access Control Supported",
+  "Macintosh Access Control Not Supported"
+};
+
+static const true_false_string tfs_smb_mac_getset_comments = {
+  "Macintosh Get & Set Comments Supported",
+  "Macintosh Get & Set Comments Not Supported"
+};
+
+static const true_false_string tfs_smb_mac_desktopdb_calls = {
+  "Macintosh Get & Set Desktop Database Info Supported",
+  "Macintosh Get & Set Desktop Database Info Supported"
+};
+
+static const true_false_string tfs_smb_mac_unique_ids = {
+  "Macintosh Unique IDs Supported",
+  "Macintosh Unique IDs Not Supported"
+};
+
+static const true_false_string tfs_smb_mac_streams = {
+  "Macintosh and Streams Extensions Not Supported",
+  "Macintosh and Streams Extensions Supported"
+};
+
 static int
 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
     int offset, guint16 *bcp)
@@ -10703,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;
@@ -10737,19 +12222,36 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                COUNT_BYTES_TRANS_SUBR(2);
 
                break;
-       case 2:         /* SMB_INFO_VOLUME */
-               /* volume serial number */
+       case 2:         /* SMB_INFO_VOLUME */
+               /* volume serial number */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* volume label length, only one byte here */
+               CHECK_BYTE_COUNT_TRANS_SUBR(1);
+               proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+               COUNT_BYTES_TRANS_SUBR(1);
+
+               /* label */
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
+               CHECK_STRING_TRANS_SUBR(fn);
+               proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
+                       fn);
+               COUNT_BYTES_TRANS_SUBR(fn_len);
+
+               break;
+       case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
+       case 1001:      /* SMB_FS_LABEL_INFORMATION */
+               /* volume label length */
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
+               vll = tvb_get_letohl(tvb, offset);
+               proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
                COUNT_BYTES_TRANS_SUBR(4);
 
-               /* volume label length, only one byte here */
-               CHECK_BYTE_COUNT_TRANS_SUBR(1);
-               proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
-               COUNT_BYTES_TRANS_SUBR(1);
-
                /* label */
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
+               fn_len = vll;
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
                CHECK_STRING_TRANS_SUBR(fn);
                proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
                        fn);
@@ -10757,10 +12259,11 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                break;
        case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
+       case 1002:      /* SMB_FS_VOLUME_INFORMATION */
                /* create time */
                CHECK_BYTE_COUNT_TRANS_SUBR(8);
-               offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Create Time", hf_smb_create_time);
+               offset = dissect_smb_64bit_time(tvb, tree, offset,
+                       hf_smb_create_time);
                *bcp -= 8;
        
                /* volume serial number */
@@ -10781,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);
@@ -10789,6 +12292,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                break;
        case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
+       case 1003:      /* SMB_FS_SIZE_INFORMATION */
                /* allocation size */
                CHECK_BYTE_COUNT_TRANS_SUBR(8);
                proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
@@ -10811,6 +12315,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                break;
        case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
+       case 1004:      /* SMB_FS_DEVICE_INFORMATION */
                /* device type */
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
                proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
@@ -10818,14 +12323,15 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
  
                /* device characteristics */
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
+               offset = dissect_device_characteristics(tvb, tree, offset);
                *bcp -= 4;
        
                break;
        case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
+       case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
                /* FS attributes */
                CHECK_BYTE_COUNT_TRANS_SUBR(4);
-               offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_fs_attributes(tvb, tree, offset);
                *bcp -= 4;
        
                /* max name len */
@@ -10841,12 +12347,116 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
 
                /* label */
                fn_len = fnl;
-               fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
+               fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
                CHECK_STRING_TRANS_SUBR(fn);
                proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
                        fn);
                COUNT_BYTES_TRANS_SUBR(fn_len);
 
+               break;
+       case 0x301:     /* MAC_QUERY_FS_INFO */
+               /* Create time */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
+               *bcp -= 8;
+               /* Modify Time */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
+               *bcp -= 8;
+               /* Backup Time */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
+               *bcp -= 8;
+               /* Allocation blocks */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb, 
+                                   offset,
+                                   4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Allocation Block Size */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Free Block Count */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Finder Info ... */
+               CHECK_BYTE_COUNT_TRANS_SUBR(32);
+               proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb, 
+                                           offset, 32, 
+                                           tvb_get_ptr(tvb, offset,32),
+                                           "Finder Info: %s",
+                                           tvb_format_text(tvb, offset, 32));
+               COUNT_BYTES_TRANS_SUBR(32);
+               /* Number Files */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb, 
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Number of Root Directories */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Number of files */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Dir Count */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
+                                   offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+               /* Mac Support Flags */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               support = tvb_get_ntohl(tvb, offset);
+               item = proto_tree_add_text(tree, tvb, offset, 4, 
+                                          "Mac Support Flags: 0x%08x", support);
+               ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
+                                      tvb, offset, 4, support);
+               proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
+                                      tvb, offset, 4, support);
+               COUNT_BYTES_TRANS_SUBR(4);
+               break; 
+       case 1006:      /* QUERY_FS_QUOTA_INFO */
+               offset = dissect_nt_quota(tvb, tree, offset, bcp);
+               break;
+       case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
+               /* allocation size */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* caller free allocation units */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* actual free allocation units */
+               CHECK_BYTE_COUNT_TRANS_SUBR(8);
+               proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
+               COUNT_BYTES_TRANS_SUBR(8);
+
+               /* sectors per unit */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* bytes per sector */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
                break;
        }
  
@@ -10945,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 */
@@ -11031,11 +12675,25 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
+               /*
+                * XXX - Microsoft Networks SMB File Sharing Protocol
+                * Extensions Version 3.0, Document Version 1.11,
+                * July 19, 1990 says that the file attributes, create
+                * time (which it says is the last modification time),
+                * data size, granted access, file type, and IPC state
+                * are returned only if bit 0 is set in the open flags,
+                * and that the EA length is returned only if bit 3
+                * is set in the open flags.  Does that mean that,
+                * at least in that SMB dialect, those fields are not
+                * present in the reply parameters if the bits in
+                * question aren't set?
+                */
+
                /* File Attributes */
-               offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+               offset = dissect_file_attributes(tvb, tree, offset);
 
                /* create time */
-               offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
+               offset = dissect_smb_datetime(tvb, tree, offset,
                        hf_smb_create_time, 
                        hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
 
@@ -11044,20 +12702,20 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
                offset += 4;
 
                /* granted access */
-               offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
+               offset = dissect_access(tvb, tree, offset, "Granted");
 
                /* File Type */
                proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
                offset += 2;
 
                /* IPC State */
-               offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
+               offset = dissect_ipc_state(tvb, tree, offset, FALSE);
 
                /* open_action */
-               offset = dissect_open_action(tvb, pinfo, tree, offset);
+               offset = dissect_open_action(tvb, tree, offset);
 
-               /* 4 reserved bytes */
-               proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
+               /* server unique file ID */
+               proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
                offset += 4;
 
                /* ea error offset, only a 16 bit integer here */
@@ -11106,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;
 
@@ -11120,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 */
@@ -11176,11 +12890,10 @@ dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, prot
 
 
 static int
-dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 sc, wc;
        guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
-       gboolean reassembled = FALSE;
        smb_info_t *si;
        smb_transact2_info_t *t2i = NULL;
        guint16 bc;
@@ -11340,22 +13053,11 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
           create pd_tvb from it 
        */
        if(r_fd){
-               proto_tree *tr;
-               proto_item *it;
-               fragment_data *fd;
-               
-               it = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
-               tr = proto_item_add_subtree(it, ett_smb_segments);
-               for(fd=r_fd->next;fd;fd=fd->next){
-                       proto_tree_add_text(tr, tvb, 0, 0, "Frame:%u Data:%u-%u",
-                                           fd->frame, fd->offset, fd->offset+fd->len-1);
-               }
-               
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
-                                            r_fd->datalen, "Reassembled SMB");
+                                            r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, pd_tvb);
-               pinfo->fragmented = FALSE;
+               add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
+               show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
        }
 
 
@@ -11488,8 +13190,7 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                }
                if (!dissected_trans) {
                        /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
-                       dissect_trans_data(s_tvb, p_tvb, d_tvb,
-                                          pinfo, tree);
+                       dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
                }
        }
 
@@ -11508,26 +13209,50 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
 }
 
 
+static int
+dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
+{
+       guint8 wc;
+       guint16 bc;
+
+       WORD_COUNT;
+
+       /* Monitor handle */
+       proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
+       offset += 2;
+
+       BYTE_COUNT;
+
+       END_OF_SMB
+
+       return offset;
+}
+
 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    END Transaction/Transaction2 Primary and secondary requests
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
 
 
 static int
-dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
+dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
 {
        guint8 wc;
        guint16 bc;
 
        WORD_COUNT;
  
-       if (wc != 0)
+       if (wc != 0) {
                proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
+               offset += wc*2;
+       }
 
        BYTE_COUNT;
 
-       if (bc != 0)
+       if (bc != 0) {
                proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
+               offset += bc;
+               bc = 0;
+       }
 
        END_OF_SMB
 
@@ -11539,7 +13264,7 @@ typedef struct _smb_function {
        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
 } smb_function;
 
-smb_function smb_dissector[256] = {
+static smb_function smb_dissector[256] = {
   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
@@ -11569,10 +13294,10 @@ smb_function smb_dissector[256] = {
   /* 0x19 */  {dissect_unknown, dissect_unknown},
   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
-  /* 0x1c */  {dissect_unknown, dissect_unknown},
+  /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
-  /* 0x1f */  {dissect_unknown, dissect_unknown},
+  /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
 
   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
   /* 0x21 */  {dissect_unknown, dissect_unknown},
@@ -11580,11 +13305,11 @@ smb_function smb_dissector[256] = {
   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
   /* 0x25 Transaction*/                {dissect_transaction_request, dissect_transaction_response},
-  /* 0x26 Transaction Secondary */  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
-  /* 0x27 */  {dissect_unknown, dissect_unknown},
-  /* 0x28 */  {dissect_unknown, dissect_unknown},
-  /* 0x29 */  {dissect_unknown, dissect_unknown},
-  /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
+  /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
+  /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
+  /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
+  /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
+  /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
@@ -11592,11 +13317,11 @@ smb_function smb_dissector[256] = {
   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
 
   /* 0x30 */  {dissect_unknown, dissect_unknown},
-  /* 0x31 */  {dissect_unknown, dissect_unknown},
+  /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
   /* 0x32 Transaction2*/               {dissect_transaction_request, dissect_transaction_response},
   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
-  /* 0x35 */  {dissect_unknown, dissect_unknown},
+  /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
   /* 0x36 */  {dissect_unknown, dissect_unknown},
   /* 0x37 */  {dissect_unknown, dissect_unknown},
   /* 0x38 */  {dissect_unknown, dissect_unknown},
@@ -11678,9 +13403,9 @@ smb_function smb_dissector[256] = {
 
   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
-  /* 0x82 */  {dissect_unknown, dissect_unknown},
-  /* 0x83 */  {dissect_unknown, dissect_unknown},
-  /* 0x84 */  {dissect_unknown, dissect_unknown},
+  /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
+  /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
+  /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
   /* 0x85 */  {dissect_unknown, dissect_unknown},
   /* 0x86 */  {dissect_unknown, dissect_unknown},
   /* 0x87 */  {dissect_unknown, dissect_unknown},
@@ -11709,12 +13434,13 @@ smb_function smb_dissector[256] = {
   /* 0x9d */  {dissect_unknown, dissect_unknown},
   /* 0x9e */  {dissect_unknown, dissect_unknown},
   /* 0x9f */  {dissect_unknown, dissect_unknown},
+
   /* 0xa0 NT Transaction*/     {dissect_nt_transaction_request, dissect_nt_transaction_response},
   /* 0xa1 NT Trans secondary*/ {dissect_nt_transaction_request, dissect_nt_transaction_response},
   /* 0xa2 NT CreateAndX*/              {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
   /* 0xa3 */  {dissect_unknown, dissect_unknown},
   /* 0xa4 NT Cancel*/          {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
-  /* 0xa5 */  {dissect_unknown, dissect_unknown},
+  /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
   /* 0xa6 */  {dissect_unknown, dissect_unknown},
   /* 0xa7 */  {dissect_unknown, dissect_unknown},
   /* 0xa8 */  {dissect_unknown, dissect_unknown},
@@ -11742,6 +13468,7 @@ smb_function smb_dissector[256] = {
   /* 0xbd */  {dissect_unknown, dissect_unknown},
   /* 0xbe */  {dissect_unknown, dissect_unknown},
   /* 0xbf */  {dissect_unknown, dissect_unknown},
+
   /* 0xc0 Open Print File*/    {dissect_open_print_file_request, dissect_fid},
   /* 0xc1 Write Print File*/   {dissect_write_print_file_request, dissect_empty},
   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
@@ -11759,17 +13486,17 @@ smb_function smb_dissector[256] = {
   /* 0xce */  {dissect_unknown, dissect_unknown},
   /* 0xcf */  {dissect_unknown, dissect_unknown},
 
-  /* 0xd0 */  {dissect_unknown, dissect_unknown},
-  /* 0xd1 */  {dissect_unknown, dissect_unknown},
-  /* 0xd2 */  {dissect_unknown, dissect_unknown},
-  /* 0xd3 */  {dissect_unknown, dissect_unknown},
-  /* 0xd4 */  {dissect_unknown, dissect_unknown},
-  /* 0xd5 */  {dissect_unknown, dissect_unknown},
-  /* 0xd6 */  {dissect_unknown, dissect_unknown},
-  /* 0xd7 */  {dissect_unknown, dissect_unknown},
-  /* 0xd8 */  {dissect_unknown, dissect_unknown},
-  /* 0xd9 */  {dissect_unknown, dissect_unknown},
-  /* 0xda */  {dissect_unknown, dissect_unknown},
+  /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
+  /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
+  /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
+  /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
+  /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
+  /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
+  /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
+  /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
+  /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
+  /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
+  /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
   /* 0xdb */  {dissect_unknown, dissect_unknown},
   /* 0xdc */  {dissect_unknown, dissect_unknown},
   /* 0xdd */  {dissect_unknown, dissect_unknown},
@@ -11812,7 +13539,7 @@ smb_function smb_dissector[256] = {
 };
 
 static int
-dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
+dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
 {
        int old_offset = offset;
        smb_info_t *si;
@@ -11824,9 +13551,17 @@ dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int
                int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
-                       col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
-                               decode_smb_name(cmd),
-                               (si->request)? "Request" : "Response");
+                       if(first_pdu){
+                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                                       "%s %s",
+                                       decode_smb_name(cmd),
+                                       (si->request)? "Request" : "Response");
+                       } else {
+                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                                       "; %s",
+                                       decode_smb_name(cmd));
+                       }
+                       
                }
 
                cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
@@ -11887,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" },
@@ -11905,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" },
@@ -11988,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" },
@@ -12021,7 +13756,7 @@ static const value_string smb_cmd_vals[] = {
   { 0xA2, "NT Create AndX" },
   { 0xA3, "unknown-0xA3" },
   { 0xA4, "NT Cancel" },
-  { 0xA5, "unknown-0xA5" },
+  { 0xA5, "NT Rename" },
   { 0xA6, "unknown-0xA6" },
   { 0xA7, "unknown-0xA7" },
   { 0xA8, "unknown-0xA8" },
@@ -12064,14 +13799,14 @@ static const value_string smb_cmd_vals[] = {
   { 0xCD, "unknown-0xCD" },
   { 0xCE, "unknown-0xCE" },
   { 0xCF, "unknown-0xCF" },
-  { 0xD0, "SMBsends" },
-  { 0xD1, "SMBsendb" },
-  { 0xD2, "SMBfwdname" },
-  { 0xD3, "SMBcancelf" },
-  { 0xD4, "SMBgetmac" },
-  { 0xD5, "SMBsendstrt" },
-  { 0xD6, "SMBsendend" },
-  { 0xD7, "SMBsendtxt" },
+  { 0xD0, "Send Single Block Message" },
+  { 0xD1, "Send Broadcast Message" },
+  { 0xD2, "Forward User Name" },
+  { 0xD3, "Cancel Forward" },
+  { 0xD4, "Get Machine Name" },
+  { 0xD5, "Send Start of Multi-block Message" },
+  { 0xD6, "Send End of Multi-block Message" },
+  { 0xD7, "Send Text of Multi-block Message" },
   { 0xD8, "SMBreadbulk" },
   { 0xD9, "SMBwritebulk" },
   { 0xDA, "SMBwritebulkdata" },
@@ -12128,7 +13863,7 @@ static char *decode_smb_name(unsigned char cmd)
 
 
 static void
-free_hash_tables(gpointer ctarg, gpointer user_data)
+free_hash_tables(gpointer ctarg, gpointer user_data _U_)
 {
        conv_tables_t *ct = ctarg;
 
@@ -12138,6 +13873,8 @@ free_hash_tables(gpointer ctarg, gpointer user_data)
                g_hash_table_destroy(ct->matched);
        if (ct->dcerpc_fid_to_frame)
                g_hash_table_destroy(ct->dcerpc_fid_to_frame);
+       if (ct->tid_service)
+               g_hash_table_destroy(ct->tid_service);
 }
 
 static void
@@ -12200,159 +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;
-  int copylen;
-
-  if (*bcp == 0) {
-    /* Not enough data in buffer */
-    return NULL;
-  }
-  si = pinfo->private_data;
-  if (si->unicode) {
-    if ((!nopad) && (*offsetp % 2)) {
-      /*
-       * XXX - this should be an offset relative to the beginning of the SMB,
-       * not an offset relative to the beginning of the frame; if the stuff
-       * before the SMB has an odd number of bytes, an offset relative to
-       * the beginning of the frame will give the wrong answer.
-       */
-      (*offsetp)++;   /* Looks like a pad byte there sometimes */
-      (*bcp)--;
-      if (*bcp == 0) {
-        /* Not enough data in buffer */
-        return NULL;
-      }
-    }
-    if(exactlen){
-      string_len = *len;
-      string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
-    } else {
-      string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
-    }
-  } else {
-    if(exactlen){
-      /*
-       * The string we return must be null-terminated.
-       */
-      if (cur == &str[0][0]) {
-        cur = &str[1][0];
-      } else if (cur == &str[1][0]) {  
-        cur = &str[2][0];
-      } else {  
-        cur = &str[0][0];
-      }
-      copylen = *len;
-      if (copylen > MAX_UNICODE_STR_LEN)
-        copylen = MAX_UNICODE_STR_LEN;
-      tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
-      cur[copylen] = '\0';
-      if (copylen > MAX_UNICODE_STR_LEN)
-        strcat(cur, "...");
-      string_len = *len;
-      string = cur;
-    } else {
-      string_len = tvb_strsize(tvb, *offsetp);
-      string = tvb_get_ptr(tvb, *offsetp, string_len);
-    }
-  }
-  *len = string_len;
-  return string;
-}
-
-
-
 static const value_string errcls_types[] = {
   { SMB_SUCCESS, "Success"},
   { SMB_ERRDOS, "DOS Error"},
@@ -12387,7 +13971,8 @@ const value_string DOS_errors[] = {
   {SMBE_nosuchshare, "Requested share does not exist"},
   {SMBE_filexists, "File in operation already exists"},
   {SMBE_cannotopen, "Cannot open the file specified"},
-  {SMBE_unknownlevel, "Unknown level??"},
+  {SMBE_unknownlevel, "Unknown info level"},
+  {SMBE_invalidname, "Invalid name"},
   {SMBE_badpipe, "Named pipe invalid"},
   {SMBE_pipebusy, "All instances of pipe are busy"},
   {SMBE_pipeclosing, "Named pipe close in progress"},
@@ -12407,6 +13992,10 @@ const value_string DOS_errors[] = {
   {SMBE_invalidenvironment, "Invalid environment"},
   {SMBE_printerdriverinuse, "Printer driver in use"},
   {SMBE_invalidparam, "Invalid parameter"},
+  {SMBE_invalidformsize, "Invalid form size"},
+  {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
+  {SMBE_invalidowner, "Invalid owner"},
+  {SMBE_nomoreitems, "No more items"},
   {0, NULL}
   };
 
@@ -12457,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}
 };
@@ -12506,6 +14095,131 @@ static char *decode_smb_error(guint8 errcls, guint16 errcode)
 
 }
 
+
+/* These are the MS country codes from
+
+       http://www.unicode.org/unicode/onlinedat/countries.html
+
+   For countries that share the same number, I choose to use only the
+   name of the largest country. Apologies for this. If this offends you,
+   here is the table to change that.
+
+   This also includes the code of 0 for "Default", which isn't in
+   that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
+   header file.  Presumably it means "don't override the setting
+   on the user's machine".
+
+   Future versions of Microsoft's "winnls.h" header file might include
+   additional codes; the current version matches the Unicode Consortium's
+   table.
+*/
+const value_string ms_country_codes[] = {
+       {  0,   "Default"},
+       {  1,   "USA"},
+       {  2,   "Canada"},
+       {  7,   "Russia"},
+       { 20,   "Egypt"},
+       { 27,   "South Africa"},
+       { 30,   "Greece"},
+       { 31,   "Netherlands"},
+       { 32,   "Belgium"},
+       { 33,   "France"},
+       { 34,   "Spain"},
+       { 36,   "Hungary"},
+       { 39,   "Italy"},
+       { 40,   "Romania"},
+       { 41,   "Switzerland"},
+       { 43,   "Austria"},
+       { 44,   "United Kingdom"},
+       { 45,   "Denmark"},
+       { 46,   "Sweden"},
+       { 47,   "Norway"},
+       { 48,   "Poland"},
+       { 49,   "Germany"},
+       { 51,   "Peru"},
+       { 52,   "Mexico"},
+       { 54,   "Argentina"},
+       { 55,   "Brazil"},
+       { 56,   "Chile"},
+       { 57,   "Colombia"},
+       { 58,   "Venezuela"},
+       { 60,   "Malaysia"},
+       { 61,   "Australia"},
+       { 62,   "Indonesia"},
+       { 63,   "Philippines"},
+       { 64,   "New Zealand"},
+       { 65,   "Singapore"},
+       { 66,   "Thailand"},
+       { 81,   "Japan"},
+       { 82,   "South Korea"},
+       { 84,   "Viet Nam"},
+       { 86,   "China"},
+       { 90,   "Turkey"},
+       { 91,   "India"},
+       { 92,   "Pakistan"},
+       {212,   "Morocco"},
+       {213,   "Algeria"},
+       {216,   "Tunisia"},
+       {218,   "Libya"},
+       {254,   "Kenya"},
+       {263,   "Zimbabwe"},
+       {298,   "Faroe Islands"},
+       {351,   "Portugal"},
+       {352,   "Luxembourg"},
+       {353,   "Ireland"},
+       {354,   "Iceland"},
+       {355,   "Albania"},
+       {358,   "Finland"},
+       {359,   "Bulgaria"},
+       {370,   "Lithuania"},
+       {371,   "Latvia"},
+       {372,   "Estonia"},
+       {374,   "Armenia"},
+       {375,   "Belarus"},
+       {380,   "Ukraine"},
+       {381,   "Serbia"},
+       {385,   "Croatia"},
+       {386,   "Slovenia"},
+       {389,   "Macedonia"},
+       {420,   "Czech Republic"},
+       {421,   "Slovak Republic"},
+       {501,   "Belize"},
+       {502,   "Guatemala"},
+       {503,   "El Salvador"},
+       {504,   "Honduras"},
+       {505,   "Nicaragua"},
+       {506,   "Costa Rica"},
+       {507,   "Panama"},
+       {591,   "Bolivia"},
+       {593,   "Ecuador"},
+       {595,   "Paraguay"},
+       {598,   "Uruguay"},
+       {673,   "Brunei Darussalam"},
+       {852,   "Hong Kong"},
+       {853,   "Macau"},
+       {886,   "Taiwan"},
+       {960,   "Maldives"},
+       {961,   "Lebanon"},
+       {962,   "Jordan"},
+       {963,   "Syria"},
+       {964,   "Iraq"},
+       {965,   "Kuwait"},
+       {966,   "Saudi Arabia"},
+       {967,   "Yemen"},
+       {968,   "Oman"},
+       {971,   "United Arab Emirates"},
+       {972,   "Israel"},
+       {973,   "Bahrain"},
+       {974,   "Qatar"},
+       {976,   "Mongolia"},
+       {981,   "Iran"},
+       {994,   "Azerbaijan"},
+       {995,   "Georgia"},
+       {996,   "Kyrgyzstan"},
+
+       {0,     NULL}
+};
+
 /*
  * NT error codes.
  *
@@ -12621,6 +14335,7 @@ const value_string NT_errors[] = {
   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
   { 0x80000026, "STATUS_LONGJUMP" },
+  { 0x80040111, "MAPI_E_LOGON_FAILED" },
   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
   { 0x80090301, "SEC_E_INVALID_HANDLE" },
   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
@@ -13396,7 +15111,7 @@ static const true_false_string tfs_smb_flags_response = {
 };
 
 static int
-dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint8 mask;
        proto_item *item = NULL;
@@ -13466,7 +15181,7 @@ static const true_false_string tfs_smb_flags2_string = {
        "Strings are ASCII"
 };
 static int
-dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
 {
        guint16 mask;
        proto_item *item = NULL;
@@ -13520,12 +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;
-       guint16 uid, pid, tid, mid;
+       guint32 nt_status = 0;
+       guint8 errclass = 0;
+       guint16 errcode = 0;
        guint32 pid_mid;
        conversation_t *conversation;
+       nstime_t ns;
 
        top_tree=parent_tree;
 
@@ -13558,11 +15273,11 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        } else {
                si.unicode = FALSE;
        }
-       tid = tvb_get_letohs(tvb, offset+24);
-       pid = tvb_get_letohs(tvb, offset+26);
-       uid = tvb_get_letohs(tvb, offset+28);
-       mid = tvb_get_letohs(tvb, offset+30);
-       pid_mid = (pid << 16) | mid;
+       si.tid = tvb_get_letohs(tvb, offset+24);
+       si.pid = tvb_get_letohs(tvb, offset+26);
+       si.uid = tvb_get_letohs(tvb, offset+28);
+       si.mid = tvb_get_letohs(tvb, offset+30);
+       pid_mid = (si.pid << 16) | si.mid;
        si.info_level = -1;
        si.info_count = -1;
 
@@ -13584,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, 
@@ -13602,14 +15317,17 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                si.ct->dcerpc_fid_to_frame=g_hash_table_new(
                        smb_saved_info_hash_unmatched, 
                        smb_saved_info_equal_unmatched);
+               si.ct->tid_service=g_hash_table_new(
+                       smb_saved_info_hash_unmatched, 
+                       smb_saved_info_equal_unmatched);
                conversation_add_proto_data(conversation, proto_smb, si.ct);
        }
 
        if( (si.request)
-           &&  (mid==0)
-           &&  (uid==0)
-           &&  (pid==0)
-           &&  (tid==0) ){
+           &&  (si.mid==0)
+           &&  (si.uid==0)
+           &&  (si.pid==0)
+           &&  (si.tid==0) ){
                /* this is a broadcast SMB packet, there will not be a reply.
                   We dont need to do anything 
                */
@@ -13712,22 +15430,50 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                        */
                        sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
                        if(sip!=NULL){
-                               if(si.request){
-                                       /* ok, we are processing an SMB
-                                          request but there was already
-                                          another "identical" smb resuest
-                                          we had not matched yet.
-                                          This must mean that either we have
-                                          a retransmission or that the
-                                          response to the previous one was
-                                          lost and the client has reused
-                                          the MID for this conversation.
-                                          In either case it's not much more
-                                          we can do than forget the old
-                                          request and concentrate on the 
+                               gboolean cmd_match=FALSE;
+
+                               /*
+                                * Make sure the SMB we found was the
+                                * same command, or a different command
+                                * that's another valid type of reply
+                                * to that command.
+                                */
+                               if(si.cmd==sip->cmd){
+                                       cmd_match=TRUE;
+                               }
+                               else if(si.cmd==SMB_COM_NT_CANCEL){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
+                                    && (sip->cmd==SMB_COM_TRANSACTION)){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
+                                    && (sip->cmd==SMB_COM_TRANSACTION2)){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
+                                    && (sip->cmd==SMB_COM_NT_TRANSACT)){
+                                       cmd_match=TRUE;
+                               }
+
+                               if( (si.request) || (!cmd_match) ) {
+                                       /* If we are processing an SMB request but there was already
+                                          another "identical" smb resuest we had not matched yet.
+                                          This must mean that either we have a retransmission or that the
+                                          response to the previous one was lost and the client has reused
+                                          the MID for this conversation. In either case it's not much more
+                                          we can do than forget the old request and concentrate on the 
                                           present one instead.
+
+                                          We also do this cleanup if we see that the cmd in the original
+                                          request in sip->cmd is not compatible with the current cmd.
+                                          This is to prevent matching errors such as if there were two
+                                          SMBs of different cmds but with identical MID and PID values and
+                                          if ethereal lost the first reply and the second request.
                                        */
                                        g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
+                                       sip=NULL; /* XXX should free it as well */
                                } else {
                                        /* we have found a response to some request we have seen earlier.
                                           What we do now depends on whether this is the first response
@@ -13737,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);
@@ -13759,8 +15501,20 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                sip = g_mem_chunk_alloc(smb_saved_info_chunk);
                                sip->frame_req = pinfo->fd->num;
                                sip->frame_res = 0;
+                               sip->req_time.secs=pinfo->fd->abs_secs;         
+                               sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
+                               sip->flags = 0;
+                               if(g_hash_table_lookup(si.ct->tid_service, (void *)si.tid)
+                                   == (void *)TID_IPC) {
+                                       sip->flags |= SMB_SIF_TID_IS_IPC;
+                               }
+                               sip->cmd = si.cmd;
                                sip->extra_info = NULL;
                                g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
+                               new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
+                               new_key->frame = sip->frame_req;
+                               new_key->pid_mid = pid_mid;
+                               g_hash_table_insert(si.ct->matched, new_key, sip);
                        }
                } else {
                        /* we have seen this packet before; check the
@@ -13792,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);
+                       }
                }
        }
 
@@ -13834,10 +15597,10 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        }
 
        /* flags */
-       offset = dissect_smb_flags(tvb, pinfo, htree, offset);
+       offset = dissect_smb_flags(tvb, htree, offset);
 
        /* flags2 */
-       offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
+       offset = dissect_smb_flags2(tvb, htree, offset);
 
        /*
         * The document at
@@ -13873,23 +15636,23 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
        offset += 12;
 
        /* TID */
-       proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
+       proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si.tid);
        offset += 2;
 
        /* PID */
-       proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
+       proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si.pid);
        offset += 2;
 
        /* UID */
-       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
+       proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si.uid);
        offset += 2;
 
        /* MID */
-       proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, mid);
+       proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
        offset += 2;
 
        pinfo->private_data = &si;
-        dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
+        dissect_smb_command(tvb, pinfo, offset, tree, si.cmd, TRUE);
 
        /* Append error info from this packet to info string. */
        if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
@@ -13904,7 +15667,8 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                 */
                                col_append_fstr(
                                        pinfo->cinfo, COL_INFO, ", Error: %s",
-                                       val_to_str(nt_status, NT_errors, "%s"));
+                                       val_to_str(nt_status, NT_errors,
+                                           "Unknown (0x%08X)"));
                        }
                } else {
                        /*
@@ -13945,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 }},
@@ -14078,7 +15846,7 @@ proto_register_smb(void)
                NULL, 0, "Unique token identifying this session", HFILL }},
 
        { &hf_smb_server_timezone,
-               { "Time Zone", "smb.server.timezone", FT_INT16, BASE_DEC,
+               { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
                NULL, 0, "Current timezone at server.", HFILL }},
 
        { &hf_smb_encryption_key_length,
@@ -14093,12 +15861,16 @@ 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 }},
 
        { &hf_smb_server_guid,
-               { "Server GUID", "smb.server.guid", FT_BYTES, BASE_HEX,
+               { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
                NULL, 0, "Globally unique identifier for this server", HFILL }},
 
        { &hf_smb_security_blob_len,
@@ -14154,79 +15926,79 @@ proto_register_smb(void)
                NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
 
        { &hf_smb_server_cap_raw_mode,
-               { "Raw Mode", "smb.server.cap.raw_mode", FT_BOOLEAN, 32,
+               { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
 
        { &hf_smb_server_cap_mpx_mode,
-               { "MPX Mode", "smb.server.cap.mpx_mode", FT_BOOLEAN, 32,
+               { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
 
        { &hf_smb_server_cap_unicode,
-               { "Unicode", "smb.server.cap.unicode", FT_BOOLEAN, 32,
+               { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
 
        { &hf_smb_server_cap_large_files,
-               { "Large Files", "smb.server.cap.large_files", FT_BOOLEAN, 32,
+               { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
 
        { &hf_smb_server_cap_nt_smbs,
-               { "NT SMBs", "smb.server.cap.nt_smbs", FT_BOOLEAN, 32,
+               { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
 
        { &hf_smb_server_cap_rpc_remote_apis,
-               { "RPC Remote APIs", "smb.server.cap.rpc_remote_apis", FT_BOOLEAN, 32,
+               { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
 
        { &hf_smb_server_cap_nt_status,
-               { "NT Status Codes", "smb.server.cap.nt_status", FT_BOOLEAN, 32,
+               { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
 
        { &hf_smb_server_cap_level_ii_oplocks,
-               { "Level 2 Oplocks", "smb.server.cap.level_2_oplocks", FT_BOOLEAN, 32,
+               { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
 
        { &hf_smb_server_cap_lock_and_read,
-               { "Lock and Read", "smb.server.cap.lock_and_read", FT_BOOLEAN, 32,
+               { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
 
        { &hf_smb_server_cap_nt_find,
-               { "NT Find", "smb.server.cap.nt_find", FT_BOOLEAN, 32,
+               { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
 
        { &hf_smb_server_cap_dfs,
-               { "Dfs", "smb.server.cap.dfs", FT_BOOLEAN, 32,
+               { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
 
        { &hf_smb_server_cap_infolevel_passthru,
-               { "Infolevel Passthru", "smb.server.cap.infolevel_passthru", FT_BOOLEAN, 32,
+               { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
 
        { &hf_smb_server_cap_large_readx,
-               { "Large ReadX", "smb.server.cap.large_readx", FT_BOOLEAN, 32,
+               { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
 
        { &hf_smb_server_cap_large_writex,
-               { "Large WriteX", "smb.server.cap.large_writex", FT_BOOLEAN, 32,
+               { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
 
        { &hf_smb_server_cap_unix,
-               { "UNIX", "smb.server.cap.unix", FT_BOOLEAN, 32,
+               { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
 
        { &hf_smb_server_cap_reserved,
-               { "Reserved", "smb.server.cap.reserved", FT_BOOLEAN, 32,
+               { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
 
        { &hf_smb_server_cap_bulk_transfer,
-               { "Bulk Transfer", "smb.server.cap.bulk_transfer", FT_BOOLEAN, 32,
+               { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
 
        { &hf_smb_server_cap_compressed_data,
-               { "Compressed Data", "smb.server.cap.compressed_data", FT_BOOLEAN, 32,
+               { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
 
        { &hf_smb_server_cap_extended_security,
-               { "Extended Security", "smb.server.cap.extended_security", FT_BOOLEAN, 32,
+               { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
 
        { &hf_smb_system_time,
@@ -14289,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 }},
@@ -14314,91 +16114,91 @@ proto_register_smb(void)
                NULL, 0, "FID: File ID", HFILL }},
 
        { &hf_smb_file_attr_read_only_16bit,
-               { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 16,
+               { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_attr_read_only_8bit,
-               { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 8,
+               { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_attr_hidden_16bit,
-               { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 16,
+               { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_attr_hidden_8bit,
-               { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 8,
+               { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_attr_system_16bit,
-               { "System", "smb.file.attribute.system", FT_BOOLEAN, 16,
+               { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_attr_system_8bit,
-               { "System", "smb.file.attribute.system", FT_BOOLEAN, 8,
+               { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_attr_volume_16bit,
-               { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 16,
+               { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
 
        { &hf_smb_file_attr_volume_8bit,
-               { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 8,
+               { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
 
        { &hf_smb_file_attr_directory_16bit,
-               { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 16,
+               { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_attr_directory_8bit,
-               { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 8,
+               { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_attr_archive_16bit,
-               { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 16,
+               { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_attr_archive_8bit,
-               { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 8,
+               { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_attr_device,
-               { "Device", "smb.file.attribute.device", FT_BOOLEAN, 16,
+               { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
 
        { &hf_smb_file_attr_normal,
-               { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 16,
+               { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
 
        { &hf_smb_file_attr_temporary,
-               { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 16,
+               { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
 
        { &hf_smb_file_attr_sparse,
-               { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 16,
+               { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
 
        { &hf_smb_file_attr_reparse,
-               { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 16,
+               { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
 
        { &hf_smb_file_attr_compressed,
-               { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 16,
+               { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
 
        { &hf_smb_file_attr_offline,
-               { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 16,
+               { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
 
        { &hf_smb_file_attr_not_content_indexed,
-               { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 16,
+               { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
 
        { &hf_smb_file_attr_encrypted,
-               { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 16,
+               { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
 
        { &hf_smb_file_size,
-               { "File Size", "smb.file.size", FT_UINT32, BASE_DEC,
+               { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
                NULL, 0, "File Size", HFILL }},
 
        { &hf_smb_search_attribute_read_only,
@@ -14449,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 }},
@@ -14486,9 +16346,13 @@ proto_register_smb(void)
                NULL, 0, "Padding or unknown data", HFILL }},
 
        { &hf_smb_file_data,
-               { "File Data", "smb.file.data", FT_BYTES, BASE_HEX,
+               { "File Data", "smb.file_data", FT_BYTES, BASE_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 }},
@@ -14597,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 }},
@@ -15109,91 +16977,91 @@ proto_register_smb(void)
                TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
 
        { &hf_smb_file_eattr_read_only,
-               { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 32,
+               { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_eattr_hidden,
-               { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 32,
+               { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_eattr_system,
-               { "System", "smb.file.attribute.system", FT_BOOLEAN, 32,
+               { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_eattr_volume,
-               { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 32,
+               { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
 
        { &hf_smb_file_eattr_directory,
-               { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 32,
+               { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_eattr_archive,
-               { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 32,
+               { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_eattr_device,
-               { "Device", "smb.file.attribute.device", FT_BOOLEAN, 32,
+               { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
 
        { &hf_smb_file_eattr_normal,
-               { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 32,
+               { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
 
        { &hf_smb_file_eattr_temporary,
-               { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 32,
+               { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
 
        { &hf_smb_file_eattr_sparse,
-               { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 32,
+               { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
 
        { &hf_smb_file_eattr_reparse,
-               { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 32,
+               { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
 
        { &hf_smb_file_eattr_compressed,
-               { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 32,
+               { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
 
        { &hf_smb_file_eattr_offline,
-               { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 32,
+               { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
 
        { &hf_smb_file_eattr_not_content_indexed,
-               { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 32,
+               { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
 
        { &hf_smb_file_eattr_encrypted,
-               { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 32,
+               { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
 
        { &hf_smb_file_eattr_write_through,
-               { "Write Through", "smb.file.attribute.write_through", FT_BOOLEAN, 32,
+               { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
 
        { &hf_smb_file_eattr_no_buffering,
-               { "No Buffering", "smb.file.attribute.no_buffering", FT_BOOLEAN, 32,
+               { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
 
        { &hf_smb_file_eattr_random_access,
-               { "Random Access", "smb.file.attribute.random_access", FT_BOOLEAN, 32,
+               { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
 
        { &hf_smb_file_eattr_sequential_scan,
-               { "Sequential Scan", "smb.file.attribute.sequential_scan", FT_BOOLEAN, 32,
+               { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
 
        { &hf_smb_file_eattr_delete_on_close,
-               { "Delete on Close", "smb.file.attribute.delete_on_close", FT_BOOLEAN, 32,
+               { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
 
        { &hf_smb_file_eattr_backup_semantics,
-               { "Backup", "smb.file.attribute.backup_semantics", FT_BOOLEAN, 32,
+               { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
 
        { &hf_smb_file_eattr_posix_semantics,
-               { "Posix", "smb.file.attribute.posix_semantics", FT_BOOLEAN, 32,
+               { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
 
        { &hf_smb_sec_desc_len,
@@ -15228,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 }},
@@ -15254,7 +17126,7 @@ proto_register_smb(void)
 
        { &hf_smb_setup_len,
                { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
-               NULL, 0, "Length of prionter setup data", HFILL }},
+               NULL, 0, "Length of printer setup data", HFILL }},
 
        { &hf_smb_print_mode,
                { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
@@ -15300,6 +17172,34 @@ proto_register_smb(void)
                { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
                NULL, 0, "First queue entry to return", HFILL }},
 
+       { &hf_smb_originator_name,
+               { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Name of sender of message", HFILL }},
+
+       { &hf_smb_destination_name,
+               { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Name of recipient of message", HFILL }},
+
+       { &hf_smb_message_len,
+               { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
+               NULL, 0, "Length of message", HFILL }},
+
+       { &hf_smb_message,
+               { "Message", "smb.message", FT_STRING, BASE_NONE,
+               NULL, 0, "Message text", HFILL }},
+
+       { &hf_smb_mgid,
+               { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
+               NULL, 0, "Message group ID for multi-block messages", HFILL }},
+
+       { &hf_smb_forwarded_name,
+               { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Recipient name being forwarded", HFILL }},
+
+       { &hf_smb_machine_name,
+               { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
+               NULL, 0, "Name of target machine", HFILL }},
+
        { &hf_smb_cancel_to,
                { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
                NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
@@ -15338,7 +17238,7 @@ proto_register_smb(void)
 
        { &hf_smb_ff2_resume,
                { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
-               TFS(&tfs_ff2_resume), 0x0004, "Return resume keys for each entry found", HFILL }},
+               TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
 
        { &hf_smb_ff2_close_eos,
                { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
@@ -15356,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 }},
@@ -15369,9 +17279,17 @@ proto_register_smb(void)
                NULL, 0, "Latest referral version number understood", HFILL }},
 
        { &hf_smb_qfsi_information_level,
-               { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
+               { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
                VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
 
+       { &hf_smb_nt_rename_level,
+               { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
+               VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
+
+       { &hf_smb_cluster_count,
+               { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
+               NULL, 0, "Number of clusters", HFILL }},
+
        { &hf_smb_ea_size,
                { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
                NULL, 0, "Size of file's EA information", HFILL }},
@@ -15504,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 }},
@@ -15517,19 +17447,19 @@ proto_register_smb(void)
                NULL, 0, "Length of Short (8.3) File Name", HFILL }},
 
        { &hf_smb_fs_id,
-               { "FS Id", "smb.fs.id", FT_UINT32, BASE_DEC,
+               { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
                NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
 
        { &hf_smb_sector_unit,
-               { "Sectors/Unit", "smb.fs.sector_per_unit", FT_UINT32, BASE_DEC,
+               { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
                NULL, 0, "Sectors per allocation unit", HFILL }},
 
        { &hf_smb_fs_units,
-               { "Total Units", "smb.fs.units", FT_UINT32, BASE_DEC,
+               { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
                NULL, 0, "Total number of units on this filesystem", HFILL }},
 
        { &hf_smb_fs_sector,
-               { "Bytes per Sector", "smb.fs.bytes_per_sector", FT_UINT32, BASE_DEC,
+               { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
                NULL, 0, "Bytes per sector", HFILL }},
 
        { &hf_smb_avail_units,
@@ -15552,16 +17482,36 @@ proto_register_smb(void)
                { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
                NULL, 0, "Number of free allocation units", HFILL }},
 
+       { &hf_smb_caller_free_alloc_units64,
+               { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
+               NULL, 0, "Number of caller free allocation units", HFILL }},
+
+       { &hf_smb_actual_free_alloc_units64,
+               { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
+               NULL, 0, "Number of actual free allocation units", HFILL }},
+
+       { &hf_smb_soft_quota_limit,
+               { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
+               NULL, 0, "Soft Quota treshold", HFILL }},
+
+       { &hf_smb_hard_quota_limit,
+               { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
+               NULL, 0, "Hard Quota limit", HFILL }},
+
+       { &hf_smb_user_quota_used,
+               { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
+               NULL, 0, "How much Quota is used by this user", HFILL }},
+
        { &hf_smb_max_name_len,
-               { "Max name length", "smb.fs.max_name_len", FT_UINT32, BASE_DEC,
+               { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
                NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
 
        { &hf_smb_fs_name_len,
-               { "Label Length", "smb.fs.name.len", FT_UINT32, BASE_DEC,
+               { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
                NULL, 0, "Length of filesystem name in bytes", HFILL }},
 
        { &hf_smb_fs_name,
-               { "FS Name", "smb.fs.name", FT_STRING, BASE_DEC,
+               { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
                NULL, 0, "Name of filesystem", HFILL }},
 
        { &hf_smb_device_char_removable,
@@ -15593,31 +17543,31 @@ proto_register_smb(void)
                TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
 
        { &hf_smb_fs_attr_css,
-               { "Case Sensitive Search", "smb.fs.attr.css", FT_BOOLEAN, 32,
+               { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
 
        { &hf_smb_fs_attr_cpn,
-               { "Case Preserving", "smb.fs.attr.cpn", FT_BOOLEAN, 32,
+               { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
 
        { &hf_smb_fs_attr_pacls,
-               { "Persistent ACLs", "smb.fs.attr.pacls", FT_BOOLEAN, 32,
+               { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
 
        { &hf_smb_fs_attr_fc,
-               { "Compression", "smb.fs.attr.fc", FT_BOOLEAN, 32,
+               { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
 
        { &hf_smb_fs_attr_vq,
-               { "Volume Quotas", "smb.fs.attr.vq", FT_BOOLEAN, 32,
+               { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
 
        { &hf_smb_fs_attr_dim,
-               { "Mounted", "smb.fs.attr.dim", FT_BOOLEAN, 32,
+               { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
 
        { &hf_smb_fs_attr_vic,
-               { "Compressed", "smb.fs.attr.vic", FT_BOOLEAN, 32,
+               { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
 
        { &hf_smb_sec_desc_revision,
@@ -15644,6 +17594,10 @@ proto_register_smb(void)
                { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
                NULL, 0, "Number of ACE structures for this ACL", HFILL }},
 
+       { &hf_smb_user_quota_offset,
+               { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
+               NULL, 0, "Relative offset to next user quota structure", HFILL }},
+
        { &hf_smb_ace_type,
                { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
                VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
@@ -15681,7 +17635,7 @@ proto_register_smb(void)
                TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
 
        { &hf_smb_sec_desc_type_owner_defaulted,
-               { "Onwer Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
+               { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
                TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
 
        { &hf_smb_sec_desc_type_group_defaulted,
@@ -15732,6 +17686,49 @@ proto_register_smb(void)
                { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
                TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
 
+       { &hf_smb_quota_flags_deny_disk,
+               { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
+
+       { &hf_smb_quota_flags_log_limit,
+               { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
+
+       { &hf_smb_quota_flags_log_warning,
+               { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
+
+       { &hf_smb_quota_flags_enabled,
+               { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
+
+       { &hf_smb_segment_overlap,
+               { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Fragment overlaps with other fragments", HFILL }},
+
+       { &hf_smb_segment_overlap_conflict,
+               { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Overlapping fragments contained conflicting data", HFILL }},
+
+       { &hf_smb_segment_multiple_tails,
+               { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Several tails were found when defragmenting the packet", HFILL }},
+
+       { &hf_smb_segment_too_long_fragment,
+               { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+                       "Fragment contained data past end of packet", HFILL }},
+
+       { &hf_smb_segment_error,
+               { "Defragmentation error", "smb.segment.error", FT_NONE, BASE_NONE, NULL, 0x0,
+                       "Defragmentation error due to illegal fragments", HFILL }},
+
+       { &hf_smb_segment,
+               { "SMB Segment", "smb.segment", FT_NONE, BASE_NONE, NULL, 0x0,
+                       "SMB Segment", HFILL }},
+
+       { &hf_smb_segments,
+               { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
+                       "SMB Segments", HFILL }},
        };
        static gint *ett[] = {
                &ett_smb,
@@ -15757,8 +17754,7 @@ proto_register_smb(void)
                &ett_smb_ssetupandxaction,
                &ett_smb_optionsup,
                &ett_smb_time_date,
-               &ett_smb_64bit_time,
-               &ett_smb_move_flags,
+               &ett_smb_move_copy_flags,
                &ett_smb_file_attributes,
                &ett_smb_search_resume_key,
                &ett_smb_search_dir_info,
@@ -15778,6 +17774,8 @@ proto_register_smb(void)
                &ett_smb_nt_share_access,
                &ett_smb_nt_security_flags,
                &ett_smb_nt_trans_setup,
+               &ett_smb_nt_trans_data,
+               &ett_smb_nt_trans_param,
                &ett_smb_nt_notify_completion_filter,
                &ett_smb_nt_ioctl_flags,
                &ett_smb_security_information_mask,
@@ -15785,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,
@@ -15795,12 +17796,16 @@ proto_register_smb(void)
                &ett_smb_device_characteristics,
                &ett_smb_fs_attributes,
                &ett_smb_segments,
+               &ett_smb_segment,
                &ett_smb_sec_desc,
                &ett_smb_sid,
                &ett_smb_acl,
                &ett_smb_ace,
                &ett_smb_ace_flags,
                &ett_smb_sec_desc_type,
+               &ett_smb_quotaflags,
+               &ett_smb_gssapi,
+               &ett_smb_mac_support_flags,
        };
        module_t *smb_module;
 
@@ -15812,11 +17817,11 @@ proto_register_smb(void)
        smb_module = prefs_register_protocol(proto_smb, NULL);
        prefs_register_bool_preference(smb_module, "trans_reassembly",
                "Reassemble SMB Transaction payload",
-               "Whether the dissector should do reassembly the payload of SMB Transaction commands spanning multiple SMB PDUs",
+               "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
                &smb_trans_reassembly);
        prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
                "Reassemble DCERPC over SMB",
-               "Whether the dissector should do reassembly of DCERPC over SMB commands",
+               "Whether the dissector should reassemble DCERPC over SMB commands",
                &smb_dcerpc_reassembly);
        register_init_routine(smb_trans_reassembly_init);
        register_init_routine(smb_dcerpc_reassembly_init);
@@ -15826,4 +17831,5 @@ void
 proto_reg_handoff_smb(void)
 {
        heur_dissector_add("netbios", dissect_smb, proto_smb);
+       gssapi_handle = find_dissector("gssapi");
 }