Ethereal-dev: [Ethereal-dev] packet-smb.c patch 4

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "Pia Sahlberg" <piabar@xxxxxxxxxxx>
Date: Sat, 11 Aug 2001 04:27:11 +0000
hi list

attached is patch 4 for smb, as previously it requires all previous patches.
this patch adds a few more commands as tvbuffified. now 16 commands aretvbuffified.

best regards
 ronnie sahlberg


_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp
diff -u -r -x *.[^ch]|nmake|am ethereal-orig/packet-smb.c ethereal/packet-smb.c
--- ethereal-orig/packet-smb.c	Sat Aug 11 11:58:33 2001
+++ ethereal/packet-smb.c	Sat Aug 11 13:56:21 2001
@@ -105,6 +105,8 @@
static int hf_system_time_high = -1;
static int hf_server_guid = -1;
static int hf_security_blob = -1;
+static int hf_dir_name = -1;
+static int hf_old_file_name = -1;
static int hf_file_name = -1;
static int hf_file_attribute_read_only = -1;
static int hf_file_attribute_hidden = -1;
@@ -116,6 +118,16 @@
static int hf_last_write_dos_date = -1;
static int hf_last_write_dos_time = -1;
static int hf_file_size = -1;
+static int hf_create_date = -1;
+static int hf_create_dos_date = -1;
+static int hf_create_dos_time = -1;
+static int hf_fid = -1;
+static int hf_rw_count = -1;
+static int hf_file_offset = -1;
+static int hf_file_remaining = -1;
+static int hf_file_data = -1;
+static int hf_data_len = -1;
+static int hf_lock_count = -1;

/*xxxxx*/

@@ -870,1230 +882,1177 @@
	return offset;
}

-typedef struct _smb_function {
-	int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-	int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-} smb_function;
-
-smb_function smb_dissector[256] = {
-/* 0x00 */  {NULL, NULL},
-/* 0x01 */  {NULL, NULL},
-/* 0x02 */  {NULL, NULL},
-/* 0x03 */  {NULL, NULL},
-/* 0x04 */  {NULL, NULL},
-/* 0x05 */  {NULL, NULL},
-/* 0x06 */  {NULL, NULL},
-/* 0x07 */  {NULL, NULL},
-/* 0x08 */ {dissect_smb_query_information_request, dissect_smb_query_information_response},
-/* 0x09 */  {NULL, NULL},
-/* 0x0a */  {NULL, NULL},
-/* 0x0b */  {NULL, NULL},
-/* 0x0c */  {NULL, NULL},
-/* 0x0d */  {NULL, NULL},
-/* 0x0e */  {NULL, NULL},
-/* 0x0f */  {NULL, NULL},
-/* 0x10 */  {NULL, NULL},
-/* 0x11 */  {NULL, NULL},
-/* 0x12 */  {NULL, NULL},
-/* 0x13 */  {NULL, NULL},
-/* 0x14 */  {NULL, NULL},
-/* 0x15 */  {NULL, NULL},
-/* 0x16 */  {NULL, NULL},
-/* 0x17 */  {NULL, NULL},
-/* 0x18 */  {NULL, NULL},
-/* 0x19 */  {NULL, NULL},
-/* 0x1a */  {NULL, NULL},
-/* 0x1b */  {NULL, NULL},
-/* 0x1c */  {NULL, NULL},
-/* 0x1d */  {NULL, NULL},
-/* 0x1e */  {NULL, NULL},
-/* 0x1f */  {NULL, NULL},
-/* 0x20 */  {NULL, NULL},
-/* 0x21 */  {NULL, NULL},
-/* 0x22 */  {NULL, NULL},
-/* 0x23 */  {NULL, NULL},
-/* 0x24 */  {NULL, NULL},
-/* 0x25 */  {NULL, NULL},
-/* 0x26 */  {NULL, NULL},
-/* 0x27 */  {NULL, NULL},
-/* 0x28 */  {NULL, NULL},
-/* 0x29 */  {NULL, NULL},
-/* 0x2a */  {NULL, NULL},
-/* 0x2b */  {NULL, NULL},
-/* 0x2c */  {NULL, NULL},
-/* 0x2d */  {NULL, NULL},
-/* 0x2e */  {NULL, NULL},
-/* 0x2f */  {NULL, NULL},
-/* 0x30 */  {NULL, NULL},
-/* 0x31 */  {NULL, NULL},
-/* 0x32 */  {NULL, NULL},
-/* 0x33 */  {NULL, NULL},
-/* 0x34 */  {NULL, NULL},
-/* 0x35 */  {NULL, NULL},
-/* 0x36 */  {NULL, NULL},
-/* 0x37 */  {NULL, NULL},
-/* 0x38 */  {NULL, NULL},
-/* 0x39 */  {NULL, NULL},
-/* 0x3a */  {NULL, NULL},
-/* 0x3b */  {NULL, NULL},
-/* 0x3c */  {NULL, NULL},
-/* 0x3d */  {NULL, NULL},
-/* 0x3e */  {NULL, NULL},
-/* 0x3f */  {NULL, NULL},
-/* 0x40 */  {NULL, NULL},
-/* 0x41 */  {NULL, NULL},
-/* 0x42 */  {NULL, NULL},
-/* 0x43 */  {NULL, NULL},
-/* 0x44 */  {NULL, NULL},
-/* 0x45 */  {NULL, NULL},
-/* 0x46 */  {NULL, NULL},
-/* 0x47 */  {NULL, NULL},
-/* 0x48 */  {NULL, NULL},
-/* 0x49 */  {NULL, NULL},
-/* 0x4a */  {NULL, NULL},
-/* 0x4b */  {NULL, NULL},
-/* 0x4c */  {NULL, NULL},
-/* 0x4d */  {NULL, NULL},
-/* 0x4e */  {NULL, NULL},
-/* 0x4f */  {NULL, NULL},
-/* 0x50 */  {NULL, NULL},
-/* 0x51 */  {NULL, NULL},
-/* 0x52 */  {NULL, NULL},
-/* 0x53 */  {NULL, NULL},
-/* 0x54 */  {NULL, NULL},
-/* 0x55 */  {NULL, NULL},
-/* 0x56 */  {NULL, NULL},
-/* 0x57 */  {NULL, NULL},
-/* 0x58 */  {NULL, NULL},
-/* 0x59 */  {NULL, NULL},
-/* 0x5a */  {NULL, NULL},
-/* 0x5b */  {NULL, NULL},
-/* 0x5c */  {NULL, NULL},
-/* 0x5d */  {NULL, NULL},
-/* 0x5e */  {NULL, NULL},
-/* 0x5f */  {NULL, NULL},
-/* 0x60 */  {NULL, NULL},
-/* 0x61 */  {NULL, NULL},
-/* 0x62 */  {NULL, NULL},
-/* 0x63 */  {NULL, NULL},
-/* 0x64 */  {NULL, NULL},
-/* 0x65 */  {NULL, NULL},
-/* 0x66 */  {NULL, NULL},
-/* 0x67 */  {NULL, NULL},
-/* 0x68 */  {NULL, NULL},
-/* 0x69 */  {NULL, NULL},
-/* 0x6a */  {NULL, NULL},
-/* 0x6b */  {NULL, NULL},
-/* 0x6c */  {NULL, NULL},
-/* 0x6d */  {NULL, NULL},
-/* 0x6e */  {NULL, NULL},
-/* 0x6f */  {NULL, NULL},
-/* 0x70 */  {NULL, NULL},
-/* 0x71 */  {NULL, NULL},
-/* 0x72 */  {dissect_smb_negprot_request, dissect_smb_negprot_response},
-/* 0x73 */  {NULL, NULL},
-/* 0x74 */  {NULL, NULL},
-/* 0x75 */  {NULL, NULL},
-/* 0x76 */  {NULL, NULL},
-/* 0x77 */  {NULL, NULL},
-/* 0x78 */  {NULL, NULL},
-/* 0x79 */  {NULL, NULL},
-/* 0x7a */  {NULL, NULL},
-/* 0x7b */  {NULL, NULL},
-/* 0x7c */  {NULL, NULL},
-/* 0x7d */  {NULL, NULL},
-/* 0x7e */  {NULL, NULL},
-/* 0x7f */  {NULL, NULL},
-/* 0x80 */  {NULL, NULL},
-/* 0x81 */  {NULL, NULL},
-/* 0x82 */  {NULL, NULL},
-/* 0x83 */  {NULL, NULL},
-/* 0x84 */  {NULL, NULL},
-/* 0x85 */  {NULL, NULL},
-/* 0x86 */  {NULL, NULL},
-/* 0x87 */  {NULL, NULL},
-/* 0x88 */  {NULL, NULL},
-/* 0x89 */  {NULL, NULL},
-/* 0x8a */  {NULL, NULL},
-/* 0x8b */  {NULL, NULL},
-/* 0x8c */  {NULL, NULL},
-/* 0x8d */  {NULL, NULL},
-/* 0x8e */  {NULL, NULL},
-/* 0x8f */  {NULL, NULL},
-/* 0x90 */  {NULL, NULL},
-/* 0x91 */  {NULL, NULL},
-/* 0x92 */  {NULL, NULL},
-/* 0x93 */  {NULL, NULL},
-/* 0x94 */  {NULL, NULL},
-/* 0x95 */  {NULL, NULL},
-/* 0x96 */  {NULL, NULL},
-/* 0x97 */  {NULL, NULL},
-/* 0x98 */  {NULL, NULL},
-/* 0x99 */  {NULL, NULL},
-/* 0x9a */  {NULL, NULL},
-/* 0x9b */  {NULL, NULL},
-/* 0x9c */  {NULL, NULL},
-/* 0x9d */  {NULL, NULL},
-/* 0x9e */  {NULL, NULL},
-/* 0x9f */  {NULL, NULL},
-/* 0xa0 */  {NULL, NULL},
-/* 0xa1 */  {NULL, NULL},
-/* 0xa2 */  {NULL, NULL},
-/* 0xa3 */  {NULL, NULL},
-/* 0xa4 */  {NULL, NULL},
-/* 0xa5 */  {NULL, NULL},
-/* 0xa6 */  {NULL, NULL},
-/* 0xa7 */  {NULL, NULL},
-/* 0xa8 */  {NULL, NULL},
-/* 0xa9 */  {NULL, NULL},
-/* 0xaa */  {NULL, NULL},
-/* 0xab */  {NULL, NULL},
-/* 0xac */  {NULL, NULL},
-/* 0xad */  {NULL, NULL},
-/* 0xae */  {NULL, NULL},
-/* 0xaf */  {NULL, NULL},
-/* 0xb0 */  {NULL, NULL},
-/* 0xb1 */  {NULL, NULL},
-/* 0xb2 */  {NULL, NULL},
-/* 0xb3 */  {NULL, NULL},
-/* 0xb4 */  {NULL, NULL},
-/* 0xb5 */  {NULL, NULL},
-/* 0xb6 */  {NULL, NULL},
-/* 0xb7 */  {NULL, NULL},
-/* 0xb8 */  {NULL, NULL},
-/* 0xb9 */  {NULL, NULL},
-/* 0xba */  {NULL, NULL},
-/* 0xbb */  {NULL, NULL},
-/* 0xbc */  {NULL, NULL},
-/* 0xbd */  {NULL, NULL},
-/* 0xbe */  {NULL, NULL},
-/* 0xbf */  {NULL, NULL},
-/* 0xc0 */  {NULL, NULL},
-/* 0xc1 */  {NULL, NULL},
-/* 0xc2 */  {NULL, NULL},
-/* 0xc3 */  {NULL, NULL},
-/* 0xc4 */  {NULL, NULL},
-/* 0xc5 */  {NULL, NULL},
-/* 0xc6 */  {NULL, NULL},
-/* 0xc7 */  {NULL, NULL},
-/* 0xc8 */  {NULL, NULL},
-/* 0xc9 */  {NULL, NULL},
-/* 0xca */  {NULL, NULL},
-/* 0xcb */  {NULL, NULL},
-/* 0xcc */  {NULL, NULL},
-/* 0xcd */  {NULL, NULL},
-/* 0xce */  {NULL, NULL},
-/* 0xcf */  {NULL, NULL},
-/* 0xd0 */  {NULL, NULL},
-/* 0xd1 */  {NULL, NULL},
-/* 0xd2 */  {NULL, NULL},
-/* 0xd3 */  {NULL, NULL},
-/* 0xd4 */  {NULL, NULL},
-/* 0xd5 */  {NULL, NULL},
-/* 0xd6 */  {NULL, NULL},
-/* 0xd7 */  {NULL, NULL},
-/* 0xd8 */  {NULL, NULL},
-/* 0xd9 */  {NULL, NULL},
-/* 0xda */  {NULL, NULL},
-/* 0xdb */  {NULL, NULL},
-/* 0xdc */  {NULL, NULL},
-/* 0xdd */  {NULL, NULL},
-/* 0xde */  {NULL, NULL},
-/* 0xdf */  {NULL, NULL},
-/* 0xe0 */  {NULL, NULL},
-/* 0xe1 */  {NULL, NULL},
-/* 0xe2 */  {NULL, NULL},
-/* 0xe3 */  {NULL, NULL},
-/* 0xe4 */  {NULL, NULL},
-/* 0xe5 */  {NULL, NULL},
-/* 0xe6 */  {NULL, NULL},
-/* 0xe7 */  {NULL, NULL},
-/* 0xe8 */  {NULL, NULL},
-/* 0xe9 */  {NULL, NULL},
-/* 0xea */  {NULL, NULL},
-/* 0xeb */  {NULL, NULL},
-/* 0xec */  {NULL, NULL},
-/* 0xed */  {NULL, NULL},
-/* 0xee */  {NULL, NULL},
-/* 0xef */  {NULL, NULL},
-/* 0xf0 */  {NULL, NULL},
-/* 0xf1 */  {NULL, NULL},
-/* 0xf2 */  {NULL, NULL},
-/* 0xf3 */  {NULL, NULL},
-/* 0xf4 */  {NULL, NULL},
-/* 0xf5 */  {NULL, NULL},
-/* 0xf6 */  {NULL, NULL},
-/* 0xf7 */  {NULL, NULL},
-/* 0xf8 */  {NULL, NULL},
-/* 0xf9 */  {NULL, NULL},
-/* 0xfa */  {NULL, NULL},
-/* 0xfb */  {NULL, NULL},
-/* 0xfc */  {NULL, NULL},
-/* 0xfd */  {NULL, NULL},
-/* 0xfe */  {NULL, NULL},
-/* 0xff */  {NULL, NULL}
-};
-
-
-
-/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- * Everything tvbuffified above this line
- * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- */
+static int
+dissect_smb_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	int offset = 0;

+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

+	/* file attributes */
+	offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+	/* last write time */
+ offset = dissect_smbu_time_date(tvb, pinfo, tree, offset, "Last Write Time", hf_last_write_date, hf_last_write_dos_date, hf_last_write_dos_time);

-/*
- * Struct passed to each SMB decode routine of info it may need
- */
+	/* 10 reserved bytes */
+ proto_tree_add_bytes(tree, hf_reserved, tvb, offset, 10, tvb_get_ptr(tvb, offset, 10));
+	offset += 10;

-char *decode_smb_name(unsigned char);
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-int smb_packet_init_count = 200;
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-struct smb_request_key {
-  guint32 conversation;
-  guint16 mid;
-  guint16 pid;
-};
+	/* file name */
+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_file_name);

-static GHashTable *smb_request_hash = NULL;
-static GMemChunk *smb_request_keys = NULL;
-static GMemChunk *smb_request_vals = NULL;
+	return offset;
+}

-/* Hash Functions */
-static gint
-smb_equal(gconstpointer v, gconstpointer w)
+static int
+dissect_smb_create_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-  struct smb_request_key *v1 = (struct smb_request_key *)v;
-  struct smb_request_key *v2 = (struct smb_request_key *)w;
+	int offset = 0;

-#if defined(DEBUG_SMB_HASH)
-  printf("Comparing %08X:%u:%u\n      and %08X:%u:%u\n",
-	 v1 -> conversation, v1 -> mid, v1 -> pid,
-	 v2 -> conversation, v2 -> mid, v2 -> pid);
-#endif
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-  if (v1 -> conversation == v2 -> conversation &&
-      v1 -> mid          == v2 -> mid &&
-      v1 -> pid          == v2 -> pid) {
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-    return 1;
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-  }
+	/* dir name */
+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_dir_name);

-  return 0;
+	return offset;
}

-static guint
-smb_hash (gconstpointer v)
+static int
+dissect_smb_create_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-  struct smb_request_key *key = (struct smb_request_key *)v;
-  guint val;
-
-  val = (key -> conversation) + (key -> mid) + (key -> pid);
-
-#if defined(DEBUG_SMB_HASH)
-  printf("SMB Hash calculated as %u\n", val);
-#endif
-
-  return val;
-
-}
+	int offset = 0;

-/*
- * Free up any state information we've saved, and re-initialize the
- * tables of state information.
- */
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-/*
- * For a hash table entry, free the address data to which the key refers
- * and the fragment data to which the value refers.
- * (The actual key and value structures get freed by "reassemble_init()".)
- */
-static gboolean
-free_request_val_data(gpointer key, gpointer value, gpointer user_data)
-{
-  struct smb_request_val *request_val = value;
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-  if (request_val->last_transact_command != NULL)
-    g_free(request_val->last_transact_command);
-  if (request_val->last_param_descrip != NULL)
-    g_free(request_val->last_param_descrip);
-  if (request_val->last_data_descrip != NULL)
-    g_free(request_val->last_data_descrip);
-  return TRUE;
+	return offset;
}

-static void
-smb_init_protocol(void)
+static int
+dissect_smb_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-#if defined(DEBUG_SMB_HASH)
-  printf("Initializing SMB hashtable area\n");
-#endif
-
-  if (smb_request_hash) {
-    /*
-     * Remove all entries from the hash table and free all strings
-     * attached to the keys and values.  (The keys and values
-     * themselves are freed with "g_mem_chunk_destroy()" calls
-     * below.)
-     */
- g_hash_table_foreach_remove(smb_request_hash, free_request_val_data, NULL);
-    g_hash_table_destroy(smb_request_hash);
-  }
-  if (smb_request_keys)
-    g_mem_chunk_destroy(smb_request_keys);
-  if (smb_request_vals)
-    g_mem_chunk_destroy(smb_request_vals);
+	int offset = 0;

-  smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
-  smb_request_keys = g_mem_chunk_new("smb_request_keys",
-				     sizeof(struct smb_request_key),
- smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
-  smb_request_vals = g_mem_chunk_new("smb_request_vals",
-				     sizeof(struct smb_request_val),
- smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
-}
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int, int);
+	/* file attributes */
+	offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+	/* creation time */
+ offset = dissect_smbu_time_date(tvb, pinfo, tree, offset, "Creation Time", hf_create_date, hf_create_dos_date, hf_create_dos_time);

+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-/* NOTEr: this value_string is accessed directly by index and not val_to_str().
- * That means that ALL entries 0x00-0xFF MUST exists and be in order.
- */
-static const value_string smb_cmd_vals[] = {
-  { 0x00, "SMBcreatedirectory" },
-  { 0x01, "SMBdeletedirectory" },
-  { 0x02, "SMBopen" },
-  { 0x03, "SMBcreate" },
-  { 0x04, "SMBclose" },
-  { 0x05, "SMBflush" },
-  { 0x06, "SMBunlink" },
-  { 0x07, "SMBmv" },
-  { 0x08, "SMBgetatr" },
-  { 0x09, "SMBsetatr" },
-  { 0x0A, "SMBread" },
-  { 0x0B, "SMBwrite" },
-  { 0x0C, "SMBlock" },
-  { 0x0D, "SMBunlock" },
-  { 0x0E, "SMBctemp" },
-  { 0x0F, "SMBmknew" },
-  { 0x10, "SMBchkpth" },
-  { 0x11, "SMBexit" },
-  { 0x12, "SMBlseek" },
-  { 0x13, "SMBlockread" },
-  { 0x14, "SMBwriteunlock" },
-  { 0x15, "unknown-0x15" },
-  { 0x16, "unknown-0x16" },
-  { 0x17, "unknown-0x17" },
-  { 0x18, "unknown-0x18" },
-  { 0x19, "unknown-0x19" },
-  { 0x1A, "SMBreadBraw" },
-  { 0x1B, "SMBreadBmpx" },
-  { 0x1C, "SMBreadBs" },
-  { 0x1D, "SMBwriteBraw" },
-  { 0x1E, "SMBwriteBmpx" },
-  { 0x1F, "SMBwriteBs" },
-  { 0x20, "SMBwriteC" },
-  { 0x21, "unknown-0x21" },
-  { 0x22, "SMBsetattrE" },
-  { 0x23, "SMBgetattrE" },
-  { 0x24, "SMBlockingX" },
-  { 0x25, "SMBtrans" },
-  { 0x26, "SMBtranss" },
-  { 0x27, "SMBioctl" },
-  { 0x28, "SMBioctls" },
-  { 0x29, "SMBcopy" },
-  { 0x2A, "SMBmove" },
-  { 0x2B, "SMBecho" },
-  { 0x2C, "SMBwriteclose" },
-  { 0x2D, "SMBopenX" },
-  { 0x2E, "SMBreadX" },
-  { 0x2F, "SMBwriteX" },
-  { 0x30, "unknown-0x30" },
-  { 0x31, "SMBcloseandtreedisc" },
-  { 0x32, "SMBtrans2" },
-  { 0x33, "SMBtrans2secondary" },
-  { 0x34, "SMBfindclose2" },
-  { 0x35, "SMBfindnotifyclose" },
-  { 0x36, "unknown-0x36" },
-  { 0x37, "unknown-0x37" },
-  { 0x38, "unknown-0x38" },
-  { 0x39, "unknown-0x39" },
-  { 0x3A, "unknown-0x3A" },
-  { 0x3B, "unknown-0x3B" },
-  { 0x3C, "unknown-0x3C" },
-  { 0x3D, "unknown-0x3D" },
-  { 0x3E, "unknown-0x3E" },
-  { 0x3F, "unknown-0x3F" },
-  { 0x40, "unknown-0x40" },
-  { 0x41, "unknown-0x41" },
-  { 0x42, "unknown-0x42" },
-  { 0x43, "unknown-0x43" },
-  { 0x44, "unknown-0x44" },
-  { 0x45, "unknown-0x45" },
-  { 0x46, "unknown-0x46" },
-  { 0x47, "unknown-0x47" },
-  { 0x48, "unknown-0x48" },
-  { 0x49, "unknown-0x49" },
-  { 0x4A, "unknown-0x4A" },
-  { 0x4B, "unknown-0x4B" },
-  { 0x4C, "unknown-0x4C" },
-  { 0x4D, "unknown-0x4D" },
-  { 0x4E, "unknown-0x4E" },
-  { 0x4F, "unknown-0x4F" },
-  { 0x50, "unknown-0x50" },
-  { 0x51, "unknown-0x51" },
-  { 0x52, "unknown-0x52" },
-  { 0x53, "unknown-0x53" },
-  { 0x54, "unknown-0x54" },
-  { 0x55, "unknown-0x55" },
-  { 0x56, "unknown-0x56" },
-  { 0x57, "unknown-0x57" },
-  { 0x58, "unknown-0x58" },
-  { 0x59, "unknown-0x59" },
-  { 0x5A, "unknown-0x5A" },
-  { 0x5B, "unknown-0x5B" },
-  { 0x5C, "unknown-0x5C" },
-  { 0x5D, "unknown-0x5D" },
-  { 0x5E, "unknown-0x5E" },
-  { 0x5F, "unknown-0x5F" },
-  { 0x60, "unknown-0x60" },
-  { 0x61, "unknown-0x61" },
-  { 0x62, "unknown-0x62" },
-  { 0x63, "unknown-0x63" },
-  { 0x64, "unknown-0x64" },
-  { 0x65, "unknown-0x65" },
-  { 0x66, "unknown-0x66" },
-  { 0x67, "unknown-0x67" },
-  { 0x68, "unknown-0x68" },
-  { 0x69, "unknown-0x69" },
-  { 0x6A, "unknown-0x6A" },
-  { 0x6B, "unknown-0x6B" },
-  { 0x6C, "unknown-0x6C" },
-  { 0x6D, "unknown-0x6D" },
-  { 0x6E, "unknown-0x6E" },
-  { 0x6F, "unknown-0x6F" },
-  { 0x70, "SMBtcon" },
-  { 0x71, "SMBtdis" },
-  { 0x72, "SMBnegprot" },
-  { 0x73, "SMBsesssetupX" },
-  { 0x74, "SMBlogoffX" },
-  { 0x75, "SMBtconX" },
-  { 0x76, "unknown-0x76" },
-  { 0x77, "unknown-0x77" },
-  { 0x78, "unknown-0x78" },
-  { 0x79, "unknown-0x79" },
-  { 0x7A, "unknown-0x7A" },
-  { 0x7B, "unknown-0x7B" },
-  { 0x7C, "unknown-0x7C" },
-  { 0x7D, "unknown-0x7D" },
-  { 0x7E, "unknown-0x7E" },
-  { 0x7F, "unknown-0x7F" },
-  { 0x80, "SMBdskattr" },
-  { 0x81, "SMBsearch" },
-  { 0x82, "SMBffirst" },
-  { 0x83, "SMBfunique" },
-  { 0x84, "SMBfclose" },
-  { 0x85, "unknown-0x85" },
-  { 0x86, "unknown-0x86" },
-  { 0x87, "unknown-0x87" },
-  { 0x88, "unknown-0x88" },
-  { 0x89, "unknown-0x89" },
-  { 0x8A, "unknown-0x8A" },
-  { 0x8B, "unknown-0x8B" },
-  { 0x8C, "unknown-0x8C" },
-  { 0x8D, "unknown-0x8D" },
-  { 0x8E, "unknown-0x8E" },
-  { 0x8F, "unknown-0x8F" },
-  { 0x90, "unknown-0x90" },
-  { 0x91, "unknown-0x91" },
-  { 0x92, "unknown-0x92" },
-  { 0x93, "unknown-0x93" },
-  { 0x94, "unknown-0x94" },
-  { 0x95, "unknown-0x95" },
-  { 0x96, "unknown-0x96" },
-  { 0x97, "unknown-0x97" },
-  { 0x98, "unknown-0x98" },
-  { 0x99, "unknown-0x99" },
-  { 0x9A, "unknown-0x9A" },
-  { 0x9B, "unknown-0x9B" },
-  { 0x9C, "unknown-0x9C" },
-  { 0x9D, "unknown-0x9D" },
-  { 0x9E, "unknown-0x9E" },
-  { 0x9F, "unknown-0x9F" },
-  { 0xA0, "SMBnttransact" },
-  { 0xA1, "SMBnttransactsecondary" },
-  { 0xA2, "SMBntcreateX" },
-  { 0xA3, "unknown-0xA3" },
-  { 0xA4, "SMBntcancel" },
-  { 0xA5, "unknown-0xA5" },
-  { 0xA6, "unknown-0xA6" },
-  { 0xA7, "unknown-0xA7" },
-  { 0xA8, "unknown-0xA8" },
-  { 0xA9, "unknown-0xA9" },
-  { 0xAA, "unknown-0xAA" },
-  { 0xAB, "unknown-0xAB" },
-  { 0xAC, "unknown-0xAC" },
-  { 0xAD, "unknown-0xAD" },
-  { 0xAE, "unknown-0xAE" },
-  { 0xAF, "unknown-0xAF" },
-  { 0xB0, "unknown-0xB0" },
-  { 0xB1, "unknown-0xB1" },
-  { 0xB2, "unknown-0xB2" },
-  { 0xB3, "unknown-0xB3" },
-  { 0xB4, "unknown-0xB4" },
-  { 0xB5, "unknown-0xB5" },
-  { 0xB6, "unknown-0xB6" },
-  { 0xB7, "unknown-0xB7" },
-  { 0xB8, "unknown-0xB8" },
-  { 0xB9, "unknown-0xB9" },
-  { 0xBA, "unknown-0xBA" },
-  { 0xBB, "unknown-0xBB" },
-  { 0xBC, "unknown-0xBC" },
-  { 0xBD, "unknown-0xBD" },
-  { 0xBE, "unknown-0xBE" },
-  { 0xBF, "unknown-0xBF" },
-  { 0xC0, "SMBsplopen" },
-  { 0xC1, "SMBsplwr" },
-  { 0xC2, "SMBsplclose" },
-  { 0xC3, "SMBsplretq" },
-  { 0xC4, "unknown-0xC4" },
-  { 0xC5, "unknown-0xC5" },
-  { 0xC6, "unknown-0xC6" },
-  { 0xC7, "unknown-0xC7" },
-  { 0xC8, "unknown-0xC8" },
-  { 0xC9, "unknown-0xC9" },
-  { 0xCA, "unknown-0xCA" },
-  { 0xCB, "unknown-0xCB" },
-  { 0xCC, "unknown-0xCC" },
-  { 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" },
-  { 0xD8, "SMBreadbulk" },
-  { 0xD9, "SMBwritebulk" },
-  { 0xDA, "SMBwritebulkdata" },
-  { 0xDB, "unknown-0xDB" },
-  { 0xDC, "unknown-0xDC" },
-  { 0xDD, "unknown-0xDD" },
-  { 0xDE, "unknown-0xDE" },
-  { 0xDF, "unknown-0xDF" },
-  { 0xE0, "unknown-0xE0" },
-  { 0xE1, "unknown-0xE1" },
-  { 0xE2, "unknown-0xE2" },
-  { 0xE3, "unknown-0xE3" },
-  { 0xE4, "unknown-0xE4" },
-  { 0xE5, "unknown-0xE5" },
-  { 0xE6, "unknown-0xE6" },
-  { 0xE7, "unknown-0xE7" },
-  { 0xE8, "unknown-0xE8" },
-  { 0xE9, "unknown-0xE9" },
-  { 0xEA, "unknown-0xEA" },
-  { 0xEB, "unknown-0xEB" },
-  { 0xEC, "unknown-0xEC" },
-  { 0xED, "unknown-0xED" },
-  { 0xEE, "unknown-0xEE" },
-  { 0xEF, "unknown-0xEF" },
-  { 0xF0, "unknown-0xF0" },
-  { 0xF1, "unknown-0xF1" },
-  { 0xF2, "unknown-0xF2" },
-  { 0xF3, "unknown-0xF3" },
-  { 0xF4, "unknown-0xF4" },
-  { 0xF5, "unknown-0xF5" },
-  { 0xF6, "unknown-0xF6" },
-  { 0xF7, "unknown-0xF7" },
-  { 0xF8, "unknown-0xF8" },
-  { 0xF9, "unknown-0xF9" },
-  { 0xFA, "unknown-0xFA" },
-  { 0xFB, "unknown-0xFB" },
-  { 0xFC, "unknown-0xFC" },
-  { 0xFD, "unknown-0xFD" },
-  { 0xFE, "SMBinvalid" },
-  { 0xFF, "unknown-0xFF" },
-  { 0x00, NULL },
-};
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-void
-dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
+	/* file name */
+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_file_name);
+
+	return offset;
+}
+
+static int
+dissect_smb_create_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+	int offset = 0;

-  if (tree) {
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)",
-			END_OF_FRAME);
+	/* fid */
+ proto_tree_add_uint(tree, hf_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-  }
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

+	return offset;
}

-/*
- * Dissect a UNIX like date ...
- */
+static int
+dissect_smb_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	int offset = 0;

-struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
-                      conflict with /usr/include/time.h on some NetBSD
-                      systems */
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-static char *
-dissect_smbu_date(guint16 date, guint16 time)
+	/* fid */
+ proto_tree_add_uint(tree, hf_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* last write time */
+ offset = dissect_smbu_time_date(tvb, pinfo, tree, offset, "Last Write Time", hf_last_write_date, hf_last_write_dos_date, hf_last_write_dos_time);
+
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	return offset;
+}

+static int
+dissect_smb_delete_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-  static char         datebuf[4+2+2+2+1+10];
-  time_t              ltime = (date << 16) + time;
+	int offset = 0;

-  _gtime = gmtime(&ltime);
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-  if (_gtime)
-    sprintf(datebuf, "%04d-%02d-%02d",
- 1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
-  else
-    sprintf(datebuf, "Bad date format");
+	/* file attributes */
+	offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-  return datebuf;
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-}
+	/* file name */
+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_file_name);

-/*
- * Relies on time
- */
-static char *
-dissect_smbu_time(guint16 date, guint16 time)
+	return offset;
+}

+static int
+dissect_smb_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-  static char timebuf[2+2+2+2+1+10];
+	int offset = 0;

-  if (_gtime)
-    sprintf(timebuf, "%02d:%02d:%02d",
-	    _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
-  else
-    sprintf(timebuf, "Bad time format");
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-  return timebuf;
+	/* file attributes */
+	offset = dissect_file_attributes(tvb, pinfo, tree, offset);
+
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;
+
+	/* old file name */
+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_old_file_name);
+
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;
+
+	/* file name */
+ offset = dissect_ascii_or_unicode_string(tvb, pinfo, tree, offset, hf_file_name);

+	return offset;
}

-/*
- * Dissect a DOS-format date.
- */
-static char *
-dissect_dos_date(guint16 date)
+static int
+dissect_smb_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-	static char datebuf[4+2+2+1];
+	int offset = 0;

-	sprintf(datebuf, "%04d-%02d-%02d",
-	    ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
-	return datebuf;
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;
+
+	/* fid */
+ proto_tree_add_uint(tree, hf_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* read count */
+ proto_tree_add_uint(tree, hf_rw_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* offset */
+ proto_tree_add_uint(tree, hf_file_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+	offset += 4;
+
+	/* remaining */
+ proto_tree_add_uint(tree, hf_file_remaining, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	return offset;
}

-/*
- * Dissect a DOS-format time.
- */
-static char *
-dissect_dos_time(guint16 time)
+static int
+dissect_smb_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-	static char timebuf[2+2+2+1];
+	int offset = 0;
+	guint16 bc;

-	sprintf(timebuf, "%02d:%02d:%02d",
-	    (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
-	return timebuf;
-}
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-/* Max string length for displaying Unicode strings.  */
-#define	MAX_UNICODE_STR_LEN	256
+	/* read count */
+ proto_tree_add_uint(tree, hf_rw_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-/* 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. */
-static gchar *
-unicode_to_str(const guint8 *us, int *us_lenp) {
-  static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
-  static gchar *cur;
-  gchar        *p;
-  int           len;
-  int           us_len;
-  int           overflow = 0;
+	/* 8 reserved bytes */
+ proto_tree_add_bytes(tree, hf_reserved, tvb, offset, 8, tvb_get_ptr(tvb, offset, 8));
+	offset += 8;

-  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;
-  while (*us != 0 || *(us + 1) != 0) {
-    if (len > 0) {
-      *p++ = *us;
-      len--;
-    } else
-      overflow = 1;
-    us += 2;
-    us_len += 2;
-  }
-  if (overflow) {
-    /* Note that we're not showing the full string.  */
-    *p++ = '.';
-    *p++ = '.';
-    *p++ = '.';
-  }
-  *p = '\0';
-  *us_lenp = us_len;
-  return cur;
-}
+	/* byte count */
+	bc = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, bc);
+	offset += 2;

-/*
- * Each dissect routine is passed an offset to wct and works from there
- */
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-void
-dissect_flush_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
+	/* file data */
+ proto_tree_add_bytes(tree, hf_file_data, tvb, offset, bc, tvb_get_ptr(tvb, offset, bc));
+	offset += bc;
+
+	return offset;
+}

+static int
+dissect_smb_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
-  guint8        WordCount;
-  guint16       FID;
-  guint16       ByteCount;
+	int offset = 0;
+	guint16 cnt;

-  if (si.request) {
-    /* Request(s) dissect code */
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-    /* Build display for: Word Count (WCT) */
+	/* fid */
+ proto_tree_add_uint(tree, hf_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-    WordCount = GBYTE(pd, offset);
+	/* read count */
+	cnt = tvb_get_letohs(tvb, offset);
+	proto_tree_add_uint(tree, hf_rw_count, tvb, offset, 2, cnt);
+	offset += 2;
+
+	/* offset */
+ proto_tree_add_uint(tree, hf_file_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+	offset += 4;
+
+	/* remaining */
+ proto_tree_add_uint(tree, hf_file_remaining, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* buffer format */
+ proto_tree_add_uint(tree, hf_buffer_format, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;
+
+	/* data len */
+ proto_tree_add_uint(tree, hf_data_len, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;
+
+	/* file data */
+	if(cnt>tvb_length_remaining(tvb, offset)){
+		int len;
+		len = tvb_length_remaining(tvb, offset);
+ proto_tree_add_bytes_format(tree, hf_file_data, tvb, offset, len, tvb_get_ptr(tvb, offset, len),"Incomplete data. Only %d of %d bytes", len, cnt);
+		offset += len;
+	} else {
+ proto_tree_add_bytes(tree, hf_file_data, tvb, offset, cnt, tvb_get_ptr(tvb, offset, cnt));
+		offset += cnt;
+	}
+
+	return offset;
+}
+
+static int
+dissect_smb_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	int offset = 0;
+
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-    if (tree) {
+	/* read count */
+ proto_tree_add_uint(tree, hf_rw_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-    }
+	return offset;
+}

-    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: FID */
+static int
+dissect_smb_lock_byte_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+	int offset = 0;

-    FID = GSHORT(pd, offset);
+	/* word count */
+ proto_tree_add_uint(tree, hf_word_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
+	offset += 1;

-    if (tree) {
+	/* fid */
+ proto_tree_add_uint(tree, hf_fid, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+	/* lock count */
+ proto_tree_add_uint(tree, hf_lock_count, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+	offset += 4;

-    }
+	/* offset */
+ proto_tree_add_uint(tree, hf_file_offset, tvb, offset, 4, tvb_get_letohl(tvb, offset));
+	offset += 4;

-    offset += 2; /* Skip FID */
+	/* byte count */
+ proto_tree_add_uint(tree, hf_byte_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
+	offset += 2;

-    /* Build display for: Byte Count */
+	return offset;
+}

-    ByteCount = GSHORT(pd, offset);

-    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
+/*xxxxx*/
+typedef struct _smb_function {
+	int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+	int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+} smb_function;

-    }
+smb_function smb_dissector[256] = {
+/* 0x00 create dir*/ {dissect_smb_create_dir_request, dissect_smb_create_dir_response}, +/* 0x01 delete dir*/ {dissect_smb_create_dir_request, dissect_smb_create_dir_response},
+/* 0x02 */  {NULL, NULL},
+/* 0x03 create file*/ {dissect_smb_create_file_request, dissect_smb_create_file_response}, +/* 0x04 close file*/ {dissect_smb_close_file_request, dissect_smb_create_dir_response}, +/* 0x05 flush file*/ {dissect_smb_create_file_response, dissect_smb_create_dir_response}, +/* 0x06 delete file*/ {dissect_smb_delete_file_response, dissect_smb_create_dir_response}, +/* 0x07 rename file*/ {dissect_smb_rename_file_request, dissect_smb_create_dir_response}, +/* 0x08 query info*/ {dissect_smb_query_information_request, dissect_smb_query_information_response}, +/* 0x09 set info*/ {dissect_smb_set_information_request, dissect_smb_create_dir_response}, +/* 0x0a read file*/ {dissect_smb_read_file_request, dissect_smb_read_file_response}, +/* 0x0b write file*/ {dissect_smb_write_file_request, dissect_smb_write_file_response}, +/* 0x0c lock byte*/ {dissect_smb_lock_byte_request, dissect_smb_create_dir_response}, +/* 0x0d unlock byte*/ {dissect_smb_lock_byte_request, dissect_smb_create_dir_response},
+/* 0x0e */  {NULL, NULL},
+/* 0x0f */  {NULL, NULL},
+/* 0x10 check dir*/ {dissect_smb_create_dir_request, dissect_smb_create_dir_response},
+/* 0x11 */  {NULL, NULL},
+/* 0x12 */  {NULL, NULL},
+/* 0x13 */  {NULL, NULL},
+/* 0x14 */  {NULL, NULL},
+/* 0x15 */  {NULL, NULL},
+/* 0x16 */  {NULL, NULL},
+/* 0x17 */  {NULL, NULL},
+/* 0x18 */  {NULL, NULL},
+/* 0x19 */  {NULL, NULL},
+/* 0x1a */  {NULL, NULL},
+/* 0x1b */  {NULL, NULL},
+/* 0x1c */  {NULL, NULL},
+/* 0x1d */  {NULL, NULL},
+/* 0x1e */  {NULL, NULL},
+/* 0x1f */  {NULL, NULL},
+/* 0x20 */  {NULL, NULL},
+/* 0x21 */  {NULL, NULL},
+/* 0x22 */  {NULL, NULL},
+/* 0x23 */  {NULL, NULL},
+/* 0x24 */  {NULL, NULL},
+/* 0x25 */  {NULL, NULL},
+/* 0x26 */  {NULL, NULL},
+/* 0x27 */  {NULL, NULL},
+/* 0x28 */  {NULL, NULL},
+/* 0x29 */  {NULL, NULL},
+/* 0x2a */  {NULL, NULL},
+/* 0x2b */  {NULL, NULL},
+/* 0x2c */  {NULL, NULL},
+/* 0x2d */  {NULL, NULL},
+/* 0x2e */  {NULL, NULL},
+/* 0x2f */  {NULL, NULL},
+/* 0x30 */  {NULL, NULL},
+/* 0x31 */  {NULL, NULL},
+/* 0x32 */  {NULL, NULL},
+/* 0x33 */  {NULL, NULL},
+/* 0x34 */  {NULL, NULL},
+/* 0x35 */  {NULL, NULL},
+/* 0x36 */  {NULL, NULL},
+/* 0x37 */  {NULL, NULL},
+/* 0x38 */  {NULL, NULL},
+/* 0x39 */  {NULL, NULL},
+/* 0x3a */  {NULL, NULL},
+/* 0x3b */  {NULL, NULL},
+/* 0x3c */  {NULL, NULL},
+/* 0x3d */  {NULL, NULL},
+/* 0x3e */  {NULL, NULL},
+/* 0x3f */  {NULL, NULL},
+/* 0x40 */  {NULL, NULL},
+/* 0x41 */  {NULL, NULL},
+/* 0x42 */  {NULL, NULL},
+/* 0x43 */  {NULL, NULL},
+/* 0x44 */  {NULL, NULL},
+/* 0x45 */  {NULL, NULL},
+/* 0x46 */  {NULL, NULL},
+/* 0x47 */  {NULL, NULL},
+/* 0x48 */  {NULL, NULL},
+/* 0x49 */  {NULL, NULL},
+/* 0x4a */  {NULL, NULL},
+/* 0x4b */  {NULL, NULL},
+/* 0x4c */  {NULL, NULL},
+/* 0x4d */  {NULL, NULL},
+/* 0x4e */  {NULL, NULL},
+/* 0x4f */  {NULL, NULL},
+/* 0x50 */  {NULL, NULL},
+/* 0x51 */  {NULL, NULL},
+/* 0x52 */  {NULL, NULL},
+/* 0x53 */  {NULL, NULL},
+/* 0x54 */  {NULL, NULL},
+/* 0x55 */  {NULL, NULL},
+/* 0x56 */  {NULL, NULL},
+/* 0x57 */  {NULL, NULL},
+/* 0x58 */  {NULL, NULL},
+/* 0x59 */  {NULL, NULL},
+/* 0x5a */  {NULL, NULL},
+/* 0x5b */  {NULL, NULL},
+/* 0x5c */  {NULL, NULL},
+/* 0x5d */  {NULL, NULL},
+/* 0x5e */  {NULL, NULL},
+/* 0x5f */  {NULL, NULL},
+/* 0x60 */  {NULL, NULL},
+/* 0x61 */  {NULL, NULL},
+/* 0x62 */  {NULL, NULL},
+/* 0x63 */  {NULL, NULL},
+/* 0x64 */  {NULL, NULL},
+/* 0x65 */  {NULL, NULL},
+/* 0x66 */  {NULL, NULL},
+/* 0x67 */  {NULL, NULL},
+/* 0x68 */  {NULL, NULL},
+/* 0x69 */  {NULL, NULL},
+/* 0x6a */  {NULL, NULL},
+/* 0x6b */  {NULL, NULL},
+/* 0x6c */  {NULL, NULL},
+/* 0x6d */  {NULL, NULL},
+/* 0x6e */  {NULL, NULL},
+/* 0x6f */  {NULL, NULL},
+/* 0x70 */  {NULL, NULL},
+/* 0x71 */  {NULL, NULL},
+/* 0x72 negprot*/ {dissect_smb_negprot_request, dissect_smb_negprot_response},
+/* 0x73 */  {NULL, NULL},
+/* 0x74 */  {NULL, NULL},
+/* 0x75 */  {NULL, NULL},
+/* 0x76 */  {NULL, NULL},
+/* 0x77 */  {NULL, NULL},
+/* 0x78 */  {NULL, NULL},
+/* 0x79 */  {NULL, NULL},
+/* 0x7a */  {NULL, NULL},
+/* 0x7b */  {NULL, NULL},
+/* 0x7c */  {NULL, NULL},
+/* 0x7d */  {NULL, NULL},
+/* 0x7e */  {NULL, NULL},
+/* 0x7f */  {NULL, NULL},
+/* 0x80 */  {NULL, NULL},
+/* 0x81 */  {NULL, NULL},
+/* 0x82 */  {NULL, NULL},
+/* 0x83 */  {NULL, NULL},
+/* 0x84 */  {NULL, NULL},
+/* 0x85 */  {NULL, NULL},
+/* 0x86 */  {NULL, NULL},
+/* 0x87 */  {NULL, NULL},
+/* 0x88 */  {NULL, NULL},
+/* 0x89 */  {NULL, NULL},
+/* 0x8a */  {NULL, NULL},
+/* 0x8b */  {NULL, NULL},
+/* 0x8c */  {NULL, NULL},
+/* 0x8d */  {NULL, NULL},
+/* 0x8e */  {NULL, NULL},
+/* 0x8f */  {NULL, NULL},
+/* 0x90 */  {NULL, NULL},
+/* 0x91 */  {NULL, NULL},
+/* 0x92 */  {NULL, NULL},
+/* 0x93 */  {NULL, NULL},
+/* 0x94 */  {NULL, NULL},
+/* 0x95 */  {NULL, NULL},
+/* 0x96 */  {NULL, NULL},
+/* 0x97 */  {NULL, NULL},
+/* 0x98 */  {NULL, NULL},
+/* 0x99 */  {NULL, NULL},
+/* 0x9a */  {NULL, NULL},
+/* 0x9b */  {NULL, NULL},
+/* 0x9c */  {NULL, NULL},
+/* 0x9d */  {NULL, NULL},
+/* 0x9e */  {NULL, NULL},
+/* 0x9f */  {NULL, NULL},
+/* 0xa0 */  {NULL, NULL},
+/* 0xa1 */  {NULL, NULL},
+/* 0xa2 */  {NULL, NULL},
+/* 0xa3 */  {NULL, NULL},
+/* 0xa4 */  {NULL, NULL},
+/* 0xa5 */  {NULL, NULL},
+/* 0xa6 */  {NULL, NULL},
+/* 0xa7 */  {NULL, NULL},
+/* 0xa8 */  {NULL, NULL},
+/* 0xa9 */  {NULL, NULL},
+/* 0xaa */  {NULL, NULL},
+/* 0xab */  {NULL, NULL},
+/* 0xac */  {NULL, NULL},
+/* 0xad */  {NULL, NULL},
+/* 0xae */  {NULL, NULL},
+/* 0xaf */  {NULL, NULL},
+/* 0xb0 */  {NULL, NULL},
+/* 0xb1 */  {NULL, NULL},
+/* 0xb2 */  {NULL, NULL},
+/* 0xb3 */  {NULL, NULL},
+/* 0xb4 */  {NULL, NULL},
+/* 0xb5 */  {NULL, NULL},
+/* 0xb6 */  {NULL, NULL},
+/* 0xb7 */  {NULL, NULL},
+/* 0xb8 */  {NULL, NULL},
+/* 0xb9 */  {NULL, NULL},
+/* 0xba */  {NULL, NULL},
+/* 0xbb */  {NULL, NULL},
+/* 0xbc */  {NULL, NULL},
+/* 0xbd */  {NULL, NULL},
+/* 0xbe */  {NULL, NULL},
+/* 0xbf */  {NULL, NULL},
+/* 0xc0 */  {NULL, NULL},
+/* 0xc1 */  {NULL, NULL},
+/* 0xc2 */  {NULL, NULL},
+/* 0xc3 */  {NULL, NULL},
+/* 0xc4 */  {NULL, NULL},
+/* 0xc5 */  {NULL, NULL},
+/* 0xc6 */  {NULL, NULL},
+/* 0xc7 */  {NULL, NULL},
+/* 0xc8 */  {NULL, NULL},
+/* 0xc9 */  {NULL, NULL},
+/* 0xca */  {NULL, NULL},
+/* 0xcb */  {NULL, NULL},
+/* 0xcc */  {NULL, NULL},
+/* 0xcd */  {NULL, NULL},
+/* 0xce */  {NULL, NULL},
+/* 0xcf */  {NULL, NULL},
+/* 0xd0 */  {NULL, NULL},
+/* 0xd1 */  {NULL, NULL},
+/* 0xd2 */  {NULL, NULL},
+/* 0xd3 */  {NULL, NULL},
+/* 0xd4 */  {NULL, NULL},
+/* 0xd5 */  {NULL, NULL},
+/* 0xd6 */  {NULL, NULL},
+/* 0xd7 */  {NULL, NULL},
+/* 0xd8 */  {NULL, NULL},
+/* 0xd9 */  {NULL, NULL},
+/* 0xda */  {NULL, NULL},
+/* 0xdb */  {NULL, NULL},
+/* 0xdc */  {NULL, NULL},
+/* 0xdd */  {NULL, NULL},
+/* 0xde */  {NULL, NULL},
+/* 0xdf */  {NULL, NULL},
+/* 0xe0 */  {NULL, NULL},
+/* 0xe1 */  {NULL, NULL},
+/* 0xe2 */  {NULL, NULL},
+/* 0xe3 */  {NULL, NULL},
+/* 0xe4 */  {NULL, NULL},
+/* 0xe5 */  {NULL, NULL},
+/* 0xe6 */  {NULL, NULL},
+/* 0xe7 */  {NULL, NULL},
+/* 0xe8 */  {NULL, NULL},
+/* 0xe9 */  {NULL, NULL},
+/* 0xea */  {NULL, NULL},
+/* 0xeb */  {NULL, NULL},
+/* 0xec */  {NULL, NULL},
+/* 0xed */  {NULL, NULL},
+/* 0xee */  {NULL, NULL},
+/* 0xef */  {NULL, NULL},
+/* 0xf0 */  {NULL, NULL},
+/* 0xf1 */  {NULL, NULL},
+/* 0xf2 */  {NULL, NULL},
+/* 0xf3 */  {NULL, NULL},
+/* 0xf4 */  {NULL, NULL},
+/* 0xf5 */  {NULL, NULL},
+/* 0xf6 */  {NULL, NULL},
+/* 0xf7 */  {NULL, NULL},
+/* 0xf8 */  {NULL, NULL},
+/* 0xf9 */  {NULL, NULL},
+/* 0xfa */  {NULL, NULL},
+/* 0xfb */  {NULL, NULL},
+/* 0xfc */  {NULL, NULL},
+/* 0xfd */  {NULL, NULL},
+/* 0xfe */  {NULL, NULL},
+/* 0xff */  {NULL, NULL}
+};

-    offset += 2; /* Skip Byte Count */

-  } else {
-    /* Response(s) dissect code */

-    /* Build display for: Word Count (WCT) */
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ * Everything tvbuffified above this line
+ * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ */

-    WordCount = GBYTE(pd, offset);

-    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+/*
+ * Struct passed to each SMB decode routine of info it may need
+ */

-    }
+char *decode_smb_name(unsigned char);

-    offset += 1; /* Skip Word Count (WCT) */
+int smb_packet_init_count = 200;

-    /* Build display for: Byte Count (BCC) */
+struct smb_request_key {
+  guint32 conversation;
+  guint16 mid;
+  guint16 pid;
+};

-    ByteCount = GSHORT(pd, offset);
+static GHashTable *smb_request_hash = NULL;
+static GMemChunk *smb_request_keys = NULL;
+static GMemChunk *smb_request_vals = NULL;

-    if (tree) {
+/* Hash Functions */
+static gint
+smb_equal(gconstpointer v, gconstpointer w)
+{
+  struct smb_request_key *v1 = (struct smb_request_key *)v;
+  struct smb_request_key *v2 = (struct smb_request_key *)w;

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+#if defined(DEBUG_SMB_HASH)
+  printf("Comparing %08X:%u:%u\n      and %08X:%u:%u\n",
+	 v1 -> conversation, v1 -> mid, v1 -> pid,
+	 v2 -> conversation, v2 -> mid, v2 -> pid);
+#endif

-    }
+  if (v1 -> conversation == v2 -> conversation &&
+      v1 -> mid          == v2 -> mid &&
+      v1 -> pid          == v2 -> pid) {

-    offset += 2; /* Skip Byte Count (BCC) */
+    return 1;

  }

+  return 0;
}

-void
-dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
+static guint
+smb_hash (gconstpointer v)
{
-  guint8        WordCount;
-  guint16       TotalUnits;
-  guint16       Reserved;
-  guint16       FreeUnits;
-  guint16       ByteCount;
-  guint16       BlocksPerUnit;
-  guint16       BlockSize;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    if (WordCount > 0) {
-
-      /* Build display for: Total Units */
-
-      TotalUnits = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);
-
-      }
-
-      offset += 2; /* Skip Total Units */
-
-      /* Build display for: Blocks Per Unit */
-
-      BlocksPerUnit = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);
-
-      }
-
-      offset += 2; /* Skip Blocks Per Unit */
-
-      /* Build display for: Block Size */
-
-      BlockSize = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);
-
-      }
-
-      offset += 2; /* Skip Block Size */
-
-      /* Build display for: Free Units */
-
-      FreeUnits = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);
-
-      }
-
-      offset += 2; /* Skip Free Units */
-
-      /* Build display for: Reserved */
-
-      Reserved = GSHORT(pd, offset);
-
-      if (tree) {
+  struct smb_request_key *key = (struct smb_request_key *)v;
+  guint val;

-	proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
+  val = (key -> conversation) + (key -> mid) + (key -> pid);

-      }
+#if defined(DEBUG_SMB_HASH)
+  printf("SMB Hash calculated as %u\n", val);
+#endif

-      offset += 2; /* Skip Reserved */
+  return val;

-    }
+}

-    /* Build display for: Byte Count (BCC) */
+/*
+ * Free up any state information we've saved, and re-initialize the
+ * tables of state information.
+ */

-    ByteCount = GSHORT(pd, offset);
+/*
+ * For a hash table entry, free the address data to which the key refers
+ * and the fragment data to which the value refers.
+ * (The actual key and value structures get freed by "reassemble_init()".)
+ */
+static gboolean
+free_request_val_data(gpointer key, gpointer value, gpointer user_data)
+{
+  struct smb_request_val *request_val = value;

-    if (tree) {
+  if (request_val->last_transact_command != NULL)
+    g_free(request_val->last_transact_command);
+  if (request_val->last_param_descrip != NULL)
+    g_free(request_val->last_param_descrip);
+  if (request_val->last_data_descrip != NULL)
+    g_free(request_val->last_data_descrip);
+  return TRUE;
+}

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+static void
+smb_init_protocol(void)
+{
+#if defined(DEBUG_SMB_HASH)
+  printf("Initializing SMB hashtable area\n");
+#endif

-    }
+  if (smb_request_hash) {
+    /*
+     * Remove all entries from the hash table and free all strings
+     * attached to the keys and values.  (The keys and values
+     * themselves are freed with "g_mem_chunk_destroy()" calls
+     * below.)
+     */
+ g_hash_table_foreach_remove(smb_request_hash, free_request_val_data, NULL);
+    g_hash_table_destroy(smb_request_hash);
+  }
+  if (smb_request_keys)
+    g_mem_chunk_destroy(smb_request_keys);
+  if (smb_request_vals)
+    g_mem_chunk_destroy(smb_request_vals);

-    offset += 2; /* Skip Byte Count (BCC) */
+  smb_request_hash = g_hash_table_new(smb_hash, smb_equal);
+  smb_request_keys = g_mem_chunk_new("smb_request_keys",
+				     sizeof(struct smb_request_key),
+ smb_packet_init_count * sizeof(struct smb_request_key), G_ALLOC_AND_FREE);
+  smb_request_vals = g_mem_chunk_new("smb_request_vals",
+				     sizeof(struct smb_request_val),
+ smb_packet_init_count * sizeof(struct smb_request_val), G_ALLOC_AND_FREE);
+}

-  }
+static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info si, int, int, int);

-}

-void
-dissect_set_file_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +/* NOTEr: this value_string is accessed directly by index and not val_to_str().
+ * That means that ALL entries 0x00-0xFF MUST exists and be in order.
+ */
+static const value_string smb_cmd_vals[] = {
+  { 0x00, "SMBcreatedirectory" },
+  { 0x01, "SMBdeletedirectory" },
+  { 0x02, "SMBopen" },
+  { 0x03, "SMBcreate" },
+  { 0x04, "SMBclose" },
+  { 0x05, "SMBflush" },
+  { 0x06, "SMBunlink" },
+  { 0x07, "SMBmv" },
+  { 0x08, "SMBgetatr" },
+  { 0x09, "SMBsetatr" },
+  { 0x0A, "SMBread" },
+  { 0x0B, "SMBwrite" },
+  { 0x0C, "SMBlock" },
+  { 0x0D, "SMBunlock" },
+  { 0x0E, "SMBctemp" },
+  { 0x0F, "SMBmknew" },
+  { 0x10, "SMBchkpth" },
+  { 0x11, "SMBexit" },
+  { 0x12, "SMBlseek" },
+  { 0x13, "SMBlockread" },
+  { 0x14, "SMBwriteunlock" },
+  { 0x15, "unknown-0x15" },
+  { 0x16, "unknown-0x16" },
+  { 0x17, "unknown-0x17" },
+  { 0x18, "unknown-0x18" },
+  { 0x19, "unknown-0x19" },
+  { 0x1A, "SMBreadBraw" },
+  { 0x1B, "SMBreadBmpx" },
+  { 0x1C, "SMBreadBs" },
+  { 0x1D, "SMBwriteBraw" },
+  { 0x1E, "SMBwriteBmpx" },
+  { 0x1F, "SMBwriteBs" },
+  { 0x20, "SMBwriteC" },
+  { 0x21, "unknown-0x21" },
+  { 0x22, "SMBsetattrE" },
+  { 0x23, "SMBgetattrE" },
+  { 0x24, "SMBlockingX" },
+  { 0x25, "SMBtrans" },
+  { 0x26, "SMBtranss" },
+  { 0x27, "SMBioctl" },
+  { 0x28, "SMBioctls" },
+  { 0x29, "SMBcopy" },
+  { 0x2A, "SMBmove" },
+  { 0x2B, "SMBecho" },
+  { 0x2C, "SMBwriteclose" },
+  { 0x2D, "SMBopenX" },
+  { 0x2E, "SMBreadX" },
+  { 0x2F, "SMBwriteX" },
+  { 0x30, "unknown-0x30" },
+  { 0x31, "SMBcloseandtreedisc" },
+  { 0x32, "SMBtrans2" },
+  { 0x33, "SMBtrans2secondary" },
+  { 0x34, "SMBfindclose2" },
+  { 0x35, "SMBfindnotifyclose" },
+  { 0x36, "unknown-0x36" },
+  { 0x37, "unknown-0x37" },
+  { 0x38, "unknown-0x38" },
+  { 0x39, "unknown-0x39" },
+  { 0x3A, "unknown-0x3A" },
+  { 0x3B, "unknown-0x3B" },
+  { 0x3C, "unknown-0x3C" },
+  { 0x3D, "unknown-0x3D" },
+  { 0x3E, "unknown-0x3E" },
+  { 0x3F, "unknown-0x3F" },
+  { 0x40, "unknown-0x40" },
+  { 0x41, "unknown-0x41" },
+  { 0x42, "unknown-0x42" },
+  { 0x43, "unknown-0x43" },
+  { 0x44, "unknown-0x44" },
+  { 0x45, "unknown-0x45" },
+  { 0x46, "unknown-0x46" },
+  { 0x47, "unknown-0x47" },
+  { 0x48, "unknown-0x48" },
+  { 0x49, "unknown-0x49" },
+  { 0x4A, "unknown-0x4A" },
+  { 0x4B, "unknown-0x4B" },
+  { 0x4C, "unknown-0x4C" },
+  { 0x4D, "unknown-0x4D" },
+  { 0x4E, "unknown-0x4E" },
+  { 0x4F, "unknown-0x4F" },
+  { 0x50, "unknown-0x50" },
+  { 0x51, "unknown-0x51" },
+  { 0x52, "unknown-0x52" },
+  { 0x53, "unknown-0x53" },
+  { 0x54, "unknown-0x54" },
+  { 0x55, "unknown-0x55" },
+  { 0x56, "unknown-0x56" },
+  { 0x57, "unknown-0x57" },
+  { 0x58, "unknown-0x58" },
+  { 0x59, "unknown-0x59" },
+  { 0x5A, "unknown-0x5A" },
+  { 0x5B, "unknown-0x5B" },
+  { 0x5C, "unknown-0x5C" },
+  { 0x5D, "unknown-0x5D" },
+  { 0x5E, "unknown-0x5E" },
+  { 0x5F, "unknown-0x5F" },
+  { 0x60, "unknown-0x60" },
+  { 0x61, "unknown-0x61" },
+  { 0x62, "unknown-0x62" },
+  { 0x63, "unknown-0x63" },
+  { 0x64, "unknown-0x64" },
+  { 0x65, "unknown-0x65" },
+  { 0x66, "unknown-0x66" },
+  { 0x67, "unknown-0x67" },
+  { 0x68, "unknown-0x68" },
+  { 0x69, "unknown-0x69" },
+  { 0x6A, "unknown-0x6A" },
+  { 0x6B, "unknown-0x6B" },
+  { 0x6C, "unknown-0x6C" },
+  { 0x6D, "unknown-0x6D" },
+  { 0x6E, "unknown-0x6E" },
+  { 0x6F, "unknown-0x6F" },
+  { 0x70, "SMBtcon" },
+  { 0x71, "SMBtdis" },
+  { 0x72, "SMBnegprot" },
+  { 0x73, "SMBsesssetupX" },
+  { 0x74, "SMBlogoffX" },
+  { 0x75, "SMBtconX" },
+  { 0x76, "unknown-0x76" },
+  { 0x77, "unknown-0x77" },
+  { 0x78, "unknown-0x78" },
+  { 0x79, "unknown-0x79" },
+  { 0x7A, "unknown-0x7A" },
+  { 0x7B, "unknown-0x7B" },
+  { 0x7C, "unknown-0x7C" },
+  { 0x7D, "unknown-0x7D" },
+  { 0x7E, "unknown-0x7E" },
+  { 0x7F, "unknown-0x7F" },
+  { 0x80, "SMBdskattr" },
+  { 0x81, "SMBsearch" },
+  { 0x82, "SMBffirst" },
+  { 0x83, "SMBfunique" },
+  { 0x84, "SMBfclose" },
+  { 0x85, "unknown-0x85" },
+  { 0x86, "unknown-0x86" },
+  { 0x87, "unknown-0x87" },
+  { 0x88, "unknown-0x88" },
+  { 0x89, "unknown-0x89" },
+  { 0x8A, "unknown-0x8A" },
+  { 0x8B, "unknown-0x8B" },
+  { 0x8C, "unknown-0x8C" },
+  { 0x8D, "unknown-0x8D" },
+  { 0x8E, "unknown-0x8E" },
+  { 0x8F, "unknown-0x8F" },
+  { 0x90, "unknown-0x90" },
+  { 0x91, "unknown-0x91" },
+  { 0x92, "unknown-0x92" },
+  { 0x93, "unknown-0x93" },
+  { 0x94, "unknown-0x94" },
+  { 0x95, "unknown-0x95" },
+  { 0x96, "unknown-0x96" },
+  { 0x97, "unknown-0x97" },
+  { 0x98, "unknown-0x98" },
+  { 0x99, "unknown-0x99" },
+  { 0x9A, "unknown-0x9A" },
+  { 0x9B, "unknown-0x9B" },
+  { 0x9C, "unknown-0x9C" },
+  { 0x9D, "unknown-0x9D" },
+  { 0x9E, "unknown-0x9E" },
+  { 0x9F, "unknown-0x9F" },
+  { 0xA0, "SMBnttransact" },
+  { 0xA1, "SMBnttransactsecondary" },
+  { 0xA2, "SMBntcreateX" },
+  { 0xA3, "unknown-0xA3" },
+  { 0xA4, "SMBntcancel" },
+  { 0xA5, "unknown-0xA5" },
+  { 0xA6, "unknown-0xA6" },
+  { 0xA7, "unknown-0xA7" },
+  { 0xA8, "unknown-0xA8" },
+  { 0xA9, "unknown-0xA9" },
+  { 0xAA, "unknown-0xAA" },
+  { 0xAB, "unknown-0xAB" },
+  { 0xAC, "unknown-0xAC" },
+  { 0xAD, "unknown-0xAD" },
+  { 0xAE, "unknown-0xAE" },
+  { 0xAF, "unknown-0xAF" },
+  { 0xB0, "unknown-0xB0" },
+  { 0xB1, "unknown-0xB1" },
+  { 0xB2, "unknown-0xB2" },
+  { 0xB3, "unknown-0xB3" },
+  { 0xB4, "unknown-0xB4" },
+  { 0xB5, "unknown-0xB5" },
+  { 0xB6, "unknown-0xB6" },
+  { 0xB7, "unknown-0xB7" },
+  { 0xB8, "unknown-0xB8" },
+  { 0xB9, "unknown-0xB9" },
+  { 0xBA, "unknown-0xBA" },
+  { 0xBB, "unknown-0xBB" },
+  { 0xBC, "unknown-0xBC" },
+  { 0xBD, "unknown-0xBD" },
+  { 0xBE, "unknown-0xBE" },
+  { 0xBF, "unknown-0xBF" },
+  { 0xC0, "SMBsplopen" },
+  { 0xC1, "SMBsplwr" },
+  { 0xC2, "SMBsplclose" },
+  { 0xC3, "SMBsplretq" },
+  { 0xC4, "unknown-0xC4" },
+  { 0xC5, "unknown-0xC5" },
+  { 0xC6, "unknown-0xC6" },
+  { 0xC7, "unknown-0xC7" },
+  { 0xC8, "unknown-0xC8" },
+  { 0xC9, "unknown-0xC9" },
+  { 0xCA, "unknown-0xCA" },
+  { 0xCB, "unknown-0xCB" },
+  { 0xCC, "unknown-0xCC" },
+  { 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" },
+  { 0xD8, "SMBreadbulk" },
+  { 0xD9, "SMBwritebulk" },
+  { 0xDA, "SMBwritebulkdata" },
+  { 0xDB, "unknown-0xDB" },
+  { 0xDC, "unknown-0xDC" },
+  { 0xDD, "unknown-0xDD" },
+  { 0xDE, "unknown-0xDE" },
+  { 0xDF, "unknown-0xDF" },
+  { 0xE0, "unknown-0xE0" },
+  { 0xE1, "unknown-0xE1" },
+  { 0xE2, "unknown-0xE2" },
+  { 0xE3, "unknown-0xE3" },
+  { 0xE4, "unknown-0xE4" },
+  { 0xE5, "unknown-0xE5" },
+  { 0xE6, "unknown-0xE6" },
+  { 0xE7, "unknown-0xE7" },
+  { 0xE8, "unknown-0xE8" },
+  { 0xE9, "unknown-0xE9" },
+  { 0xEA, "unknown-0xEA" },
+  { 0xEB, "unknown-0xEB" },
+  { 0xEC, "unknown-0xEC" },
+  { 0xED, "unknown-0xED" },
+  { 0xEE, "unknown-0xEE" },
+  { 0xEF, "unknown-0xEF" },
+  { 0xF0, "unknown-0xF0" },
+  { 0xF1, "unknown-0xF1" },
+  { 0xF2, "unknown-0xF2" },
+  { 0xF3, "unknown-0xF3" },
+  { 0xF4, "unknown-0xF4" },
+  { 0xF5, "unknown-0xF5" },
+  { 0xF6, "unknown-0xF6" },
+  { 0xF7, "unknown-0xF7" },
+  { 0xF8, "unknown-0xF8" },
+  { 0xF9, "unknown-0xF9" },
+  { 0xFA, "unknown-0xFA" },
+  { 0xFB, "unknown-0xFB" },
+  { 0xFC, "unknown-0xFC" },
+  { 0xFD, "unknown-0xFD" },
+  { 0xFE, "SMBinvalid" },
+  { 0xFF, "unknown-0xFF" },
+  { 0x00, NULL },
+};

+void
+dissect_unknown_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
{
-  proto_tree    *Attributes_tree;
-  proto_item    *ti;
-  guint8        WordCount;
-  guint8        ByteCount;
-  guint8        BufferFormat;
-  guint16       Reserved5;
-  guint16       Reserved4;
-  guint16       Reserved3;
-  guint16       Reserved2;
-  guint16       Reserved1;
-  guint16       LastWriteTime;
-  guint16       LastWriteDate;
-  guint16       Attributes;
-  const char    *FileName;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    if (WordCount > 0) {
-
-      /* Build display for: Attributes */
-
-      Attributes = GSHORT(pd, offset);
-
-      if (tree) {
-
- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes);
-	Attributes_tree = proto_item_add_subtree(ti, ett_smb_file_attributes);
-	proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
-	proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
-	proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
-	proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
-	proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
-	proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
-
-      }
-
-      offset += 2; /* Skip Attributes */
-
-      /* Build display for: Last Write Time */
-
-      LastWriteTime = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
-
-      }
-
-      offset += 2; /* Skip Last Write Time */
-
-      /* Build display for: Last Write Date */
-
-      LastWriteDate = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
-
-      }
-
-      offset += 2; /* Skip Last Write Date */
-
-      /* Build display for: Reserved 1 */
-
-      Reserved1 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
-
-      }
-
-      offset += 2; /* Skip Reserved 1 */
-
-      /* Build display for: Reserved 2 */
-
-      Reserved2 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
-
-      }
-
-      offset += 2; /* Skip Reserved 2 */
-
-      /* Build display for: Reserved 3 */
-
-      Reserved3 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
-
-      }
-
-      offset += 2; /* Skip Reserved 3 */
-
-      /* Build display for: Reserved 4 */
-
-      Reserved4 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
-
-      }
-
-      offset += 2; /* Skip Reserved 4 */
-
-      /* Build display for: Reserved 5 */
-
-      Reserved5 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 5: %u", Reserved5);
-
-      }
-
-      offset += 2; /* Skip Reserved 5 */
-
-    }
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-    /* Build display for: Buffer Format */
-
-    BufferFormat = GBYTE(pd, offset);

-    if (tree) {
+  if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat); + proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (%u bytes)",
+			END_OF_FRAME);

-    }
+  }

-    offset += 1; /* Skip Buffer Format */
+}

-    /* Build display for: File Name */
+/*
+ * Dissect a UNIX like date ...
+ */

-    FileName = pd + offset;
+struct tm *_gtime; /* Add leading underscore ("_") to prevent symbol
+                      conflict with /usr/include/time.h on some NetBSD
+                      systems */

-    if (tree) {
+static char *
+dissect_smbu_date(guint16 date, guint16 time)

- proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
+{
+  static char         datebuf[4+2+2+2+1+10];
+  time_t              ltime = (date << 16) + time;

-    }
+  _gtime = gmtime(&ltime);

-    offset += strlen(FileName) + 1; /* Skip File Name */
+  if (_gtime)
+    sprintf(datebuf, "%04d-%02d-%02d",
+ 1900 + (_gtime -> tm_year), 1 + (_gtime -> tm_mon), _gtime -> tm_mday);
+  else
+    sprintf(datebuf, "Bad date format");

-  } else {
-    /* Response(s) dissect code */
+  return datebuf;

-    /* Build display for: Word Count (WCT) */
+}

-    WordCount = GBYTE(pd, offset);
+/*
+ * Relies on time
+ */
+static char *
+dissect_smbu_time(guint16 date, guint16 time)

-    if (tree) {
+{
+  static char timebuf[2+2+2+2+1+10];

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+  if (_gtime)
+    sprintf(timebuf, "%02d:%02d:%02d",
+	    _gtime -> tm_hour, _gtime -> tm_min, _gtime -> tm_sec);
+  else
+    sprintf(timebuf, "Bad time format");

-    }
+  return timebuf;

-    offset += 1; /* Skip Word Count (WCT) */
+}

-    /* Build display for: Byte Count (BCC) */
+/*
+ * Dissect a DOS-format date.
+ */
+static char *
+dissect_dos_date(guint16 date)
+{
+	static char datebuf[4+2+2+1];

-    ByteCount = GBYTE(pd, offset);
+	sprintf(datebuf, "%04d-%02d-%02d",
+	    ((date>>9)&0x7F) + 1980, (date>>5)&0x0F, date&0x1F);
+	return datebuf;
+}

-    if (tree) {
+/*
+ * Dissect a DOS-format time.
+ */
+static char *
+dissect_dos_time(guint16 time)
+{
+	static char timebuf[2+2+2+1];

- proto_tree_add_text(tree, NullTVB, offset, 1, "Byte Count (BCC): %u", ByteCount);
+	sprintf(timebuf, "%02d:%02d:%02d",
+	    (time>>11)&0x1F, (time>>5)&0x3F, (time&0x1F)*2);
+	return timebuf;
+}

-    }
+/* Max string length for displaying Unicode strings.  */
+#define	MAX_UNICODE_STR_LEN	256

-    offset += 1; /* Skip Byte Count (BCC) */
+/* 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. */
+static gchar *
+unicode_to_str(const guint8 *us, int *us_lenp) {
+  static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
+  static gchar *cur;
+  gchar        *p;
+  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;
+  while (*us != 0 || *(us + 1) != 0) {
+    if (len > 0) {
+      *p++ = *us;
+      len--;
+    } else
+      overflow = 1;
+    us += 2;
+    us_len += 2;
+  }
+  if (overflow) {
+    /* Note that we're not showing the full string.  */
+    *p++ = '.';
+    *p++ = '.';
+    *p++ = '.';
+  }
+  *p = '\0';
+  *us_lenp = us_len;
+  return cur;
}

+/*
+ * Each dissect routine is passed an offset to wct and works from there
+ */
+
void
-dissect_write_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_get_disk_attr_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
  guint8        WordCount;
-  guint8        BufferFormat;
-  guint32       Offset;
-  guint16       Remaining;
-  guint16       FID;
-  guint16       DataLength;
-  guint16       Count;
+  guint16       TotalUnits;
+  guint16       Reserved;
+  guint16       FreeUnits;
  guint16       ByteCount;
+  guint16       BlocksPerUnit;
+  guint16       BlockSize;

  if (si.request) {
    /* Request(s) dissect code */
@@ -2110,126 +2069,97 @@

    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: FID */
-
-    FID = GSHORT(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
-    }
-
-    offset += 2; /* Skip FID */
-
-    /* Build display for: Count */
+    /* Build display for: Byte Count (BCC) */

-    Count = GSHORT(pd, offset);
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 2; /* Skip Count */
-
-    /* Build display for: Offset */
-
-    Offset = GWORD(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
-
-    }
+    offset += 2; /* Skip Byte Count (BCC) */

-    offset += 4; /* Skip Offset */
+  } else {
+    /* Response(s) dissect code */

-    /* Build display for: Remaining */
+    /* Build display for: Word Count (WCT) */

-    Remaining = GSHORT(pd, offset);
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

    }

-    offset += 2; /* Skip Remaining */
-
-    /* Build display for: Byte Count (BCC) */
+    offset += 1; /* Skip Word Count (WCT) */

-    ByteCount = GSHORT(pd, offset);
+    if (WordCount > 0) {

-    if (tree) {
+      /* Build display for: Total Units */

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+      TotalUnits = GSHORT(pd, offset);

-    }
+      if (tree) {

-    offset += 2; /* Skip Byte Count (BCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Total Units: %u", TotalUnits);

-    /* Build display for: Buffer Format */
+      }

-    BufferFormat = GBYTE(pd, offset);
+      offset += 2; /* Skip Total Units */

-    if (tree) {
+      /* Build display for: Blocks Per Unit */

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
+      BlocksPerUnit = GSHORT(pd, offset);

-    }
+      if (tree) {

-    offset += 1; /* Skip Buffer Format */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Blocks Per Unit: %u", BlocksPerUnit);

-    /* Build display for: Data Length */
+      }

-    DataLength = GSHORT(pd, offset);
+      offset += 2; /* Skip Blocks Per Unit */

-    if (tree) {
+      /* Build display for: Block Size */

- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+      BlockSize = GSHORT(pd, offset);

-    }
+      if (tree) {

-    offset += 2; /* Skip Data Length */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Block Size: %u", BlockSize);

-    if (ByteCount > 0 && tree) {
+      }

-	if(END_OF_FRAME >= ByteCount)
- proto_tree_add_text(tree, NullTVB, offset, ByteCount, "Data (%u bytes)", ByteCount);
-	else
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
+      offset += 2; /* Skip Block Size */

-    }
+      /* Build display for: Free Units */

-  } else {
-    /* Response(s) dissect code */
+      FreeUnits = GSHORT(pd, offset);

-    /* Build display for: Word Count (WCT) */
+      if (tree) {

-    WordCount = GBYTE(pd, offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Free Units: %u", FreeUnits);

-    if (tree) {
+      }

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+      offset += 2; /* Skip Free Units */

-    }
+      /* Build display for: Reserved */

-    offset += 1; /* Skip Word Count (WCT) */
+      Reserved = GSHORT(pd, offset);

-    /* Build display for: Count */
+      if (tree) {

-    Count = GSHORT(pd, offset);
+	proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);

-    if (tree) {
+      }

-      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+      offset += 2; /* Skip Reserved */

    }

-    offset += 2; /* Skip Count */
-
    /* Build display for: Byte Count (BCC) */

    ByteCount = GSHORT(pd, offset);
@@ -2246,6 +2176,7 @@

}

+
void
dissect_read_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *arent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

@@ -2485,114 +2416,11 @@

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);
-
-    }
-
-    offset += 1; /* Skip Pad */
-
-  }
-
-}
-
-void
-dissect_delete_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *paernt, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8        WordCount;
-  guint8        BufferFormat;
-  guint16       SearchAttributes;
-  guint16       ByteCount;
-  const char    *FileName;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: SearchAttributes */
-
-    SearchAttributes = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
-    }
-
-    offset += 2; /* Skip SearchAttributes */
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-    /* Build display for: Buffer Format */
-
-    BufferFormat = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
-
-    }
-
-    offset += 1; /* Skip Buffer Format */
-
-    /* Build display for: File Name */
-
-    FileName = pd + offset;
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
-
-    }
-
-    offset += strlen(FileName) + 1; /* Skip File Name */
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+      proto_tree_add_text(tree, NullTVB, offset, 1, "Pad: %u", Pad);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += 1; /* Skip Pad */

  }

@@ -3459,690 +3287,417 @@

	/* Build display for: Primary Domain */

-	PrimaryDomain = pd + offset;
-
-	if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "Primary Domain: %s", PrimaryDomain);
-
-	}
-
-	offset += strlen(PrimaryDomain) + 1; /* Skip Primary Domain */
-
-	/* Build display for: Native OS */
-
-	NativeOS = pd + offset;
-
-	if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);
-
-	}
-
-	offset += strlen(NativeOS) + 1; /* Skip Native OS */
-
-	/* Build display for: Native LanMan Type */
-
-	NativeLanManType = pd + offset;
-
-	if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanManType) + 1, "Native LanMan Type: %s", NativeLanManType);
-
-	}
-
-	offset += strlen(NativeLanManType) + 1; /* Skip Native LanMan Type */
-
-      }
-
-      break;
-
-    }
-
-
-    if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
-
-    }
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    if (WordCount > 0) {
-
-      /* Build display for: AndXCommand */
-
-      AndXCommand = GBYTE(pd, offset);
-
-      if (tree) {
-
-	proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
-
-      }
-
-      offset += 1; /* Skip AndXCommand */
-
-      /* Build display for: AndXReserved */
-
-      AndXReserved = GBYTE(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-
-      }
-
-      offset += 1; /* Skip AndXReserved */
-
-      /* Build display for: AndXOffset */
-
-      AndXOffset = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
-      }
-
-
-      offset += 2; /* Skip AndXOffset */
-
-      /* Build display for: Action */
-
-      Action = GSHORT(pd, offset);
-
-      if (tree) {
-
-	proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);
-
-      }
-
-      offset += 2; /* Skip Action */
-
-    }
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    if (errcode != 0 && WordCount == 0xFF) return;  /* No more here ... */
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-    if (ByteCount > 0) {
-
-      /* Build display for: NativeOS */
-
-      NativeOS = pd + offset;
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "NativeOS: %s", NativeOS);
-
-      }
-
-      offset += strlen(NativeOS) + 1; /* Skip NativeOS */
-
-      /* Build display for: NativeLanMan */
-
-      NativeLanMan = pd + offset;
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "NativeLanMan: %s", NativeLanMan);
-
-      }
-
-      offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */
-
-      /* Build display for: PrimaryDomain */
-
-      PrimaryDomain = pd + offset;
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);
-
-      }
-
-      offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */
-
-    }
-
-    if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
-
-    }
-
-  }
-
-}
-
-void
-dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8      wct, andxcmd = 0xFF;
-  guint16     andxoffs = 0, flags, passwdlen, bcc, optionsup;
-  const char  *str;
-  proto_tree  *flags_tree;
-  proto_item  *ti;
-
-  wct = pd[offset];
-
-  /* Now figure out what format we are talking about, 2, 3, or 4 response
-   * words ...
-   */
-
-  if (!(si.request && (wct == 4)) && !(!si.request && (wct == 2)) &&
-      !(!si.request && (wct == 3)) && !(wct == 0)) {
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);
-
-      proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");
-
-      return;
-
-    }
-
-  }
-
-  if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);
-
-  }
-
-  offset += 1;
-
-  if (wct > 0) {
-
-    andxcmd = pd[offset];
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
-			  (andxcmd == 0xFF) ? "No further commands":
-			  decode_smb_name(andxcmd));
-
- proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);
-
-    }
-
-    offset += 2;
-
-    andxoffs = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);
-
-    }
-
-    offset += 2;
-
-  }
-
-  switch (wct) {
-
-  case 0:
-
-    bcc = GSHORT(pd, offset);
+	PrimaryDomain = pd + offset;

-    if (tree) {
+	if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc); + proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "Primary Domain: %s", PrimaryDomain);

-    }
+	}

-    break;
+	offset += strlen(PrimaryDomain) + 1; /* Skip Primary Domain */

-  case 4:
+	/* Build display for: Native OS */

-    flags = GSHORT(pd, offset);
+	NativeOS = pd + offset;

-    if (tree) {
+	if (tree) {

- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%02x", flags);
-      flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
-      proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s",
-			  decode_boolean_bitfield(flags, 0x01, 16,
-						  "Disconnect TID",
-						  "Don't disconnect TID"));
+ proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "Native OS: %s", NativeOS);

-    }
+	}

-    offset += 2;
+	offset += strlen(NativeOS) + 1; /* Skip Native OS */

-    passwdlen = GSHORT(pd, offset);
+	/* Build display for: Native LanMan Type */

-    if (tree) {
+	NativeLanManType = pd + offset;

- proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);
+	if (tree) {

-    }
+ proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanManType) + 1, "Native LanMan Type: %s", NativeLanManType);

-    offset += 2;
+	}

-    bcc = GSHORT(pd, offset);
+	offset += strlen(NativeLanManType) + 1; /* Skip Native LanMan Type */

-    if (tree) {
+      }

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+      break;

    }

-    offset += 2;
-
-    str = pd + offset;

-    if (tree) {
+    if (AndXCommand != 0xFF) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen)); + (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);

    }

-    offset += passwdlen;
+  } else {
+    /* Response(s) dissect code */

-    str = pd + offset;
+    /* Build display for: Word Count (WCT) */
+
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Path: %s", str); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

    }

-    offset += strlen(str) + 1;
+    offset += 1; /* Skip Word Count (WCT) */

-    str = pd + offset;
+    if (WordCount > 0) {

-    if (tree) {
+      /* Build display for: AndXCommand */

- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);
+      AndXCommand = GBYTE(pd, offset);

-    }
+      if (tree) {

-    break;
+	proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));

-  case 2:
+      }

-    bcc = GSHORT(pd, offset);
+      offset += 1; /* Skip AndXCommand */

-    if (tree) {
+      /* Build display for: AndXReserved */

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+      AndXReserved = GBYTE(pd, offset);

-    }
+      if (tree) {

-    offset += 2;
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);

-    str = pd + offset;
+      }

-    if (tree) {
+      offset += 1; /* Skip AndXReserved */

- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
-			  str);
+      /* Build display for: AndXOffset */

-    }
+      AndXOffset = GSHORT(pd, offset);

-    offset += strlen(str) + 1;
+      if (tree) {

-    break;
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);

-  case 3:
+      }

-    optionsup = GSHORT(pd, offset);

-    if (tree) {  /* Should break out the bits */
+      offset += 2; /* Skip AndXOffset */

- proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x",
-			  optionsup);
+      /* Build display for: Action */

-    }
+      Action = GSHORT(pd, offset);

-    offset += 2;
+      if (tree) {

-    bcc = GSHORT(pd, offset);
+	proto_tree_add_text(tree, NullTVB, offset, 2, "Action: %u", Action);

-    if (tree) {
+      }

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);
+      offset += 2; /* Skip Action */

    }

-    offset += 2;
+    /* Build display for: Byte Count (BCC) */

-    str = pd + offset;
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += strlen(str) + 1;
+    if (errcode != 0 && WordCount == 0xFF) return;  /* No more here ... */

-    str = pd + offset;
+    offset += 2; /* Skip Byte Count (BCC) */

-    if (tree) {
+    if (ByteCount > 0) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Native File System: %s", str);
+      /* Build display for: NativeOS */

-    }
+      NativeOS = pd + offset;

-    offset += strlen(str) + 1;
+      if (tree) {

-
-    break;
+ proto_tree_add_text(tree, NullTVB, offset, strlen(NativeOS) + 1, "NativeOS: %s", NativeOS);

-  default:
-	; /* nothing */
-	break;
-  }
+      }

-  if (andxcmd != 0xFF) /* Process that next command ... ??? */
+      offset += strlen(NativeOS) + 1; /* Skip NativeOS */

- (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset, errcode);
+      /* Build display for: NativeLanMan */

-}
+      NativeLanMan = pd + offset;

-void
-dissect_deletedir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
+      if (tree) {

-{
-  guint8        WordCount;
-  guint8        BufferFormat;
-  guint16       ByteCount;
-  const char    *DirectoryName;
+ proto_tree_add_text(tree, NullTVB, offset, strlen(NativeLanMan) + 1, "NativeLanMan: %s", NativeLanMan);

-  if (si.request) {
-    /* Request(s) dissect code */
+      }

-    /* Build display for: Word Count (WCT) */
+      offset += strlen(NativeLanMan) + 1; /* Skip NativeLanMan */

-    WordCount = GBYTE(pd, offset);
+      /* Build display for: PrimaryDomain */

-    if (tree) {
+      PrimaryDomain = pd + offset;

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+      if (tree) {

-    }
+ proto_tree_add_text(tree, NullTVB, offset, strlen(PrimaryDomain) + 1, "PrimaryDomain: %s", PrimaryDomain);

-    offset += 1; /* Skip Word Count (WCT) */
+      }

-    /* Build display for: Byte Count (BCC) */
+      offset += strlen(PrimaryDomain) + 1; /* Skip PrimaryDomain */

-    ByteCount = GSHORT(pd, offset);
+    }

-    if (tree) {
+    if (AndXCommand != 0xFF) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+  }

-    /* Build display for: Buffer Format */
+}

-    BufferFormat = GBYTE(pd, offset);
+void
+dissect_tcon_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

-    if (tree) {
+{
+  guint8      wct, andxcmd = 0xFF;
+  guint16     andxoffs = 0, flags, passwdlen, bcc, optionsup;
+  const char  *str;
+  proto_tree  *flags_tree;
+  proto_item  *ti;

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
+  wct = pd[offset];

-    }
+  /* Now figure out what format we are talking about, 2, 3, or 4 response
+   * words ...
+   */

-    offset += 1; /* Skip Buffer Format */
+  if (!(si.request && (wct == 4)) && !(!si.request && (wct == 2)) &&
+      !(!si.request && (wct == 3)) && !(wct == 0)) {

-    /* Build display for: Directory Name */
+    if (tree) {

-    DirectoryName = pd + offset;
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Invalid TCON_ANDX format. WCT should be 0, 2, 3, or 4 ..., not %u", wct);

-    if (tree) {
+      proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data");

- proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName);
+      return;

    }
+
+  }

-    offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
+  if (tree) {

-  } else {
-    /* Response(s) dissect code */
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", wct);

-    /* Build display for: Word Count (WCT) */
+  }

-    WordCount = GBYTE(pd, offset);
+  offset += 1;
+
+  if (wct > 0) {
+
+    andxcmd = pd[offset];

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+      proto_tree_add_text(tree, NullTVB, offset, 1, "Next Command: %s",
+			  (andxcmd == 0xFF) ? "No further commands":
+			  decode_smb_name(andxcmd));
+
+ proto_tree_add_text(tree, NullTVB, offset + 1, 1, "Reserved (MBZ): %u", pd[offset+1]);

    }

-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
+    offset += 2;

-    ByteCount = GSHORT(pd, offset);
+    andxoffs = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Offset to next command: %u", andxoffs);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += 2;

  }

-}
-
-void
-dissect_createdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8        WordCount;
-  guint8        BufferFormat;
-  guint16       ByteCount;
-  const char    *DirectoryName;
-
-  if (si.request) {
-    /* Request(s) dissect code */
+  switch (wct) {

-    /* Build display for: Word Count (WCT) */
+  case 0:

-    WordCount = GBYTE(pd, offset);
+    bcc = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    break;

-    /* Build display for: Byte Count (BCC) */
+  case 4:

-    ByteCount = GSHORT(pd, offset);
+    flags = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Additional Flags: 0x%02x", flags);
+      flags_tree = proto_item_add_subtree(ti, ett_smb_aflags);
+      proto_tree_add_text(flags_tree, NullTVB, offset, 2, "%s",
+			  decode_boolean_bitfield(flags, 0x01, 16,
+						  "Disconnect TID",
+						  "Don't disconnect TID"));

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
-    /* Build display for: Buffer Format */
+    offset += 2;

-    BufferFormat = GBYTE(pd, offset);
+    passwdlen = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat); + proto_tree_add_text(tree, NullTVB, offset, 2, "Password Length: %u", passwdlen);

    }

-    offset += 1; /* Skip Buffer Format */
-
-    /* Build display for: Directory Name */
+    offset += 2;

-    DirectoryName = pd + offset;
+    bcc = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);

    }

-    offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
+    offset += 2;

-    WordCount = GBYTE(pd, offset);
+    str = pd + offset;

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Password: %s", format_text(str, passwdlen));

    }

-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
+    offset += passwdlen;

-    ByteCount = GSHORT(pd, offset);
+    str = pd + offset;

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Path: %s", str);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
-  }
+    offset += strlen(str) + 1;

-}
+    str = pd + offset;

+    if (tree) {

-void
-dissect_checkdir_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) + proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);

-{
-  guint8        WordCount;
-  guint8        BufferFormat;
-  guint16       ByteCount;
-  const char    *DirectoryName;
+    }

-  if (si.request) {
-    /* Request(s) dissect code */
+    break;

-    /* Build display for: Word Count (WCT) */
+  case 2:

-    WordCount = GBYTE(pd, offset);
+    bcc = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);

    }

-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
+    offset += 2;

-    ByteCount = GSHORT(pd, offset);
+    str = pd + offset;

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service Type: %s",
+			  str);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += strlen(str) + 1;

-    /* Build display for: Buffer Format */
+    break;

-    BufferFormat = GBYTE(pd, offset);
+  case 3:

-    if (tree) {
+    optionsup = GSHORT(pd, offset);

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
+    if (tree) {  /* Should break out the bits */

-    }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Optional Support: 0x%04x",
+			  optionsup);

-    offset += 1; /* Skip Buffer Format */
+    }

-    /* Build display for: Directory Name */
+    offset += 2;

-    DirectoryName = pd + offset;
+    bcc = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(DirectoryName) + 1, "Directory Name: %s", DirectoryName); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", bcc);

    }

-    offset += strlen(DirectoryName) + 1; /* Skip Directory Name */
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
+    offset += 2;

-    WordCount = GBYTE(pd, offset);
+    str = pd + offset;

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Service: %s", str);

    }

-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
+    offset += strlen(str) + 1;

-    ByteCount = GSHORT(pd, offset);
+    str = pd + offset;

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, strlen(str) + 1, "Native File System: %s", str);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += strlen(str) + 1;
+
+
+    break;

+  default:
+	; /* nothing */
+	break;
  }

+  if (andxcmd != 0xFF) /* Process that next command ... ??? */
+
+ (dissect[andxcmd])(pd, SMB_offset + andxoffs, fd, parent, tree, si, max_data - offset, SMB_offset, errcode);
+
}

+
void
dissect_open_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

@@ -5307,137 +4862,7 @@

    }

-    offset += strlen(ErrorFileName) + 1; /* Skip Error File Name */
-
-  }
-
-}
-
-void
-dissect_rename_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8        WordCount;
-  guint8        BufferFormat2;
-  guint8        BufferFormat1;
-  guint16       SearchAttributes;
-  guint16       ByteCount;
-  const char    *OldFileName;
-  const char    *NewFileName;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Search Attributes */
-
-    SearchAttributes = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Search Attributes: %u", SearchAttributes);
-
-    }
-
-    offset += 2; /* Skip Search Attributes */
-
-    /* Build display for: Byte Count */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count */
-
-    /* Build display for: Buffer Format 1 */
-
-    BufferFormat1 = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 1: %u", BufferFormat1);
-
-    }
-
-    offset += 1; /* Skip Buffer Format 1 */
-
-    /* Build display for: Old File Name */
-
-    OldFileName = pd + offset;
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(OldFileName) + 1, "Old File Name: %s", OldFileName);
-
-    }
-
-    offset += strlen(OldFileName) + 1; /* Skip Old File Name */
-
-    /* Build display for: Buffer Format 2 */
-
-    BufferFormat2 = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format 2: %u", BufferFormat2);
-
-    }
-
-    offset += 1; /* Skip Buffer Format 2 */
-
-    /* Build display for: New File Name */
-
-    NewFileName = pd + offset;
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(NewFileName) + 1, "New File Name: %s", NewFileName);
-
-    }
-
-    offset += strlen(NewFileName) + 1; /* Skip New File Name */
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += strlen(ErrorFileName) + 1; /* Skip Error File Name */

  }

@@ -5999,307 +5424,68 @@

    offset += 4; /* Skip Offset */

-    /* Build display for: Max Count */
-
-    MaxCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
-
-    }
-
-    offset += 2; /* Skip Max Count */
-
-    /* Build display for: Min Count */
-
-    MinCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);
-
-    }
-
-    offset += 2; /* Skip Min Count */
-
-    /* Build display for: Reserved */
-
-    Reserved = GWORD(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);
-
-    }
-
-    offset += 4; /* Skip Reserved */
-
-    /* Build display for: Remaining */
-
-    Remaining = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
-
-    }
-
-    offset += 2; /* Skip Remaining */
-
-    if (WordCount == 12) {
-
-	/* Build display for: Offset High */
-
-	OffsetHigh = GWORD(pd, offset);
-
-	if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
-
-	}
-
-	offset += 4; /* Skip Offset High */
-    }
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-
-    if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
-
-    }
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: AndXCommand */
-
-    AndXCommand = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
-
-    }
-
-    offset += 1; /* Skip AndXCommand */
-
-    /* Build display for: AndXReserved */
-
-    AndXReserved = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
-
-    }
-
-    offset += 1; /* Skip AndXReserved */
-
-    /* Build display for: AndXOffset */
-
-    AndXOffset = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
-
-    }
-
-    offset += 2; /* Skip AndXOffset */
-
-    /* Build display for: Remaining */
-
-    Remaining = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
-
-    }
-
-    offset += 2; /* Skip Remaining */
-
-    /* Build display for: Data Compaction Mode */
-
-    DataCompactionMode = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);
-
-    }
-
-    offset += 2; /* Skip Data Compaction Mode */
-
-    /* Build display for: Reserved */
-
-    Reserved = GSHORT(pd, offset);
-
-    if (tree) {
-
-	proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);
-
-    }
-
-    offset += 2; /* Skip Reserved */
-
-    /* Build display for: Data Length */
-
-    DataLength = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
-
-    }
-
-    offset += 2; /* Skip Data Length */
-
-    /* Build display for: Data Offset */
-
-    DataOffset = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);
-
-    }
-
-    offset += 2; /* Skip Data Offset */
-
-    /* Build display for: Reserved[5] */
-
-    for(i = 1; i <= 5; ++i) {
-
-	Reserved = GSHORT(pd, offset);
-
-	if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved%u: %u", i, Reserved);
-
-	}
-	offset += 2;
-    }
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-    /* Build display for data */
-
-    if (tree) {
-
-	offset = SMB_offset + DataOffset;
-	if(END_OF_FRAME >= DataLength)
- proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
-	else
- proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);
-
-    }
-
-    if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
-
-    }
-
-  }
-
-}
-
-void
-dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8        WordCount;
-  guint8        AndXReserved;
-  guint8        AndXCommand = 0xFF;
-  guint16       ByteCount;
-  guint16       AndXOffset = 0;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
+    /* Build display for: Max Count */

-    WordCount = GBYTE(pd, offset);
+    MaxCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 2; /* Skip Max Count */

-    /* Build display for: AndXCommand */
+    /* Build display for: Min Count */

-    AndXCommand = GBYTE(pd, offset);
+    MinCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand); + proto_tree_add_text(tree, NullTVB, offset, 2, "Min Count: %u", MinCount);

    }

-    offset += 1; /* Skip AndXCommand */
+    offset += 2; /* Skip Min Count */

-    /* Build display for: AndXReserved */
+    /* Build display for: Reserved */

-    AndXReserved = GBYTE(pd, offset);
+    Reserved = GWORD(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved); + proto_tree_add_text(tree, NullTVB, offset, 4, "Reserved: %u", Reserved);

    }

-    offset += 1; /* Skip AndXReserved */
+    offset += 4; /* Skip Reserved */

-    /* Build display for: AndXOffset */
+    /* Build display for: Remaining */

-    AndXOffset = GSHORT(pd, offset);
+    Remaining = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset); + proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);

    }

-    offset += 2; /* Skip AndXOffset */
+    offset += 2; /* Skip Remaining */
+
+    if (WordCount == 12) {
+
+	/* Build display for: Offset High */
+
+	OffsetHigh = GWORD(pd, offset);
+
+	if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Offset High: %u", OffsetHigh);
+
+	}
+
+	offset += 4; /* Skip Offset High */
+    }

    /* Build display for: Byte Count (BCC) */

@@ -6371,100 +5557,79 @@

    offset += 2; /* Skip AndXOffset */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: Remaining */

-    ByteCount = GSHORT(pd, offset);
+    Remaining = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
-
-    if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
+    offset += 2; /* Skip Remaining */

-    }
+    /* Build display for: Data Compaction Mode */

-  }
+    DataCompactionMode = GSHORT(pd, offset);

-}
+    if (tree) {

-void
-dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) + proto_tree_add_text(tree, NullTVB, offset, 2, "Data Compaction Mode: %u", DataCompactionMode);

-{
-  static const value_string Mode_0x03[] = {
-	{ 0, "Seek from start of file"},
-	{ 1, "Seek from current position"},
-	{ 2, "Seek from end of file"},
-	{ 0, NULL}
-  };
-  proto_tree    *Mode_tree;
-  proto_item    *ti;
-  guint8        WordCount;
-  guint32       Offset;
-  guint16       Mode;
-  guint16       FID;
-  guint16       ByteCount;
+    }

-  if (si.request) {
-    /* Request(s) dissect code */
+    offset += 2; /* Skip Data Compaction Mode */

-    /* Build display for: Word Count (WCT) */
+    /* Build display for: Reserved */

-    WordCount = GBYTE(pd, offset);
+    Reserved = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
+	proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved: %u", Reserved);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 2; /* Skip Reserved */

-    /* Build display for: FID */
+    /* Build display for: Data Length */

-    FID = GSHORT(pd, offset);
+    DataLength = GSHORT(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);

    }

-    offset += 2; /* Skip FID */
+    offset += 2; /* Skip Data Length */

-    /* Build display for: Mode */
+    /* Build display for: Data Offset */

-    Mode = GSHORT(pd, offset);
+    DataOffset = GSHORT(pd, offset);

    if (tree) {

- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
-      Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
-      proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
- decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
-
-}
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Offset: %u", DataOffset);

-    offset += 2; /* Skip Mode */
+    }

-    /* Build display for: Offset */
+    offset += 2; /* Skip Data Offset */

-    Offset = GWORD(pd, offset);
+    /* Build display for: Reserved[5] */
+
+    for(i = 1; i <= 5; ++i) {

-    if (tree) {
+	Reserved = GSHORT(pd, offset);

-      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+	if (tree) {

-    }
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved%u: %u", i, Reserved);

-    offset += 4; /* Skip Offset */
+	}
+	offset += 2;
+    }

    /* Build display for: Byte Count (BCC) */

@@ -6478,61 +5643,37 @@

    offset += 2; /* Skip Byte Count (BCC) */

-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: Offset */
-
-    Offset = GWORD(pd, offset);
+    /* Build display for data */

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+	offset = SMB_offset + DataOffset;
+	if(END_OF_FRAME >= DataLength)
+ proto_tree_add_text(tree, NullTVB, offset, DataLength, "Data (%u bytes)", DataLength);
+	else
+ proto_tree_add_text(tree, NullTVB, offset, END_OF_FRAME, "Data (first %u bytes)", END_OF_FRAME);

    }

-    offset += 4; /* Skip Offset */
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
+    if (AndXCommand != 0xFF) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
  }

}

void
-dissect_write_and_unlock_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_logoff_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
  guint8        WordCount;
-  guint8        BufferFormat;
-  guint32       Offset;
-  guint16       Remaining;
-  guint16       FID;
-  guint16       DataLength;
-  guint16       Count;
+  guint8        AndXReserved;
+  guint8        AndXCommand = 0xFF;
  guint16       ByteCount;
+  guint16       AndXOffset = 0;

  if (si.request) {
    /* Request(s) dissect code */
@@ -6549,116 +5690,111 @@

    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: FID */
+    /* Build display for: AndXCommand */

-    FID = GSHORT(pd, offset);
+    AndXCommand = GBYTE(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);

    }

-    offset += 2; /* Skip FID */
+    offset += 1; /* Skip AndXCommand */

-    /* Build display for: Count */
+    /* Build display for: AndXReserved */

-    Count = GSHORT(pd, offset);
+    AndXReserved = GBYTE(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);

    }

-    offset += 2; /* Skip Count */
+    offset += 1; /* Skip AndXReserved */

-    /* Build display for: Offset */
+    /* Build display for: AndXOffset */

-    Offset = GWORD(pd, offset);
+    AndXOffset = GSHORT(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);

    }

-    offset += 4; /* Skip Offset */
+    offset += 2; /* Skip AndXOffset */

-    /* Build display for: Remaining */
+    /* Build display for: Byte Count (BCC) */

-    Remaining = GSHORT(pd, offset);
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 2; /* Skip Remaining */
-
-    /* Build display for: Byte Count (BCC) */
+    offset += 2; /* Skip Byte Count (BCC) */

-    ByteCount = GSHORT(pd, offset);

-    if (tree) {
+    if (AndXCommand != 0xFF) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+  } else {
+    /* Response(s) dissect code */

-    /* Build display for: Buffer Format */
+    /* Build display for: Word Count (WCT) */

-    BufferFormat = GBYTE(pd, offset);
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

    }

-    offset += 1; /* Skip Buffer Format */
+    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: Data Length */
+    /* Build display for: AndXCommand */

-    DataLength = GSHORT(pd, offset);
+    AndXCommand = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength); + proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);

    }

-    offset += 2; /* Skip Data Length */
-
-  } else {
-    /* Response(s) dissect code */
+    offset += 1; /* Skip AndXCommand */

-    /* Build display for: Word Count (WCT) */
+    /* Build display for: AndXReserved */

-    WordCount = GBYTE(pd, offset);
+    AndXReserved = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 1; /* Skip AndXReserved */

-    /* Build display for: Count */
+    /* Build display for: AndXOffset */

-    Count = GSHORT(pd, offset);
+    AndXOffset = GSHORT(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);

    }

-    offset += 2; /* Skip Count */
+    offset += 2; /* Skip AndXOffset */

    /* Build display for: Byte Count (BCC) */

@@ -6672,38 +5808,49 @@

    offset += 2; /* Skip Byte Count (BCC) */

+
+    if (AndXCommand != 0xFF) {
+
+ (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
+
+    }
+
  }

}

void
-dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_seek_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
+  static const value_string Mode_0x03[] = {
+	{ 0, "Seek from start of file"},
+	{ 1, "Seek from current position"},
+	{ 2, "Seek from end of file"},
+	{ 0, NULL}
+  };
+  proto_tree    *Mode_tree;
+  proto_item    *ti;
  guint8        WordCount;
-  guint16       LastWriteTime;
-  guint16       LastWriteDate;
-  guint16       LastAccessTime;
-  guint16       LastAccessDate;
+  guint32       Offset;
+  guint16       Mode;
  guint16       FID;
-  guint16       CreationTime;
-  guint16       CreationDate;
  guint16       ByteCount;

  if (si.request) {
    /* Request(s) dissect code */

-    /* Build display for: Word Count */
+    /* Build display for: Word Count (WCT) */

    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

    }

-    offset += 1; /* Skip Word Count */
+    offset += 1; /* Skip Word Count (WCT) */

    /* Build display for: FID */

@@ -6717,104 +5864,71 @@

    offset += 2; /* Skip FID */

-    /* Build display for: Creation Date */
-
-    CreationDate = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));
-
-    }
-
-    offset += 2; /* Skip Creation Date */
-
-    /* Build display for: Creation Time */
-
-    CreationTime = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));
-
-    }
-
-    offset += 2; /* Skip Creation Time */
-
-    /* Build display for: Last Access Date */
+    /* Build display for: Mode */

-    LastAccessDate = GSHORT(pd, offset);
+    Mode = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));
-
-    }
+ ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Mode: 0x%02x", Mode);
+      Mode_tree = proto_item_add_subtree(ti, ett_smb_mode);
+      proto_tree_add_text(Mode_tree, NullTVB, offset, 2, "%s",
+ decode_enumerated_bitfield(Mode, 0x03, 16, Mode_0x03, "%s"));
+
+}

-    offset += 2; /* Skip Last Access Date */
+    offset += 2; /* Skip Mode */

-    /* Build display for: Last Access Time */
+    /* Build display for: Offset */

-    LastAccessTime = GSHORT(pd, offset);
+    Offset = GWORD(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));
+      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);

    }

-    offset += 2; /* Skip Last Access Time */
+    offset += 4; /* Skip Offset */

-    /* Build display for: Last Write Date */
+    /* Build display for: Byte Count (BCC) */

-    LastWriteDate = GSHORT(pd, offset);
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate)); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 2; /* Skip Last Write Date */
-
-    /* Build display for: Last Write Time */
-
-    LastWriteTime = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
-
-    }
+    offset += 2; /* Skip Byte Count (BCC) */

-    offset += 2; /* Skip Last Write Time */
+  } else {
+    /* Response(s) dissect code */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: Word Count (WCT) */

-    ByteCount = GSHORT(pd, offset);
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
-  } else {
-    /* Response(s) dissect code */
+    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: Word Count (WCC) */
+    /* Build display for: Offset */

-    WordCount = GBYTE(pd, offset);
+    Offset = GWORD(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);
+      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);

    }

-    offset += 1; /* Skip Word Count (WCC) */
+    offset += 4; /* Skip Offset */

    /* Build display for: Byte Count (BCC) */

@@ -6833,13 +5947,16 @@
}

void
-dissect_lock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_write_and_unlock_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
  guint8        WordCount;
+  guint8        BufferFormat;
  guint32       Offset;
-  guint32       Count;
+  guint16       Remaining;
  guint16       FID;
+  guint16       DataLength;
+  guint16       Count;
  guint16       ByteCount;

  if (si.request) {
@@ -6871,15 +5988,15 @@

    /* Build display for: Count */

-    Count = GWORD(pd, offset);
+    Count = GSHORT(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
+      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);

    }

-    offset += 4; /* Skip Count */
+    offset += 2; /* Skip Count */

    /* Build display for: Offset */

@@ -6893,6 +6010,18 @@

    offset += 4; /* Skip Offset */

+    /* Build display for: Remaining */
+
+    Remaining = GSHORT(pd, offset);
+
+    if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
+
+    }
+
+    offset += 2; /* Skip Remaining */
+
    /* Build display for: Byte Count (BCC) */

    ByteCount = GSHORT(pd, offset);
@@ -6905,6 +6034,30 @@

    offset += 2; /* Skip Byte Count (BCC) */

+    /* Build display for: Buffer Format */
+
+    BufferFormat = GBYTE(pd, offset);
+
+    if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
+
+    }
+
+    offset += 1; /* Skip Buffer Format */
+
+    /* Build display for: Data Length */
+
+    DataLength = GSHORT(pd, offset);
+
+    if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
+
+    }
+
+    offset += 2; /* Skip Data Length */
+
  } else {
    /* Response(s) dissect code */

@@ -6920,6 +6073,18 @@

    offset += 1; /* Skip Word Count (WCT) */

+    /* Build display for: Count */
+
+    Count = GSHORT(pd, offset);
+
+    if (tree) {
+
+      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+
+    }
+
+    offset += 2; /* Skip Count */
+
    /* Build display for: Byte Count (BCC) */

    ByteCount = GSHORT(pd, offset);
@@ -6937,16 +6102,17 @@
}

void
-dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_set_info2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
  guint8        WordCount;
-  guint8        BufferFormat;
-  guint16       StartIndex;
-  guint16       RestartIndex;
-  guint16       MaxCount;
-  guint16       DataLength;
-  guint16       Count;
+  guint16       LastWriteTime;
+  guint16       LastWriteDate;
+  guint16       LastAccessTime;
+  guint16       LastAccessDate;
+  guint16       FID;
+  guint16       CreationTime;
+  guint16       CreationDate;
  guint16       ByteCount;

  if (si.request) {
@@ -6964,87 +6130,92 @@

    offset += 1; /* Skip Word Count */

-    /* Build display for: Max Count */
+    /* Build display for: FID */

-    MaxCount = GSHORT(pd, offset);
+    FID = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);
+      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);

    }

-    offset += 2; /* Skip Max Count */
+    offset += 2; /* Skip FID */

-    /* Build display for: Start Index */
+    /* Build display for: Creation Date */

-    StartIndex = GSHORT(pd, offset);
+    CreationDate = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex); + proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Date: %s", dissect_dos_date(CreationDate));

    }

-    offset += 2; /* Skip Start Index */
+    offset += 2; /* Skip Creation Date */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: Creation Time */

-    ByteCount = GSHORT(pd, offset);
+    CreationTime = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime));

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
-  } else {
-    /* Response(s) dissect code */
+    offset += 2; /* Skip Creation Time */

-    /* Build display for: Word Count (WCT) */
+    /* Build display for: Last Access Date */

-    WordCount = GBYTE(pd, offset);
+    LastAccessDate = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Date: %s", dissect_dos_date(LastAccessDate));

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 2; /* Skip Last Access Date */

-    if (WordCount > 0) {
+    /* Build display for: Last Access Time */

-      /* Build display for: Count */
+    LastAccessTime = GSHORT(pd, offset);

-      Count = GSHORT(pd, offset);
+    if (tree) {

-      if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Access Time: %s", dissect_dos_time(LastAccessTime));

-	proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
+    }

-      }
+    offset += 2; /* Skip Last Access Time */

-      offset += 2; /* Skip Count */
+    /* Build display for: Last Write Date */

-      /* Build display for: Restart Index */
+    LastWriteDate = GSHORT(pd, offset);

-      RestartIndex = GSHORT(pd, offset);
+    if (tree) {

-      if (tree) {
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));

- proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);
+    }

-      }
+    offset += 2; /* Skip Last Write Date */
+
+    /* Build display for: Last Write Time */
+
+    LastWriteTime = GSHORT(pd, offset);

-      offset += 2; /* Skip Restart Index */
+    if (tree) {

-      /* Build display for: Byte Count (BCC) */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));

    }

+    offset += 2; /* Skip Last Write Time */
+
+    /* Build display for: Byte Count (BCC) */
+
    ByteCount = GSHORT(pd, offset);

    if (tree) {
@@ -7055,52 +6226,46 @@

    offset += 2; /* Skip Byte Count (BCC) */

-    /* Build display for: Buffer Format */
+  } else {
+    /* Response(s) dissect code */

-    BufferFormat = GBYTE(pd, offset);
+    /* Build display for: Word Count (WCC) */
+
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCC): %u", WordCount);

    }

-    offset += 1; /* Skip Buffer Format */
+    offset += 1; /* Skip Word Count (WCC) */

-    /* Build display for: Data Length */
+    /* Build display for: Byte Count (BCC) */

-    DataLength = GSHORT(pd, offset);
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 2; /* Skip Data Length */
+    offset += 2; /* Skip Byte Count (BCC) */

  }

}

void
-dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_lock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
-  proto_tree    *LockType_tree;
-  proto_item    *ti;
-  guint8        LockType;
  guint8        WordCount;
-  guint8        OplockLevel;
-  guint8        AndXReserved;
-  guint8        AndXCommand = 0xFF;
-  guint32       Timeout;
-  guint16       NumberofLocks;
-  guint16       NumberOfUnlocks;
+  guint32       Offset;
+  guint32       Count;
  guint16       FID;
  guint16       ByteCount;
-  guint16       AndXoffset;
-  guint16       AndXOffset = 0;

  if (si.request) {
    /* Request(s) dissect code */
@@ -7117,124 +6282,136 @@

    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: AndXCommand */
+    /* Build display for: FID */

-    AndXCommand = GBYTE(pd, offset);
+    FID = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);
+      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);

    }

-    offset += 1; /* Skip AndXCommand */
+    offset += 2; /* Skip FID */

-    /* Build display for: AndXReserved */
+    /* Build display for: Count */

-    AndXReserved = GBYTE(pd, offset);
+    Count = GWORD(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+      proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);

    }

-    offset += 1; /* Skip AndXReserved */
+    offset += 4; /* Skip Count */

-    /* Build display for: AndXOffset */
+    /* Build display for: Offset */

-    AndXOffset = GSHORT(pd, offset);
+    Offset = GWORD(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);
+      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);

    }

-    offset += 2; /* Skip AndXOffset */
+    offset += 4; /* Skip Offset */

-    /* Build display for: FID */
+    /* Build display for: Byte Count (BCC) */

-    FID = GSHORT(pd, offset);
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 2; /* Skip FID */
+    offset += 2; /* Skip Byte Count (BCC) */

-    /* Build display for: Lock Type */
+  } else {
+    /* Response(s) dissect code */

-    LockType = GBYTE(pd, offset);
+    /* Build display for: Word Count (WCT) */
+
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
-      LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
-      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
-      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
-      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
-      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
-      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
- decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
-
-}
+ proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

-    offset += 1; /* Skip Lock Type */
+    }

-    /* Build display for: OplockLevel */
+    offset += 1; /* Skip Word Count (WCT) */

-    OplockLevel = GBYTE(pd, offset);
+    /* Build display for: Byte Count (BCC) */
+
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 1; /* Skip OplockLevel */
+    offset += 2; /* Skip Byte Count (BCC) */

-    /* Build display for: Timeout */
+  }

-    Timeout = GWORD(pd, offset);
+}
+
+void
+dissect_get_print_queue_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
+
+{
+  guint8        WordCount;
+  guint8        BufferFormat;
+  guint16       StartIndex;
+  guint16       RestartIndex;
+  guint16       MaxCount;
+  guint16       DataLength;
+  guint16       Count;
+  guint16       ByteCount;
+
+  if (si.request) {
+    /* Request(s) dissect code */
+
+    /* Build display for: Word Count */
+
+    WordCount = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout); + proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count: %u", WordCount);

    }

-    offset += 4; /* Skip Timeout */
+    offset += 1; /* Skip Word Count */

-    /* Build display for: Number Of Unlocks */
+    /* Build display for: Max Count */

-    NumberOfUnlocks = GSHORT(pd, offset);
+    MaxCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks); + proto_tree_add_text(tree, NullTVB, offset, 2, "Max Count: %u", MaxCount);

    }

-    offset += 2; /* Skip Number Of Unlocks */
+    offset += 2; /* Skip Max Count */

-    /* Build display for: Number of Locks */
+    /* Build display for: Start Index */

-    NumberofLocks = GSHORT(pd, offset);
+    StartIndex = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks); + proto_tree_add_text(tree, NullTVB, offset, 2, "Start Index: %u", StartIndex);

    }

-    offset += 2; /* Skip Number of Locks */
+    offset += 2; /* Skip Start Index */

    /* Build display for: Byte Count (BCC) */

@@ -7248,13 +6425,6 @@

    offset += 2; /* Skip Byte Count (BCC) */

-
-    if (AndXCommand != 0xFF) {
-
- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
-
-    }
-
  } else {
    /* Response(s) dissect code */

@@ -7272,77 +6442,90 @@

    if (WordCount > 0) {

-      /* Build display for: AndXCommand */
+      /* Build display for: Count */

-      AndXCommand = GBYTE(pd, offset);
+      Count = GSHORT(pd, offset);

      if (tree) {

-	proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
- (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));
+	proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);

      }

-      offset += 1; /* Skip AndXCommand */
+      offset += 2; /* Skip Count */

-      /* Build display for: AndXReserved */
+      /* Build display for: Restart Index */

-      AndXReserved = GBYTE(pd, offset);
+      RestartIndex = GSHORT(pd, offset);

      if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved); + proto_tree_add_text(tree, NullTVB, offset, 2, "Restart Index: %u", RestartIndex);

      }

-      offset += 1; /* Skip AndXReserved */
-
-      /* Build display for: AndXoffset */
+      offset += 2; /* Skip Restart Index */

-      AndXoffset = GSHORT(pd, offset);
+      /* Build display for: Byte Count (BCC) */

-      if (tree) {
+    }

- proto_tree_add_text(tree, NullTVB, offset, 2, "AndXoffset: %u", AndXoffset);
+    ByteCount = GSHORT(pd, offset);

-      }
+    if (tree) {

-      offset += 2; /* Skip AndXoffset */
+ proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    /* Build display for: Byte Count */
+    offset += 2; /* Skip Byte Count (BCC) */

-    ByteCount = GSHORT(pd, offset);
+    /* Build display for: Buffer Format */
+
+    BufferFormat = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);

    }

-    offset += 2; /* Skip Byte Count */
+    offset += 1; /* Skip Buffer Format */
+
+    /* Build display for: Data Length */

+    DataLength = GSHORT(pd, offset);

-    if (AndXCommand != 0xFF) {
+    if (tree) {

- (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode); + proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);

    }

+    offset += 2; /* Skip Data Length */
+
  }

}

void
-dissect_unlock_bytes_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode) +dissect_locking_andx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
+  proto_tree    *LockType_tree;
+  proto_item    *ti;
+  guint8        LockType;
  guint8        WordCount;
-  guint32       Offset;
-  guint32       Count;
+  guint8        OplockLevel;
+  guint8        AndXReserved;
+  guint8        AndXCommand = 0xFF;
+  guint32       Timeout;
+  guint16       NumberofLocks;
+  guint16       NumberOfUnlocks;
  guint16       FID;
  guint16       ByteCount;
+  guint16       AndXoffset;
+  guint16       AndXOffset = 0;

  if (si.request) {
    /* Request(s) dissect code */
@@ -7359,187 +6542,144 @@

    offset += 1; /* Skip Word Count (WCT) */

-    /* Build display for: FID */
-
-    FID = GSHORT(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
-    }
-
-    offset += 2; /* Skip FID */
-
-    /* Build display for: Count */
-
-    Count = GWORD(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 4, "Count: %u", Count);
-
-    }
-
-    offset += 4; /* Skip Count */
-
-    /* Build display for: Offset */
+    /* Build display for: AndXCommand */

-    Offset = GWORD(pd, offset);
+    AndXCommand = GBYTE(pd, offset);

    if (tree) {

-      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %u", AndXCommand);

    }

-    offset += 4; /* Skip Offset */
+    offset += 1; /* Skip AndXCommand */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: AndXReserved */

-    ByteCount = GSHORT(pd, offset);
+    AndXReserved = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
-
-  } else {
-    /* Response(s) dissect code */
+    offset += 1; /* Skip AndXReserved */

-    /* Build display for: Word Count (WCT) */
+    /* Build display for: AndXOffset */

-    WordCount = GBYTE(pd, offset);
+    AndXOffset = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "AndXOffset: %u", AndXOffset);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 2; /* Skip AndXOffset */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: FID */

-    ByteCount = GSHORT(pd, offset);
+    FID = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
+      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += 2; /* Skip FID */

-  }
+    /* Build display for: Lock Type */

-}
+    LockType = GBYTE(pd, offset);

-void
-dissect_create_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
+    if (tree) {

-{
-  proto_tree    *Attributes_tree;
-  proto_item    *ti;
-  guint8        WordCount;
-  guint8        BufferFormat;
-  guint16       FID;
-  guint16       CreationTime;
-  guint16       ByteCount;
-  guint16       Attributes;
-  const char    *FileName;
+ ti = proto_tree_add_text(tree, NullTVB, offset, 1, "Lock Type: 0x%01x", LockType);
+      LockType_tree = proto_item_add_subtree(ti, ett_smb_lock_type);
+      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x01, 16, "Read-only lock", "Not a Read-only lock"));
+      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x02, 16, "Oplock break notification", "Not an Oplock break notification"));
+      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x04, 16, "Change lock type", "Not a lock type change"));
+      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x08, 16, "Cancel outstanding request", "Dont cancel outstanding request"));
+      proto_tree_add_text(LockType_tree, NullTVB, offset, 1, "%s",
+ decode_boolean_bitfield(LockType, 0x10, 16, "Large file locking format", "Not a large file locking format"));
+
+}

-  if (si.request) {
-    /* Request(s) dissect code */
+    offset += 1; /* Skip Lock Type */

-    /* Build display for: Word Count (WCT) */
+    /* Build display for: OplockLevel */

-    WordCount = GBYTE(pd, offset);
+    OplockLevel = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "OplockLevel: %u", OplockLevel);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 1; /* Skip OplockLevel */

-    /* Build display for: Attributes */
+    /* Build display for: Timeout */

-    Attributes = GSHORT(pd, offset);
+    Timeout = GWORD(pd, offset);

    if (tree) {

- ti = proto_tree_add_text(tree, NullTVB, offset, 2, "Attributes: 0x%02x", Attributes); - Attributes_tree = proto_item_add_subtree(ti, ett_smb_file_attributes);
-      proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x01, 16, "Read-only file", "Not a read-only file"));
-      proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x02, 16, "Hidden file", "Not a hidden file"));
-      proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x04, 16, "System file", "Not a system file"));
-      proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x08, 16, " Volume", "Not a volume"));
-      proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x10, 16, " Directory", "Not a directory"));
-      proto_tree_add_text(Attributes_tree, NullTVB, offset, 2, "%s",
- decode_boolean_bitfield(Attributes, 0x20, 16, " Archived", "Not archived"));
-
-}
+ proto_tree_add_text(tree, NullTVB, offset, 4, "Timeout: %u", Timeout);
+
+    }

-    offset += 2; /* Skip Attributes */
+    offset += 4; /* Skip Timeout */

-    /* Build display for: Creation Time */
+    /* Build display for: Number Of Unlocks */

-    CreationTime = GSHORT(pd, offset);
+    NumberOfUnlocks = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Creation Time: %s", dissect_dos_time(CreationTime)); + proto_tree_add_text(tree, NullTVB, offset, 2, "Number Of Unlocks: %u", NumberOfUnlocks);

    }

-    offset += 2; /* Skip Creation Time */
+    offset += 2; /* Skip Number Of Unlocks */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: Number of Locks */

-    ByteCount = GSHORT(pd, offset);
+    NumberofLocks = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Number of Locks: %u", NumberofLocks);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += 2; /* Skip Number of Locks */

-    /* Build display for: Buffer Format */
+    /* Build display for: Byte Count (BCC) */

-    BufferFormat = GBYTE(pd, offset);
+    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);

    }

-    offset += 1; /* Skip Buffer Format */
-
-    /* Build display for: File Name */
+    offset += 2; /* Skip Byte Count (BCC) */

-    FileName = pd + offset;

-    if (tree) {
+    if (AndXCommand != 0xFF) {

- proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName); + (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);

    }

-    offset += strlen(FileName) + 1; /* Skip File Name */
-
  } else {
    /* Response(s) dissect code */

@@ -7557,31 +6697,63 @@

    if (WordCount > 0) {

-      /* Build display for: FID */
+      /* Build display for: AndXCommand */

-      FID = GSHORT(pd, offset);
+      AndXCommand = GBYTE(pd, offset);

      if (tree) {

-	proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
+	proto_tree_add_text(tree, NullTVB, offset, 1, "AndXCommand: %s",
+ (AndXCommand == 0xFF ? "No further commands" : decode_smb_name(AndXCommand)));

      }

-      offset += 2; /* Skip FID */
-
+      offset += 1; /* Skip AndXCommand */
+
+      /* Build display for: AndXReserved */
+
+      AndXReserved = GBYTE(pd, offset);
+
+      if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 1, "AndXReserved: %u", AndXReserved);
+
+      }
+
+      offset += 1; /* Skip AndXReserved */
+
+      /* Build display for: AndXoffset */
+
+      AndXoffset = GSHORT(pd, offset);
+
+      if (tree) {
+
+ proto_tree_add_text(tree, NullTVB, offset, 2, "AndXoffset: %u", AndXoffset);
+
+      }
+
+      offset += 2; /* Skip AndXoffset */
+
    }
-
-    /* Build display for: Byte Count (BCC) */
+
+    /* Build display for: Byte Count */

    ByteCount = GSHORT(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count: %u", ByteCount);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += 2; /* Skip Byte Count */
+
+
+    if (AndXCommand != 0xFF) {
+
+ (dissect[AndXCommand])(pd, SMB_offset + AndXOffset, fd, parent, tree, si, max_data, SMB_offset, errcode);
+
+    }

  }

@@ -7885,127 +7057,26 @@

proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);

-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    if (WordCount > 0) {
-
-      /* Build display for: FID */
-
-      FID = GSHORT(pd, offset);
-
-      if (tree) {
-
-	proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
-      }
-
-      offset += 2; /* Skip FID */
-
-    }
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-    /* Build display for: Buffer Format */
-
-    BufferFormat = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);
-
-    }
-
-    offset += 1; /* Skip Buffer Format */
-
-    /* Build display for: File Name */
-
-    FileName = pd + offset;
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);
-
-    }
-
-    offset += strlen(FileName) + 1; /* Skip File Name */
-
-  }
-
-}
-
-void
-dissect_close_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8        WordCount;
-  guint16       LastWriteTime;
-  guint16       LastWriteDate;
-  guint16       FID;
-  guint16       ByteCount;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: FID */
-
-    FID = GSHORT(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
-    }
-
-    offset += 2; /* Skip FID */
-
-    /* Build display for: Last Write Time */
-
-    LastWriteTime = GSHORT(pd, offset);
+    }

-    if (tree) {
+    offset += 1; /* Skip Word Count (WCT) */

- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Time: %s", dissect_dos_time(LastWriteTime));
+    if (WordCount > 0) {

-    }
+      /* Build display for: FID */

-    offset += 2; /* Skip Last Write Time */
+      FID = GSHORT(pd, offset);

-    /* Build display for: Last Write Date */
+      if (tree) {

-    LastWriteDate = GSHORT(pd, offset);
+	proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);

-    if (tree) {
+      }

- proto_tree_add_text(tree, NullTVB, offset, 2, "Last Write Date: %s", dissect_dos_date(LastWriteDate));
+      offset += 2; /* Skip FID */

    }

-    offset += 2; /* Skip Last Write Date */
-
    /* Build display for: Byte Count (BCC) */

    ByteCount = GSHORT(pd, offset);
@@ -8018,32 +7089,29 @@

    offset += 2; /* Skip Byte Count (BCC) */

-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
+    /* Build display for: Buffer Format */

-    WordCount = GBYTE(pd, offset);
+    BufferFormat = GBYTE(pd, offset);

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount); + proto_tree_add_text(tree, NullTVB, offset, 1, "Buffer Format: %u", BufferFormat);

    }

-    offset += 1; /* Skip Word Count (WCT) */
+    offset += 1; /* Skip Buffer Format */

-    /* Build display for: Byte Count (BCC) */
+    /* Build display for: File Name */

-    ByteCount = GSHORT(pd, offset);
+    FileName = pd + offset;

    if (tree) {

- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount); + proto_tree_add_text(tree, NullTVB, offset, strlen(FileName) + 1, "File Name: %s", FileName);

    }

-    offset += 2; /* Skip Byte Count (BCC) */
+    offset += strlen(FileName) + 1; /* Skip File Name */

  }

@@ -8430,217 +7498,6 @@
}

void
-dissect_read_file_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)
-
-{
-  guint8        WordCount;
-  guint32       Offset;
-  guint16       Reserved4;
-  guint16       Reserved3;
-  guint16       Reserved2;
-  guint16       Reserved1;
-  guint16       Remaining;
-  guint16       FID;
-  guint16       DataLength;
-  guint16       Count;
-  guint16       ByteCount;
-  guint16       BufferFormat;
-
-  if (si.request) {
-    /* Request(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    /* Build display for: FID */
-
-    FID = GSHORT(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 2, "FID: %u", FID);
-
-    }
-
-    offset += 2; /* Skip FID */
-
-    /* Build display for: Count */
-
-    Count = GSHORT(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
-    }
-
-    offset += 2; /* Skip Count */
-
-    /* Build display for: Offset */
-
-    Offset = GWORD(pd, offset);
-
-    if (tree) {
-
-      proto_tree_add_text(tree, NullTVB, offset, 4, "Offset: %u", Offset);
-
-    }
-
-    offset += 4; /* Skip Offset */
-
-    /* Build display for: Remaining */
-
-    Remaining = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Remaining: %u", Remaining);
-
-    }
-
-    offset += 2; /* Skip Remaining */
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-  } else {
-    /* Response(s) dissect code */
-
-    /* Build display for: Word Count (WCT) */
-
-    WordCount = GBYTE(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 1, "Word Count (WCT): %u", WordCount);
-
-    }
-
-    offset += 1; /* Skip Word Count (WCT) */
-
-    if (WordCount > 0) {
-
-      /* Build display for: Count */
-
-      Count = GSHORT(pd, offset);
-
-      if (tree) {
-
-	proto_tree_add_text(tree, NullTVB, offset, 2, "Count: %u", Count);
-
-      }
-
-      offset += 2; /* Skip Count */
-
-      /* Build display for: Reserved 1 */
-
-      Reserved1 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 1: %u", Reserved1);
-
-      }
-
-      offset += 2; /* Skip Reserved 1 */
-
-      /* Build display for: Reserved 2 */
-
-      Reserved2 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 2: %u", Reserved2);
-
-      }
-
-      offset += 2; /* Skip Reserved 2 */
-
-      /* Build display for: Reserved 3 */
-
-      Reserved3 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 3: %u", Reserved3);
-
-      }
-
-      offset += 2; /* Skip Reserved 3 */
-
-      /* Build display for: Reserved 4 */
-
-      Reserved4 = GSHORT(pd, offset);
-
-      if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Reserved 4: %u", Reserved4);
-
-      }
-
-      offset += 2; /* Skip Reserved 4 */
-
-    }
-
-    /* Build display for: Byte Count (BCC) */
-
-    ByteCount = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Byte Count (BCC): %u", ByteCount);
-
-    }
-
-    offset += 2; /* Skip Byte Count (BCC) */
-
-    /* Build display for: Buffer Format */
-
-    BufferFormat = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Buffer Format: %u", BufferFormat);
-
-    }
-
-    offset += 2; /* Skip Buffer Format */
-
-    /* Build display for: Data Length */
-
-    DataLength = GSHORT(pd, offset);
-
-    if (tree) {
-
- proto_tree_add_text(tree, NullTVB, offset, 2, "Data Length: %u", DataLength);
-
-    }
-
-    offset += 2; /* Skip Data Length */
-
-  }
-
-}
-
-void
dissect_write_mpx_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *parent, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode)

{
@@ -10474,27 +9331,26 @@



-
-
+/*xxxxx*/
static void (*dissect[256])(const u_char *, int, frame_data *, proto_tree *, proto_tree *, struct smb_info, int, int, int) = {

-  dissect_createdir_smb,    /* unknown SMB 0x00 */
-  dissect_deletedir_smb,    /* unknown SMB 0x01 */
+  dissect_unknown_smb,/*0x00*/
+  dissect_unknown_smb,
  dissect_unknown_smb,      /* SMBopen open a file */
-  dissect_create_file_smb,  /* SMBcreate create a file */
-  dissect_close_smb,        /* SMBclose close a file */
-  dissect_flush_file_smb,   /* SMBflush flush a file */
-  dissect_delete_file_smb,  /* SMBunlink delete a file */
-  dissect_rename_file_smb,  /* SMBmv rename a file */
  dissect_unknown_smb,
-  dissect_set_file_attr_smb,/* SMBsetatr set file attributes */
-  dissect_read_file_smb,    /* SMBread read from a file */
-  dissect_write_file_smb,   /* SMBwrite write to a file */
-  dissect_lock_bytes_smb,   /* SMBlock lock a byte range */
-  dissect_unlock_bytes_smb, /* SMBunlock unlock a byte range */
+  dissect_unknown_smb,
+  dissect_unknown_smb,/*0x05*/
+  dissect_unknown_smb,
+  dissect_unknown_smb,
+  dissect_unknown_smb,
+  dissect_unknown_smb,
+  dissect_unknown_smb,/*0x0a*/
+  dissect_unknown_smb,
+  dissect_unknown_smb,
+  dissect_unknown_smb,
  dissect_create_temporary_file_smb,/* SMBctemp create a temporary file */
  dissect_unknown_smb,      /* SMBmknew make a new file */
-  dissect_checkdir_smb,     /* SMBchkpth check a directory path */
+  dissect_unknown_smb,
  dissect_process_exit_smb,      /* SMBexit process exit */
  dissect_unknown_smb,      /* SMBlseek seek */
  dissect_lock_and_read_smb,/* SMBlockread Lock a range and read it */
@@ -11341,6 +10197,10 @@
		{ "Key Length", "smb.encryption.key.length", FT_UINT16, BASE_DEC,
NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},

+	  { &hf_file_data,
+		{ "File Data", "smb.file.data", FT_BYTES, BASE_HEX,
+		NULL, 0, "Data read/written to the file", HFILL }},
+
	  { &hf_reserved,
		{ "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
		NULL, 0, "Reserved (MUST be zero)", HFILL }},
@@ -11449,6 +10309,14 @@
		{ "Security Blob", "smb.security.blob", FT_BYTES, BASE_HEX,
		NULL, 0, "Security blob", HFILL }},

+	  { &hf_dir_name,
+		{ "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
+		NULL, 0, "SMB Directory Name", HFILL }},
+
+	  { &hf_old_file_name,
+		{ "Old File Name", "smb.old_file_name", FT_STRING, BASE_NONE,
+		NULL, 0, "SMB Old File Name", HFILL }},
+
	  { &hf_file_name,
		{ "File Name", "smb.file_name", FT_STRING, BASE_NONE,
		NULL, 0, "SMB File Name", HFILL }},
@@ -11493,6 +10361,41 @@
		{ "File Size", "smb.file.size", FT_UINT32, BASE_DEC,
		NULL, 0, "File Size", HFILL }},

+	  { &hf_create_date,
+		{ "Created", "smb.create.date", FT_ABSOLUTE_TIME, BASE_NONE,
+		NULL, 0, "Creation Time", HFILL }},
+
+	  { &hf_create_dos_date,
+		{ "Created Date", "smb.create.dos.date", FT_UINT16, BASE_HEX,
+		NULL, 0, "Creation Date, SMBU format", HFILL }},
+
+	  { &hf_create_dos_time,
+		{ "Created Time", "smb.create.dos.time", FT_UINT16, BASE_HEX,
+		NULL, 0, "Creation Time, SMBU format", HFILL }},
+
+	  { &hf_fid,
+		{ "FID", "smb.fid", FT_UINT16, BASE_HEX,
+		NULL, 0, "FID: FileID", HFILL }},
+
+	  { &hf_rw_count,
+		{ "Count", "smb.file.count", FT_UINT16, BASE_DEC,
+		NULL, 0, "Count, number of bytes to read/write", HFILL }},
+
+	  { &hf_file_offset,
+		{ "Offset", "smb.file.offset", FT_UINT32, BASE_DEC,
+		NULL, 0, "Offset in file to read/write", HFILL }},
+
+	  { &hf_file_remaining,
+		{ "Remaining", "smb.file.remaining", FT_UINT16, BASE_DEC,
+		NULL, 0, "Estimate of bytes to read if nonzero", HFILL }},
+
+	  { &hf_data_len,
+		{ "Data Len", "smb.file.data_len", FT_UINT16, BASE_DEC,
+		NULL, 0, "Length of data", HFILL }},
+
+	  { &hf_lock_count,
+		{ "Count", "smb.lock.count", FT_UINT32, BASE_DEC,
+		NULL, 0, "Lock Count, number of bytes to lock/unlock", HFILL }},

/*xxxxx*/
	};