No need to put ", N byte{s} at offset O" into the Info column twice;
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id: packet-smb.c,v 1.214 2002/03/09 02:12:47 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  * 
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
37 #endif
38
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
41 #endif
42
43 #include <time.h>
44 #include <string.h>
45 #include <glib.h>
46 #include <ctype.h>
47 #include <epan/packet.h>
48 #include <epan/conversation.h>
49 #include "smb.h"
50 #include "alignment.h"
51 #include <epan/strutil.h>
52 #include "prefs.h"
53 #include "reassemble.h"
54
55 #include "packet-smb-mailslot.h"
56 #include "packet-smb-pipe.h"
57
58 /*
59  * Various specifications and documents about SMB can be found in
60  *
61  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
62  *
63  * and a CIFS draft from the Storage Networking Industry Association
64  * can be found on a link from the page at
65  *
66  *      http://www.snia.org/English/Work_Groups/NAS/CIFS/WG_CIFS_Docs.html
67  *
68  * (it supercedes the document at
69  *
70  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
71  *
72  * ).
73  *
74  * There are also some Open Group publications documenting CIFS for sale;
75  * catalog entries for them are at:
76  *
77  *      http://www.opengroup.org/products/publications/catalog/c209.htm
78  *
79  *      http://www.opengroup.org/products/publications/catalog/c195.htm
80  *
81  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
82  * can be found at
83  *
84  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
85  *
86  * (or, presumably a similar path under the Samba mirrors).  As the
87  * ".doc" indicates, it's a Word document.  Some of the specs from the
88  * Microsoft FTP site can be found in the
89  *
90  *      http://www.samba.org/samba/ftp/specs/
91  *
92  * directory as well.
93  *
94  * Beware - these specs may have errors.
95  */
96 static int proto_smb = -1;
97 static int hf_smb_cmd = -1;
98 static int hf_smb_pid = -1;
99 static int hf_smb_tid = -1;
100 static int hf_smb_uid = -1;
101 static int hf_smb_mid = -1;
102 static int hf_smb_response_to = -1;
103 static int hf_smb_response_in = -1;
104 static int hf_smb_continuation_to = -1;
105 static int hf_smb_nt_status = -1;
106 static int hf_smb_error_class = -1;
107 static int hf_smb_error_code = -1;
108 static int hf_smb_reserved = -1;
109 static int hf_smb_flags_lock = -1;
110 static int hf_smb_flags_receive_buffer = -1;
111 static int hf_smb_flags_caseless = -1;
112 static int hf_smb_flags_canon = -1;
113 static int hf_smb_flags_oplock = -1;
114 static int hf_smb_flags_notify = -1;
115 static int hf_smb_flags_response = -1;
116 static int hf_smb_flags2_long_names_allowed = -1;
117 static int hf_smb_flags2_ea = -1;
118 static int hf_smb_flags2_sec_sig = -1;
119 static int hf_smb_flags2_long_names_used = -1;
120 static int hf_smb_flags2_esn = -1;
121 static int hf_smb_flags2_dfs = -1;
122 static int hf_smb_flags2_roe = -1;
123 static int hf_smb_flags2_nt_error = -1;
124 static int hf_smb_flags2_string = -1;
125 static int hf_smb_word_count = -1;
126 static int hf_smb_byte_count = -1;
127 static int hf_smb_buffer_format = -1;
128 static int hf_smb_dialect_name = -1;
129 static int hf_smb_dialect_index = -1;
130 static int hf_smb_max_trans_buf_size = -1;
131 static int hf_smb_max_mpx_count = -1;
132 static int hf_smb_max_vcs_num = -1;
133 static int hf_smb_session_key = -1;
134 static int hf_smb_server_timezone = -1;
135 static int hf_smb_encryption_key_length = -1;
136 static int hf_smb_encryption_key = -1;
137 static int hf_smb_primary_domain = -1;
138 static int hf_smb_max_raw_buf_size = -1;
139 static int hf_smb_server_guid = -1;
140 static int hf_smb_security_blob_len = -1;
141 static int hf_smb_security_blob = -1;
142 static int hf_smb_sm_mode16 = -1;
143 static int hf_smb_sm_password16 = -1;
144 static int hf_smb_sm_mode = -1;
145 static int hf_smb_sm_password = -1;
146 static int hf_smb_sm_signatures = -1;
147 static int hf_smb_sm_sig_required = -1;
148 static int hf_smb_rm_read = -1;
149 static int hf_smb_rm_write = -1;
150 static int hf_smb_server_date_time = -1;
151 static int hf_smb_server_smb_date = -1;
152 static int hf_smb_server_smb_time = -1;
153 static int hf_smb_server_cap_raw_mode = -1;
154 static int hf_smb_server_cap_mpx_mode = -1;
155 static int hf_smb_server_cap_unicode = -1;
156 static int hf_smb_server_cap_large_files = -1;
157 static int hf_smb_server_cap_nt_smbs = -1;
158 static int hf_smb_server_cap_rpc_remote_apis = -1;
159 static int hf_smb_server_cap_nt_status = -1;
160 static int hf_smb_server_cap_level_ii_oplocks = -1;
161 static int hf_smb_server_cap_lock_and_read = -1;
162 static int hf_smb_server_cap_nt_find = -1;
163 static int hf_smb_server_cap_dfs = -1;
164 static int hf_smb_server_cap_infolevel_passthru = -1;
165 static int hf_smb_server_cap_large_readx = -1;
166 static int hf_smb_server_cap_large_writex = -1;
167 static int hf_smb_server_cap_unix = -1;
168 static int hf_smb_server_cap_reserved = -1;
169 static int hf_smb_server_cap_bulk_transfer = -1;
170 static int hf_smb_server_cap_compressed_data = -1;
171 static int hf_smb_server_cap_extended_security = -1;
172 static int hf_smb_system_time = -1;
173 static int hf_smb_unknown = -1;
174 static int hf_smb_dir_name = -1;
175 static int hf_smb_echo_count = -1;
176 static int hf_smb_echo_data = -1;
177 static int hf_smb_echo_seq_num = -1;
178 static int hf_smb_max_buf_size = -1;
179 static int hf_smb_password = -1;
180 static int hf_smb_password_len = -1;
181 static int hf_smb_ansi_password = -1;
182 static int hf_smb_ansi_password_len = -1;
183 static int hf_smb_unicode_password = -1;
184 static int hf_smb_unicode_password_len = -1;
185 static int hf_smb_path = -1;
186 static int hf_smb_service = -1;
187 static int hf_smb_move_flags_file = -1;
188 static int hf_smb_move_flags_dir = -1;
189 static int hf_smb_move_flags_verify = -1;
190 static int hf_smb_move_files_moved = -1;
191 static int hf_smb_count = -1;
192 static int hf_smb_file_name = -1;
193 static int hf_smb_open_function_open = -1;
194 static int hf_smb_open_function_create = -1;
195 static int hf_smb_fid = -1;
196 static int hf_smb_file_attr_read_only_16bit = -1;
197 static int hf_smb_file_attr_read_only_8bit = -1;
198 static int hf_smb_file_attr_hidden_16bit = -1;
199 static int hf_smb_file_attr_hidden_8bit = -1;
200 static int hf_smb_file_attr_system_16bit = -1;
201 static int hf_smb_file_attr_system_8bit = -1;
202 static int hf_smb_file_attr_volume_16bit = -1;
203 static int hf_smb_file_attr_volume_8bit = -1;
204 static int hf_smb_file_attr_directory_16bit = -1;
205 static int hf_smb_file_attr_directory_8bit = -1;
206 static int hf_smb_file_attr_archive_16bit = -1;
207 static int hf_smb_file_attr_archive_8bit = -1;
208 static int hf_smb_file_attr_device = -1;
209 static int hf_smb_file_attr_normal = -1;
210 static int hf_smb_file_attr_temporary = -1;
211 static int hf_smb_file_attr_sparse = -1;
212 static int hf_smb_file_attr_reparse = -1;
213 static int hf_smb_file_attr_compressed = -1;
214 static int hf_smb_file_attr_offline = -1;
215 static int hf_smb_file_attr_not_content_indexed = -1;
216 static int hf_smb_file_attr_encrypted = -1;
217 static int hf_smb_file_size = -1;
218 static int hf_smb_search_attribute_read_only = -1;
219 static int hf_smb_search_attribute_hidden = -1;
220 static int hf_smb_search_attribute_system = -1;
221 static int hf_smb_search_attribute_volume = -1;
222 static int hf_smb_search_attribute_directory = -1;
223 static int hf_smb_search_attribute_archive = -1;
224 static int hf_smb_access_mode = -1;
225 static int hf_smb_access_sharing = -1;
226 static int hf_smb_access_locality = -1;
227 static int hf_smb_access_caching = -1;
228 static int hf_smb_access_writetru = -1;
229 static int hf_smb_create_time = -1;
230 static int hf_smb_create_dos_date = -1;
231 static int hf_smb_create_dos_time = -1;
232 static int hf_smb_last_write_time = -1;
233 static int hf_smb_last_write_dos_date = -1;
234 static int hf_smb_last_write_dos_time = -1;
235 static int hf_smb_access_time = -1;
236 static int hf_smb_access_dos_date = -1;
237 static int hf_smb_access_dos_time = -1;
238 static int hf_smb_old_file_name = -1;
239 static int hf_smb_offset = -1;
240 static int hf_smb_remaining = -1;
241 static int hf_smb_padding = -1;
242 static int hf_smb_file_data = -1;
243 static int hf_smb_total_data_len = -1;
244 static int hf_smb_data_len = -1;
245 static int hf_smb_seek_mode = -1;
246 static int hf_smb_data_size = -1;
247 static int hf_smb_alloc_size = -1;
248 static int hf_smb_alloc_size64 = -1;
249 static int hf_smb_max_count = -1;
250 static int hf_smb_min_count = -1;
251 static int hf_smb_timeout = -1;
252 static int hf_smb_high_offset = -1;
253 static int hf_smb_units = -1;
254 static int hf_smb_bpu = -1;
255 static int hf_smb_blocksize = -1;
256 static int hf_smb_freeunits = -1;
257 static int hf_smb_data_offset = -1;
258 static int hf_smb_dcm = -1;
259 static int hf_smb_request_mask = -1;
260 static int hf_smb_response_mask = -1;
261 static int hf_smb_sid = -1;
262 static int hf_smb_write_mode_write_through = -1;
263 static int hf_smb_write_mode_return_remaining = -1;
264 static int hf_smb_write_mode_raw = -1;
265 static int hf_smb_write_mode_message_start = -1;
266 static int hf_smb_write_mode_connectionless = -1;
267 static int hf_smb_resume_key_len = -1;
268 static int hf_smb_resume_server_cookie = -1;
269 static int hf_smb_resume_client_cookie = -1;
270 static int hf_smb_andxoffset = -1;
271 static int hf_smb_lock_type_large = -1;
272 static int hf_smb_lock_type_cancel = -1;
273 static int hf_smb_lock_type_change = -1;
274 static int hf_smb_lock_type_oplock = -1;
275 static int hf_smb_lock_type_shared = -1;
276 static int hf_smb_locking_ol = -1;
277 static int hf_smb_number_of_locks = -1;
278 static int hf_smb_number_of_unlocks = -1;
279 static int hf_smb_lock_long_offset = -1;
280 static int hf_smb_lock_long_length = -1;
281 static int hf_smb_file_type = -1;
282 static int hf_smb_ipc_state_nonblocking = -1;
283 static int hf_smb_ipc_state_endpoint = -1;
284 static int hf_smb_ipc_state_pipe_type = -1;
285 static int hf_smb_ipc_state_read_mode = -1;
286 static int hf_smb_ipc_state_icount = -1;
287 static int hf_smb_server_fid = -1;
288 static int hf_smb_open_flags_add_info = -1;
289 static int hf_smb_open_flags_ex_oplock = -1;
290 static int hf_smb_open_flags_batch_oplock = -1;
291 static int hf_smb_open_flags_ealen = -1;
292 static int hf_smb_open_action_open = -1;
293 static int hf_smb_open_action_lock = -1;
294 static int hf_smb_vc_num = -1;
295 static int hf_smb_account = -1;
296 static int hf_smb_os = -1;
297 static int hf_smb_lanman = -1;
298 static int hf_smb_setup_action_guest = -1;
299 static int hf_smb_fs = -1;
300 static int hf_smb_connect_flags_dtid = -1;
301 static int hf_smb_connect_support_search = -1;
302 static int hf_smb_connect_support_in_dfs = -1;
303 static int hf_smb_max_setup_count = -1;
304 static int hf_smb_total_param_count = -1;
305 static int hf_smb_total_data_count = -1;
306 static int hf_smb_max_param_count = -1;
307 static int hf_smb_max_data_count = -1;
308 static int hf_smb_param_disp16 = -1;
309 static int hf_smb_param_count16 = -1;
310 static int hf_smb_param_offset16 = -1;
311 static int hf_smb_param_disp32 = -1;
312 static int hf_smb_param_count32 = -1;
313 static int hf_smb_param_offset32 = -1;
314 static int hf_smb_data_disp16 = -1;
315 static int hf_smb_data_count16 = -1;
316 static int hf_smb_data_offset16 = -1;
317 static int hf_smb_data_disp32 = -1;
318 static int hf_smb_data_count32 = -1;
319 static int hf_smb_data_offset32 = -1;
320 static int hf_smb_setup_count = -1;
321 static int hf_smb_nt_trans_subcmd = -1;
322 static int hf_smb_nt_ioctl_function_code = -1;
323 static int hf_smb_nt_ioctl_isfsctl = -1;
324 static int hf_smb_nt_ioctl_flags_root_handle = -1;
325 static int hf_smb_nt_ioctl_data = -1;
326 static int hf_smb_nt_security_information = -1;
327 static int hf_smb_nt_notify_action = -1;
328 static int hf_smb_nt_notify_watch_tree = -1;
329 static int hf_smb_nt_notify_stream_write = -1;
330 static int hf_smb_nt_notify_stream_size = -1;
331 static int hf_smb_nt_notify_stream_name = -1;
332 static int hf_smb_nt_notify_security = -1;
333 static int hf_smb_nt_notify_ea = -1;
334 static int hf_smb_nt_notify_creation = -1;
335 static int hf_smb_nt_notify_last_access = -1;
336 static int hf_smb_nt_notify_last_write = -1;
337 static int hf_smb_nt_notify_size = -1;
338 static int hf_smb_nt_notify_attributes = -1;
339 static int hf_smb_nt_notify_dir_name = -1;
340 static int hf_smb_nt_notify_file_name = -1;
341 static int hf_smb_root_dir_fid = -1;
342 static int hf_smb_nt_create_disposition = -1;
343 static int hf_smb_sd_length = -1;
344 static int hf_smb_ea_length = -1;
345 static int hf_smb_file_name_len = -1;
346 static int hf_smb_nt_impersonation_level = -1;
347 static int hf_smb_nt_security_flags_context_tracking = -1;
348 static int hf_smb_nt_security_flags_effective_only = -1;
349 static int hf_smb_nt_access_mask_generic_read = -1;
350 static int hf_smb_nt_access_mask_generic_write = -1;
351 static int hf_smb_nt_access_mask_generic_execute = -1;
352 static int hf_smb_nt_access_mask_generic_all = -1;
353 static int hf_smb_nt_access_mask_maximum_allowed = -1;
354 static int hf_smb_nt_access_mask_system_security = -1;
355 static int hf_smb_nt_access_mask_synchronize = -1;
356 static int hf_smb_nt_access_mask_write_owner = -1;
357 static int hf_smb_nt_access_mask_write_dac = -1;
358 static int hf_smb_nt_access_mask_read_control = -1;
359 static int hf_smb_nt_access_mask_delete = -1;
360 static int hf_smb_nt_access_mask_write_attributes = -1;
361 static int hf_smb_nt_access_mask_read_attributes = -1;
362 static int hf_smb_nt_access_mask_delete_child = -1;
363 static int hf_smb_nt_access_mask_execute = -1;
364 static int hf_smb_nt_access_mask_write_ea = -1;
365 static int hf_smb_nt_access_mask_read_ea = -1;
366 static int hf_smb_nt_access_mask_append = -1;
367 static int hf_smb_nt_access_mask_write = -1;
368 static int hf_smb_nt_access_mask_read = -1;
369 static int hf_smb_nt_create_bits_oplock = -1;
370 static int hf_smb_nt_create_bits_boplock = -1;
371 static int hf_smb_nt_create_bits_dir = -1;
372 static int hf_smb_nt_create_options_directory_file = -1;
373 static int hf_smb_nt_create_options_write_through = -1;
374 static int hf_smb_nt_create_options_sequential_only = -1;
375 static int hf_smb_nt_create_options_sync_io_alert = -1;
376 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
377 static int hf_smb_nt_create_options_non_directory_file = -1;
378 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
379 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
380 static int hf_smb_nt_create_options_random_access = -1;
381 static int hf_smb_nt_create_options_delete_on_close = -1;
382 static int hf_smb_nt_share_access_read = -1;
383 static int hf_smb_nt_share_access_write = -1;
384 static int hf_smb_nt_share_access_delete = -1;
385 static int hf_smb_file_eattr_read_only = -1;
386 static int hf_smb_file_eattr_hidden = -1;
387 static int hf_smb_file_eattr_system = -1;
388 static int hf_smb_file_eattr_volume = -1;
389 static int hf_smb_file_eattr_directory = -1;
390 static int hf_smb_file_eattr_archive = -1;
391 static int hf_smb_file_eattr_device = -1;
392 static int hf_smb_file_eattr_normal = -1;
393 static int hf_smb_file_eattr_temporary = -1;
394 static int hf_smb_file_eattr_sparse = -1;
395 static int hf_smb_file_eattr_reparse = -1;
396 static int hf_smb_file_eattr_compressed = -1;
397 static int hf_smb_file_eattr_offline = -1;
398 static int hf_smb_file_eattr_not_content_indexed = -1;
399 static int hf_smb_file_eattr_encrypted = -1;
400 static int hf_smb_file_eattr_write_through = -1;
401 static int hf_smb_file_eattr_no_buffering = -1;
402 static int hf_smb_file_eattr_random_access = -1;
403 static int hf_smb_file_eattr_sequential_scan = -1;
404 static int hf_smb_file_eattr_delete_on_close = -1;
405 static int hf_smb_file_eattr_backup_semantics = -1;
406 static int hf_smb_file_eattr_posix_semantics = -1;
407 static int hf_smb_sec_desc_len = -1;
408 static int hf_smb_sec_desc_revision = -1;
409 static int hf_smb_sec_desc_type_owner_defaulted = -1;
410 static int hf_smb_sec_desc_type_group_defaulted = -1;
411 static int hf_smb_sec_desc_type_dacl_present = -1;
412 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
413 static int hf_smb_sec_desc_type_sacl_present = -1;
414 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
415 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
416 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
417 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
418 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
419 static int hf_smb_sec_desc_type_dacl_protected = -1;
420 static int hf_smb_sec_desc_type_sacl_protected = -1;
421 static int hf_smb_sec_desc_type_self_relative = -1;
422 static int hf_smb_sid_revision = -1;
423 static int hf_smb_sid_num_auth = -1;
424 static int hf_smb_acl_revision = -1;
425 static int hf_smb_acl_size = -1;
426 static int hf_smb_acl_num_aces = -1;
427 static int hf_smb_ace_type = -1;
428 static int hf_smb_ace_size = -1;
429 static int hf_smb_ace_flags_object_inherit = -1;
430 static int hf_smb_ace_flags_container_inherit = -1;
431 static int hf_smb_ace_flags_non_propagate_inherit = -1;
432 static int hf_smb_ace_flags_inherit_only = -1;
433 static int hf_smb_ace_flags_inherited_ace = -1;
434 static int hf_smb_ace_flags_successful_access = -1;
435 static int hf_smb_ace_flags_failed_access = -1;
436 static int hf_smb_nt_qsd_owner = -1;
437 static int hf_smb_nt_qsd_group = -1;
438 static int hf_smb_nt_qsd_dacl = -1;
439 static int hf_smb_nt_qsd_sacl = -1;
440 static int hf_smb_extended_attributes = -1;
441 static int hf_smb_oplock_level = -1;
442 static int hf_smb_create_action = -1;
443 static int hf_smb_ea_error_offset = -1;
444 static int hf_smb_end_of_file = -1;
445 static int hf_smb_device_type = -1;
446 static int hf_smb_is_directory = -1;
447 static int hf_smb_next_entry_offset = -1;
448 static int hf_smb_change_time = -1;
449 static int hf_smb_setup_len = -1;
450 static int hf_smb_print_mode = -1;
451 static int hf_smb_print_identifier = -1;
452 static int hf_smb_restart_index = -1;
453 static int hf_smb_print_queue_date = -1;
454 static int hf_smb_print_queue_dos_date = -1;
455 static int hf_smb_print_queue_dos_time = -1;
456 static int hf_smb_print_status = -1;
457 static int hf_smb_print_spool_file_number = -1;
458 static int hf_smb_print_spool_file_size = -1;
459 static int hf_smb_print_spool_file_name = -1;
460 static int hf_smb_start_index = -1;
461 static int hf_smb_cancel_to = -1;
462 static int hf_smb_trans2_subcmd = -1;
463 static int hf_smb_trans_name = -1;
464 static int hf_smb_transaction_flags_dtid = -1;
465 static int hf_smb_transaction_flags_owt = -1;
466 static int hf_smb_search_count = -1;
467 static int hf_smb_search_pattern = -1;
468 static int hf_smb_ff2_backup = -1;
469 static int hf_smb_ff2_continue = -1;
470 static int hf_smb_ff2_resume = -1;
471 static int hf_smb_ff2_close_eos = -1;
472 static int hf_smb_ff2_close = -1;
473 static int hf_smb_ff2_information_level = -1;
474 static int hf_smb_qpi_loi = -1;
475 static int hf_smb_storage_type = -1;
476 static int hf_smb_resume = -1;
477 static int hf_smb_max_referral_level = -1;
478 static int hf_smb_qfsi_information_level = -1;
479 static int hf_smb_ea_size = -1;
480 static int hf_smb_list_length = -1;
481 static int hf_smb_number_of_links = -1;
482 static int hf_smb_delete_pending = -1;
483 static int hf_smb_index_number = -1;
484 static int hf_smb_current_offset = -1;
485 static int hf_smb_t2_alignment = -1;
486 static int hf_smb_t2_stream_name_length = -1;
487 static int hf_smb_t2_stream_size = -1;
488 static int hf_smb_t2_stream_name = -1;
489 static int hf_smb_t2_compressed_file_size = -1;
490 static int hf_smb_t2_compressed_format = -1;
491 static int hf_smb_t2_compressed_unit_shift = -1;
492 static int hf_smb_t2_compressed_chunk_shift = -1;
493 static int hf_smb_t2_compressed_cluster_shift = -1;
494 static int hf_smb_dfs_path_consumed = -1;
495 static int hf_smb_dfs_num_referrals = -1;
496 static int hf_smb_get_dfs_server_hold_storage = -1;
497 static int hf_smb_get_dfs_fielding = -1;
498 static int hf_smb_dfs_referral_version = -1;
499 static int hf_smb_dfs_referral_size = -1;
500 static int hf_smb_dfs_referral_server_type = -1;
501 static int hf_smb_dfs_referral_flags_strip = -1;
502 static int hf_smb_dfs_referral_node_offset = -1;
503 static int hf_smb_dfs_referral_node = -1;
504 static int hf_smb_dfs_referral_proximity = -1;
505 static int hf_smb_dfs_referral_ttl = -1;
506 static int hf_smb_dfs_referral_path_offset = -1;
507 static int hf_smb_dfs_referral_path = -1;
508 static int hf_smb_dfs_referral_alt_path_offset = -1;
509 static int hf_smb_dfs_referral_alt_path = -1;
510 static int hf_smb_end_of_search = -1;
511 static int hf_smb_last_name_offset = -1;
512 static int hf_smb_file_index = -1;
513 static int hf_smb_short_file_name = -1;
514 static int hf_smb_short_file_name_len = -1;
515 static int hf_smb_fs_id = -1;
516 static int hf_smb_sector_unit = -1;
517 static int hf_smb_fs_units = -1;
518 static int hf_smb_fs_sector = -1;
519 static int hf_smb_avail_units = -1;
520 static int hf_smb_volume_serial_num = -1;
521 static int hf_smb_volume_label_len = -1;
522 static int hf_smb_volume_label = -1;
523 static int hf_smb_free_alloc_units64 = -1;
524 static int hf_smb_max_name_len = -1;
525 static int hf_smb_fs_name_len = -1;
526 static int hf_smb_fs_name = -1;
527 static int hf_smb_device_char_removable = -1;
528 static int hf_smb_device_char_read_only = -1;
529 static int hf_smb_device_char_floppy = -1;
530 static int hf_smb_device_char_write_once = -1;
531 static int hf_smb_device_char_remote = -1;
532 static int hf_smb_device_char_mounted = -1;
533 static int hf_smb_device_char_virtual = -1;
534 static int hf_smb_fs_attr_css = -1;
535 static int hf_smb_fs_attr_cpn = -1;
536 static int hf_smb_fs_attr_pacls = -1;
537 static int hf_smb_fs_attr_fc = -1;
538 static int hf_smb_fs_attr_vq = -1;
539 static int hf_smb_fs_attr_dim = -1;
540 static int hf_smb_fs_attr_vic = -1;
541 static int hf_smb_quota_flags_deny_disk = -1;
542 static int hf_smb_quota_flags_log_limit = -1;
543 static int hf_smb_quota_flags_log_warning = -1;
544
545 static gint ett_smb = -1;
546 static gint ett_smb_hdr = -1;
547 static gint ett_smb_command = -1;
548 static gint ett_smb_fileattributes = -1;
549 static gint ett_smb_capabilities = -1;
550 static gint ett_smb_aflags = -1;
551 static gint ett_smb_dialect = -1;
552 static gint ett_smb_dialects = -1;
553 static gint ett_smb_mode = -1;
554 static gint ett_smb_rawmode = -1;
555 static gint ett_smb_flags = -1;
556 static gint ett_smb_flags2 = -1;
557 static gint ett_smb_desiredaccess = -1;
558 static gint ett_smb_search = -1;
559 static gint ett_smb_file = -1;
560 static gint ett_smb_openfunction = -1;
561 static gint ett_smb_filetype = -1;
562 static gint ett_smb_openaction = -1;
563 static gint ett_smb_writemode = -1;
564 static gint ett_smb_lock_type = -1;
565 static gint ett_smb_ssetupandxaction = -1;
566 static gint ett_smb_optionsup = -1;
567 static gint ett_smb_time_date = -1;
568 static gint ett_smb_move_flags = -1;
569 static gint ett_smb_file_attributes = -1;
570 static gint ett_smb_search_resume_key = -1;
571 static gint ett_smb_search_dir_info = -1;
572 static gint ett_smb_unlocks = -1;
573 static gint ett_smb_unlock = -1;
574 static gint ett_smb_locks = -1;
575 static gint ett_smb_lock = -1;
576 static gint ett_smb_open_flags = -1;
577 static gint ett_smb_ipc_state = -1;
578 static gint ett_smb_open_action = -1;
579 static gint ett_smb_setup_action = -1;
580 static gint ett_smb_connect_flags = -1;
581 static gint ett_smb_connect_support_bits = -1;
582 static gint ett_smb_nt_access_mask = -1;
583 static gint ett_smb_nt_create_bits = -1;
584 static gint ett_smb_nt_create_options = -1;
585 static gint ett_smb_nt_share_access = -1;
586 static gint ett_smb_nt_security_flags = -1;
587 static gint ett_smb_nt_trans_setup = -1;
588 static gint ett_smb_nt_notify_completion_filter = -1;
589 static gint ett_smb_nt_ioctl_flags = -1;
590 static gint ett_smb_security_information_mask = -1;
591 static gint ett_smb_print_queue_entry = -1;
592 static gint ett_smb_transaction_flags = -1;
593 static gint ett_smb_transaction_params = -1;
594 static gint ett_smb_find_first2_flags = -1;
595 static gint ett_smb_transaction_data = -1;
596 static gint ett_smb_stream_info = -1;
597 static gint ett_smb_dfs_referrals = -1;
598 static gint ett_smb_dfs_referral = -1;
599 static gint ett_smb_dfs_referral_flags = -1;
600 static gint ett_smb_get_dfs_flags = -1;
601 static gint ett_smb_ff2_data = -1;
602 static gint ett_smb_device_characteristics = -1;
603 static gint ett_smb_fs_attributes = -1;
604 static gint ett_smb_segments = -1;
605 static gint ett_smb_sec_desc = -1;
606 static gint ett_smb_sid = -1;
607 static gint ett_smb_acl = -1;
608 static gint ett_smb_ace = -1;
609 static gint ett_smb_ace_flags = -1;
610 static gint ett_smb_sec_desc_type = -1;
611 static gint ett_smb_quotaflags = -1;
612
613 proto_tree *top_tree=NULL;     /* ugly */
614
615 static char *decode_smb_name(unsigned char);
616 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
617 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
618     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
619     gboolean exactlen, guint16 *bcp);
620
621 /*
622  * Macros for use in the main dissector routines for an SMB.
623  */
624
625 #define WORD_COUNT      \
626         /* Word Count */                                \
627         wc = tvb_get_guint8(tvb, offset);               \
628         proto_tree_add_uint(tree, hf_smb_word_count,    \
629                 tvb, offset, 1, wc);                    \
630         offset += 1;                                    \
631         if(wc==0) goto bytecount;
632
633 #define BYTE_COUNT      \
634         bytecount:                                      \
635         bc = tvb_get_letohs(tvb, offset);               \
636         proto_tree_add_uint(tree, hf_smb_byte_count,    \
637                         tvb, offset, 2, bc);            \
638         offset += 2;                                    \
639         if(bc==0) goto endofcommand;
640
641 #define CHECK_BYTE_COUNT(len)   \
642         if (bc < len) goto endofcommand;
643
644 #define COUNT_BYTES(len)   {\
645         int tmp;            \
646         tmp=len;            \
647         offset += tmp;      \
648         bc -= tmp;          \
649         }
650
651 #define END_OF_SMB      \
652         if (bc != 0) { \
653                 proto_tree_add_text(tree, tvb, offset, bc, \
654                     "Extra byte parameters");           \
655                 offset += bc;                           \
656         }                                               \
657         endofcommand:
658
659 /*
660  * Macros for use in routines called by them.
661  */
662 #define CHECK_BYTE_COUNT_SUBR(len)      \
663         if (*bcp < len) {               \
664                 *trunc = TRUE;          \
665                 return offset;          \
666         }
667
668 #define CHECK_STRING_SUBR(fn)   \
669         if (fn == NULL) {       \
670                 *trunc = TRUE;  \
671                 return offset;  \
672         }
673
674 #define COUNT_BYTES_SUBR(len)   \
675         offset += len;          \
676         *bcp -= len;
677
678 /*
679  * Macros for use when dissecting transaction parameters and data
680  */
681 #define CHECK_BYTE_COUNT_TRANS(len)     \
682         if (bc < len) return offset;
683
684 #define CHECK_STRING_TRANS(fn)  \
685         if (fn == NULL) return offset;
686
687 #define COUNT_BYTES_TRANS(len)  \
688         offset += len;          \
689         bc -= len;
690
691 /*
692  * Macros for use in subrroutines dissecting transaction parameters or data
693  */
694 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
695         if (*bcp < len) return offset;
696
697 #define CHECK_STRING_TRANS_SUBR(fn)     \
698         if (fn == NULL) return offset;
699
700 #define COUNT_BYTES_TRANS_SUBR(len)     \
701         offset += len;                  \
702         *bcp -= len;
703
704
705 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
706    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
707    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
708 static gboolean smb_trans_reassembly = FALSE;
709 gboolean smb_dcerpc_reassembly = FALSE;
710
711 static GHashTable *smb_trans_fragment_table = NULL;
712 GHashTable *dcerpc_fragment_table = NULL;
713
714 static void
715 smb_trans_reassembly_init(void)
716 {
717         fragment_table_init(&smb_trans_fragment_table);
718 }
719 static void
720 smb_dcerpc_reassembly_init(void)
721 {
722         fragment_table_init(&dcerpc_fragment_table);
723 }
724
725
726 static fragment_data *
727 smb_trans_defragment(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
728                      int offset, int count, int pos, int totlen)
729 {
730         fragment_data *fd_head=NULL;
731         smb_info_t *si;
732         int more_frags;
733
734         more_frags=totlen>(pos+count);
735
736         si = (smb_info_t *)pinfo->private_data;
737         if (si->sip == NULL) {
738                 /*
739                  * We don't have the frame number of the request.
740                  *
741                  * XXX - is there truly nothing we can do here?
742                  * Can we not separately keep track of the original
743                  * transaction and its continuations, as we did
744                  * at one time?
745                  *
746                  * It is probably not much point in even trying to do something here
747                  * if we have never seen the initial request. Without the initial 
748                  * request we probably miss all parameters and the begining of data
749                  * so we cant even call a subdissector since we can not determine
750                  * which type of transaction call this is.
751                  */
752                 return NULL;
753         }
754
755         if(!pinfo->fd->flags.visited){
756                 fd_head = fragment_add(tvb, offset, pinfo,
757                                        si->sip->frame_req, smb_trans_fragment_table,
758                                        pos, count, more_frags);
759         } else {
760                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
761         }
762
763         /* we only show the defragmented packet for the first fragment,
764            or else we might end up with dissecting one HUGE transaction PDU
765            a LOT of times. (first fragment is the only one containing the setup
766            bytes)
767            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction 
768            SMBs. Takes a LOT of time dissecting and is not fun.
769         */
770         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
771                 return fd_head;
772         } else {
773                 return NULL;
774         }
775 }
776                 
777
778
779
780
781 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
782    These variables and functions are used to match
783    responses with calls
784    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
785 /*
786  * The information we need to save about a request in order to show the
787  * frame number of the request in the dissection of the reply.
788  */
789 typedef struct  {
790         guint32 frame;
791         guint32 pid_mid;
792 } smb_saved_info_key_t;
793
794 static GMemChunk *smb_saved_info_key_chunk = NULL;
795 static GMemChunk *smb_saved_info_chunk = NULL;
796 static int smb_saved_info_init_count = 200;
797
798 /* unmatched smb_saved_info structures.
799    For unmatched smb_saved_info structures we store the smb_saved_info
800    structure using the MID and the PID as the key.
801
802    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
803    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
804    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
805 */
806 static gint
807 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
808 {
809         register guint32 key1 = (guint32)k1;
810         register guint32 key2 = (guint32)k2;
811         return key1==key2;
812 }
813 static guint
814 smb_saved_info_hash_unmatched(gconstpointer k)
815 {
816         register guint32 key = (guint32)k;
817         return key;
818 }
819
820 /* matched smb_saved_info structures.
821    For matched smb_saved_info structures we store the smb_saved_info
822    structure twice in the table using the frame number, and a combination
823    of the MID and the PID, as the key.
824    The frame number is guaranteed to be unique but if ever someone makes
825    some change that will renumber the frames in a capture we are in BIG trouble.
826    This is not likely though since that would break (among other things) all the
827    reassembly routines as well.
828
829    We also need the MID as there may be more than one SMB request or reply
830    in a single frame, and we also need the PID as there may be more than
831    one outstanding request with the same MID and different PIDs.
832 */
833 static gint
834 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
835 {
836         const smb_saved_info_key_t *key1 = k1;
837         const smb_saved_info_key_t *key2 = k2;
838         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
839 }
840 static guint
841 smb_saved_info_hash_matched(gconstpointer k)
842 {
843         const smb_saved_info_key_t *key = k;
844         return key->frame + key->pid_mid;
845 }
846
847 /*
848  * The information we need to save about an NT Transaction request in order
849  * to dissect the reply.
850  */
851 typedef struct {
852         int subcmd;
853 } smb_nt_transact_info_t;
854
855 static GMemChunk *smb_nt_transact_info_chunk = NULL;
856 static int smb_nt_transact_info_init_count = 200;
857
858 /*
859  * The information we need to save about a Transaction2 request in order
860  * to dissect the reply.
861  */
862 typedef struct {
863         int subcmd;
864         int info_level;
865 } smb_transact2_info_t;
866
867 static GMemChunk *smb_transact2_info_chunk = NULL;
868 static int smb_transact2_info_init_count = 200;
869
870 /*
871  * The information we need to save about a Transaction request in order
872  * to dissect the reply; this includes information for use by the
873  * Remote API dissector.
874  */
875 static GMemChunk *smb_transact_info_chunk = NULL;
876 static int smb_transact_info_init_count = 200;
877
878 static GMemChunk *conv_tables_chunk = NULL;
879 static GSList *conv_tables = NULL;
880 static int conv_tables_count = 10;
881
882
883 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
884    End of request/response matching functions
885    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
886
887 static const value_string buffer_format_vals[] = {
888         {1,     "Data Block"},
889         {2,     "Dialect"},
890         {3,     "Pathname"},
891         {4,     "ASCII"},
892         {5,     "Variable Block"},
893         {0,     NULL}
894 };
895
896 /*
897  * UTIME - this is *almost* like a UNIX time stamp, except that it's
898  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
899  * January 1, 1970, 00:00:00 GMT.
900  *
901  * This means we have to do some extra work to convert it.  This code is
902  * based on the Samba code:
903  *
904  *      Unix SMB/Netbios implementation.
905  *      Version 1.9.
906  *      time handling functions
907  *      Copyright (C) Andrew Tridgell 1992-1998
908  */
909
910 /*
911  * Yield the difference between *A and *B, in seconds, ignoring leap
912  * seconds.
913  */
914 #define TM_YEAR_BASE 1900
915
916 static int
917 tm_diff(struct tm *a, struct tm *b)
918 {
919         int ay = a->tm_year + (TM_YEAR_BASE - 1);
920         int by = b->tm_year + (TM_YEAR_BASE - 1);
921         int intervening_leap_days =
922             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
923         int years = ay - by;
924         int days =
925             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
926         int hours = 24*days + (a->tm_hour - b->tm_hour);
927         int minutes = 60*hours + (a->tm_min - b->tm_min);
928         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
929
930         return seconds;
931 }
932
933 /*
934  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
935  * determined.
936  */
937 static int
938 TimeZone(time_t t)
939 {
940         struct tm *tm = gmtime(&t);
941         struct tm tm_utc;
942
943         if (tm == NULL)
944                 return 0;
945         tm_utc = *tm;
946         tm = localtime(&t);
947         if (tm == NULL)
948                 return 0;
949         return tm_diff(&tm_utc,tm);
950 }
951
952 /*
953  * Return the same value as TimeZone, but it should be more efficient.
954  *
955  * We keep a table of DST offsets to prevent calling localtime() on each 
956  * call of this function. This saves a LOT of time on many unixes.
957  *
958  * Updated by Paul Eggert <eggert@twinsun.com>
959  */
960 #ifndef CHAR_BIT
961 #define CHAR_BIT 8
962 #endif
963
964 #ifndef TIME_T_MIN
965 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
966                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
967 #endif
968 #ifndef TIME_T_MAX
969 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
970 #endif
971
972 static int
973 TimeZoneFaster(time_t t)
974 {
975         static struct dst_table {time_t start,end; int zone;} *tdt;
976         static struct dst_table *dst_table = NULL;
977         static int table_size = 0;
978         int i;
979         int zone = 0;
980
981         if (t == 0)
982                 t = time(NULL);
983
984         /* Tunis has a 8 day DST region, we need to be careful ... */
985 #define MAX_DST_WIDTH (365*24*60*60)
986 #define MAX_DST_SKIP (7*24*60*60)
987
988         for (i = 0; i < table_size; i++) {
989                 if (t >= dst_table[i].start && t <= dst_table[i].end)
990                         break;
991         }
992
993         if (i < table_size) {
994                 zone = dst_table[i].zone;
995         } else {
996                 time_t low,high;
997
998                 zone = TimeZone(t);
999                 if (dst_table == NULL)
1000                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1001                 else
1002                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1003                 if (tdt == NULL) {
1004                         if (dst_table)
1005                                 free(dst_table);
1006                         table_size = 0;
1007                 } else {
1008                         dst_table = tdt;
1009                         table_size++;
1010     
1011                         dst_table[i].zone = zone; 
1012                         dst_table[i].start = dst_table[i].end = t;
1013     
1014                         /* no entry will cover more than 6 months */
1015                         low = t - MAX_DST_WIDTH/2;
1016                         if (t < low)
1017                                 low = TIME_T_MIN;
1018       
1019                         high = t + MAX_DST_WIDTH/2;
1020                         if (high < t)
1021                                 high = TIME_T_MAX;
1022       
1023                         /*
1024                          * Widen the new entry using two bisection searches.
1025                          */
1026                         while (low+60*60 < dst_table[i].start) {
1027                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1028                                         t = dst_table[i].start - MAX_DST_SKIP;
1029                                 else
1030                                         t = low + (dst_table[i].start-low)/2;
1031                                 if (TimeZone(t) == zone)
1032                                         dst_table[i].start = t;
1033                                 else
1034                                         low = t;
1035                         }
1036
1037                         while (high-60*60 > dst_table[i].end) {
1038                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1039                                         t = dst_table[i].end + MAX_DST_SKIP;
1040                                 else
1041                                         t = high - (high-dst_table[i].end)/2;
1042                                 if (TimeZone(t) == zone)
1043                                         dst_table[i].end = t;
1044                                 else
1045                                         high = t;
1046                         }
1047                 }
1048         }
1049         return zone;
1050 }
1051
1052 /*
1053  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1054  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1055  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1056  * daylight savings transitions because some local times are ambiguous.
1057  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1058  */
1059 static int
1060 LocTimeDiff(time_t lt)
1061 {
1062         int d = TimeZoneFaster(lt);
1063         time_t t = lt + d;
1064
1065         /* if overflow occurred, ignore all the adjustments so far */
1066         if (((t < lt) ^ (d < 0)))
1067                 t = lt;
1068
1069         /*
1070          * Now t should be close enough to the true UTC to yield the
1071          * right answer.
1072          */
1073         return TimeZoneFaster(t);
1074 }
1075
1076 static int
1077 dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1078 {
1079         guint32 timeval;
1080         nstime_t ts;
1081  
1082         timeval = tvb_get_letohl(tvb, offset);
1083         if (timeval == 0xffffffff) {
1084                 proto_tree_add_text(tree, tvb, offset, 4,
1085                     "%s: No time specified (0xffffffff)",
1086                     proto_registrar_get_name(hf_date));
1087                 offset += 4;
1088                 return offset;
1089         }
1090
1091         /*
1092          * We add the local time offset.
1093          */
1094         ts.secs = timeval + LocTimeDiff(timeval);
1095         ts.nsecs = 0;
1096
1097         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1098         offset += 4;
1099  
1100         return offset;
1101 }
1102
1103 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1104
1105 /*
1106  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1107  * to an "nstime_t".
1108  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1109  * midnight "UTC", in 100ns units.
1110  * Return TRUE if the conversion succeeds, FALSE otherwise.
1111  *
1112  * According to the Samba code, it appears to be kludge-GMT (at least for
1113  * file listings). This means it's the GMT you get by taking a local time
1114  * and adding the server time zone offset.  This is NOT the same as GMT in
1115  * some cases.   However, we don't know the server time zone, so we don't
1116  * do that adjustment.
1117  *
1118  * This code is based on the Samba code:
1119  *
1120  *      Unix SMB/Netbios implementation.
1121  *      Version 1.9.
1122  *      time handling functions
1123  *      Copyright (C) Andrew Tridgell 1992-1998
1124  */
1125 static gboolean
1126 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1127 {
1128         double d;
1129         /* The next two lines are a fix needed for the 
1130             broken SCO compiler. JRA. */
1131         time_t l_time_min = TIME_T_MIN;
1132         time_t l_time_max = TIME_T_MAX;
1133
1134         if (filetime_high == 0)
1135                 return FALSE;
1136
1137         /*
1138          * Get the time as a double, in seconds and fractional seconds.
1139          */
1140         d = ((double)filetime_high)*4.0*(double)(1<<30);
1141         d += filetime_low;
1142         d *= 1.0e-7;
1143  
1144         /* Now adjust by 369 years, to make the seconds since 1970. */
1145         d -= TIME_FIXUP_CONSTANT;
1146
1147         if (!(l_time_min <= d && d <= l_time_max))
1148                 return FALSE;
1149
1150         /*
1151          * Get the time as seconds and nanoseconds.
1152          */
1153         tv->secs = d;
1154         tv->nsecs = (d - tv->secs)*1000000000;
1155
1156         return TRUE;
1157 }
1158
1159 int
1160 dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
1161 {
1162         guint32 filetime_high, filetime_low;
1163         nstime_t ts;
1164
1165         if (tree) {
1166                 filetime_low = tvb_get_letohl(tvb, offset);
1167                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1168                 if (filetime_low == 0 && filetime_high == 0) {
1169                         proto_tree_add_text(tree, tvb, offset, 8,
1170                             "%s: No time specified (0)",
1171                             proto_registrar_get_name(hf_date));
1172                 } else if(filetime_low==0 && filetime_high==0x80000000){
1173                         proto_tree_add_text(tree, tvb, offset, 8,
1174                             "%s: Infinity (absolute time)",
1175                             proto_registrar_get_name(hf_date));
1176                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1177                         proto_tree_add_text(tree, tvb, offset, 8,
1178                             "%s: Infinity (relative time)",
1179                             proto_registrar_get_name(hf_date));
1180                 } else {                        
1181                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1182                                 proto_tree_add_time(tree, hf_date, tvb,
1183                                     offset, 8, &ts);
1184                         } else {
1185                                 proto_tree_add_text(tree, tvb, offset, 8,
1186                                     "%s: Time can't be converted",
1187                                     proto_registrar_get_name(hf_date));
1188                         }
1189                 }
1190         }
1191
1192         offset += 8;
1193         return offset;
1194 }
1195
1196 static int
1197 dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
1198     proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
1199     int hf_dos_time, gboolean time_first)
1200 {
1201         guint16 dos_time, dos_date;
1202         proto_item *item = NULL;
1203         proto_tree *tree = NULL;
1204         struct tm tm;
1205         time_t t;
1206         static const int mday_noleap[12] = {
1207                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1208         };
1209         static const int mday_leap[12] = {
1210                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1211         };
1212 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1213         nstime_t tv;
1214
1215         if (time_first) {
1216                 dos_time = tvb_get_letohs(tvb, offset);
1217                 dos_date = tvb_get_letohs(tvb, offset+2);
1218         } else {
1219                 dos_date = tvb_get_letohs(tvb, offset);
1220                 dos_time = tvb_get_letohs(tvb, offset+2);
1221         }
1222
1223         if ((dos_time == 0xffff && dos_time == 0xffff) ||
1224             (dos_time == 0 && dos_time == 0)) {
1225                 /*
1226                  * No date/time specified.
1227                  */
1228                 if(parent_tree){
1229                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1230                             "%s: No time specified (0x%08x)",
1231                             proto_registrar_get_name(hf_date),
1232                             (dos_date << 16) | dos_time);
1233                 }
1234                 offset += 4;
1235                 return offset;
1236         }
1237
1238         tm.tm_sec = (dos_time&0x1f)*2;
1239         tm.tm_min = (dos_time>>5)&0x3f;
1240         tm.tm_hour = (dos_time>>11)&0x1f;
1241         tm.tm_mday = dos_date&0x1f;
1242         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1243         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1244         tm.tm_isdst = -1;
1245
1246         /*
1247          * Do some sanity checks before calling "mktime()";
1248          * "mktime()" doesn't do them, it "normalizes" out-of-range
1249          * values.
1250          */
1251         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1252            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1253            (ISLEAP(tm.tm_year + 1900) ?
1254              tm.tm_mday > mday_leap[tm.tm_mon] :
1255              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1256              (t = mktime(&tm)) == -1) {
1257                 /*
1258                  * Invalid date/time.
1259                  */
1260                 if (parent_tree) {
1261                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1262                             "%s: Invalid time",
1263                             proto_registrar_get_name(hf_date));
1264                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1265                         if (time_first) {
1266                                 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1267                                 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1268                         } else {
1269                                 proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1270                                 proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1271                         }
1272                 }
1273                 offset += 4;
1274                 return offset;
1275         }
1276
1277         tv.secs = t;
1278         tv.nsecs = 0;
1279
1280         if(parent_tree){
1281                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1282                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1283                 if (time_first) {
1284                         proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1285                         proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset+2, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1286                 } else {
1287                         proto_tree_add_uint_format(tree, hf_dos_date, tvb, offset, 2, dos_date, "DOS Date: %04d-%02d-%02d (0x%04x)", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, dos_date);
1288                         proto_tree_add_uint_format(tree, hf_dos_time, tvb, offset+2, 2, dos_time, "DOS Time: %02d:%02d:%02d (0x%04x)", tm.tm_hour, tm.tm_min, tm.tm_sec, dos_time);
1289                 }
1290         }
1291
1292         offset += 4;
1293
1294         return offset;
1295 }
1296
1297
1298 static const value_string da_access_vals[] = {
1299         { 0,            "Open for reading"},
1300         { 1,            "Open for writing"},
1301         { 2,            "Open for reading and writing"},
1302         { 3,            "Open for execute"},
1303         {0, NULL}
1304 };
1305 static const value_string da_sharing_vals[] = {
1306         { 0,            "Compatibility mode"},
1307         { 1,            "Deny read/write/execute (exclusive)"},
1308         { 2,            "Deny write"},
1309         { 3,            "Deny read/execute"},
1310         { 4,            "Deny none"},
1311         {0, NULL}
1312 };
1313 static const value_string da_locality_vals[] = {
1314         { 0,            "Locality of reference unknown"},
1315         { 1,            "Mainly sequential access"},
1316         { 2,            "Mainly random access"},
1317         { 3,            "Random access with some locality"},
1318         {0, NULL}
1319 };
1320 static const true_false_string tfs_da_caching = {
1321         "Do not cache this file",
1322         "Caching permitted on this file"
1323 };
1324 static const true_false_string tfs_da_writetru = {
1325         "Write through enabled",
1326         "Write through disabled"
1327 };
1328 static int
1329 dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
1330 {
1331         guint16 mask;
1332         proto_item *item = NULL;
1333         proto_tree *tree = NULL;
1334
1335         mask = tvb_get_letohs(tvb, offset);
1336
1337         if(parent_tree){
1338                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1339                         "%s Access: 0x%04x", type, mask);
1340                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1341         }
1342
1343         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1344                 tvb, offset, 2, mask);
1345         proto_tree_add_boolean(tree, hf_smb_access_caching,
1346                 tvb, offset, 2, mask);
1347         proto_tree_add_uint(tree, hf_smb_access_locality,
1348                 tvb, offset, 2, mask);
1349         proto_tree_add_uint(tree, hf_smb_access_sharing,
1350                 tvb, offset, 2, mask);
1351         proto_tree_add_uint(tree, hf_smb_access_mode,
1352                 tvb, offset, 2, mask);
1353
1354         offset += 2;
1355
1356         return offset;
1357 }
1358
1359 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1360 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1361 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1362 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1363 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1364 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1365 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1366 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1367 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1368 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1369 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1370 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1371 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1372 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1373 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1374
1375 /*
1376  * These are flags to be used in NT Create operations.
1377  */
1378 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1379 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1380 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1381 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1382 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1383 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1384 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1385
1386 static const true_false_string tfs_file_attribute_write_through = {
1387         "This object requires WRITE THROUGH",
1388         "This object does NOT require write through",
1389 };
1390 static const true_false_string tfs_file_attribute_no_buffering = {
1391         "This object requires NO BUFFERING",
1392         "This object can be buffered",
1393 };
1394 static const true_false_string tfs_file_attribute_random_access = {
1395         "This object will be RANDOM ACCESSed",
1396         "Random access is NOT requested",
1397 };
1398 static const true_false_string tfs_file_attribute_sequential_scan = {
1399         "This object is optimized for SEQUENTIAL SCAN",
1400         "This object is NOT optimized for sequential scan",
1401 };
1402 static const true_false_string tfs_file_attribute_delete_on_close = {
1403         "This object will be DELETED ON CLOSE",
1404         "This object will not be deleted on close",
1405 };
1406 static const true_false_string tfs_file_attribute_backup_semantics = {
1407         "This object supports BACKUP SEMANTICS",
1408         "This object does NOT support backup semantics",
1409 };
1410 static const true_false_string tfs_file_attribute_posix_semantics = {
1411         "This object supports POSIX SEMANTICS",
1412         "This object does NOT support POSIX semantics",
1413 };
1414 static const true_false_string tfs_file_attribute_read_only = {
1415         "This file is READ ONLY",
1416         "This file is NOT read only",
1417 };
1418 static const true_false_string tfs_file_attribute_hidden = {
1419         "This is a HIDDEN file",
1420         "This is NOT a hidden file"
1421 };
1422 static const true_false_string tfs_file_attribute_system = {
1423         "This is a SYSTEM file",
1424         "This is NOT a system file"
1425 };
1426 static const true_false_string tfs_file_attribute_volume = {
1427         "This is a VOLUME ID",
1428         "This is NOT a volume ID"
1429 };
1430 static const true_false_string tfs_file_attribute_directory = {
1431         "This is a DIRECTORY",
1432         "This is NOT a directory"
1433 };
1434 static const true_false_string tfs_file_attribute_archive = {
1435         "This is an ARCHIVE file",
1436         "This is NOT an archive file"
1437 };
1438 static const true_false_string tfs_file_attribute_device = {
1439         "This is a DEVICE",
1440         "This is NOT a device"
1441 };
1442 static const true_false_string tfs_file_attribute_normal = {
1443         "This file is an ordinary file",
1444         "This file has some attribute set"
1445 };
1446 static const true_false_string tfs_file_attribute_temporary = {
1447         "This is a TEMPORARY file",
1448         "This is NOT a temporary file"
1449 };
1450 static const true_false_string tfs_file_attribute_sparse = {
1451         "This is a SPARSE file",
1452         "This is NOT a sparse file"
1453 };
1454 static const true_false_string tfs_file_attribute_reparse = {
1455         "This file has an associated REPARSE POINT",
1456         "This file does NOT have an associated reparse point"
1457 };
1458 static const true_false_string tfs_file_attribute_compressed = {
1459         "This is a COMPRESSED file",
1460         "This is NOT a compressed file"
1461 };
1462 static const true_false_string tfs_file_attribute_offline = {
1463         "This file is OFFLINE",
1464         "This file is NOT offline"
1465 };
1466 static const true_false_string tfs_file_attribute_not_content_indexed = {
1467         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1468         "This file MAY be indexed by the content indexing service"
1469 };
1470 static const true_false_string tfs_file_attribute_encrypted = {
1471         "This is an ENCRYPTED file",
1472         "This is NOT an encrypted file"
1473 };
1474
1475 static int
1476 dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1477 {
1478         guint16 mask;
1479         proto_item *item = NULL;
1480         proto_tree *tree = NULL;
1481
1482         mask = tvb_get_letohs(tvb, offset);
1483
1484         if(parent_tree){
1485                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1486                         "File Attributes: 0x%04x", mask);
1487                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1488         }
1489         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1490                 tvb, offset, 2, mask);
1491         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1492                 tvb, offset, 2, mask);
1493         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1494                 tvb, offset, 2, mask);
1495         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1496                 tvb, offset, 2, mask);
1497         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1498                 tvb, offset, 2, mask);
1499         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1500                 tvb, offset, 2, mask);
1501
1502         offset += 2;
1503
1504         return offset;
1505 }
1506
1507 /* 3.11 */
1508 static int
1509 dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1510 {
1511         guint32 mask;
1512         proto_item *item = NULL;
1513         proto_tree *tree = NULL;
1514
1515         mask = tvb_get_letohl(tvb, offset);
1516
1517         if(parent_tree){
1518                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1519                         "File Attributes: 0x%08x", mask);
1520                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1521         }
1522
1523         /*
1524          * XXX - Network Monitor disagrees on some of the
1525          * bits, e.g. the bits above temporary are "atomic write"
1526          * and "transaction write", and it says nothing about the
1527          * bits above that.
1528          *
1529          * Does the Win32 API documentation, or the NT Native API book,
1530          * suggest anything?
1531          */
1532         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1533                 tvb, offset, 4, mask);
1534         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1535                 tvb, offset, 4, mask);
1536         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1537                 tvb, offset, 4, mask);
1538         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1539                 tvb, offset, 4, mask);
1540         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1541                 tvb, offset, 4, mask);
1542         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1543                 tvb, offset, 4, mask);
1544         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1545                 tvb, offset, 4, mask);
1546         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1547                 tvb, offset, 4, mask);
1548         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1549                 tvb, offset, 4, mask);
1550         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1551                 tvb, offset, 4, mask);
1552         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1553                 tvb, offset, 4, mask);
1554         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1555                 tvb, offset, 4, mask);
1556         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1557                 tvb, offset, 4, mask);
1558         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1559                 tvb, offset, 4, mask);
1560         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1561                 tvb, offset, 4, mask);
1562         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1563                 tvb, offset, 4, mask);
1564         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1565                 tvb, offset, 4, mask);
1566         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1567                 tvb, offset, 4, mask);
1568         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1569                 tvb, offset, 4, mask);
1570         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1571                 tvb, offset, 4, mask);
1572         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1573                 tvb, offset, 4, mask);
1574         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1575                 tvb, offset, 4, mask);
1576
1577         offset += 4;
1578
1579         return offset;
1580 }
1581
1582 static int
1583 dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1584 {
1585         guint8 mask;
1586         proto_item *item = NULL;
1587         proto_tree *tree = NULL;
1588
1589         mask = tvb_get_guint8(tvb, offset);
1590
1591         if(parent_tree){
1592                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1593                         "File Attributes: 0x%02x", mask);
1594                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1595         }
1596         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1597                 tvb, offset, 1, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1599                 tvb, offset, 1, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1601                 tvb, offset, 1, mask);
1602         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1603                 tvb, offset, 1, mask);
1604         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1605                 tvb, offset, 1, mask);
1606         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1607                 tvb, offset, 1, mask);
1608
1609         offset += 1;
1610
1611         return offset;
1612 }
1613
1614 static const true_false_string tfs_search_attribute_read_only = {
1615         "Include READ ONLY files in search results",
1616         "Do NOT include read only files in search results",
1617 };
1618 static const true_false_string tfs_search_attribute_hidden = {
1619         "Include HIDDEN files in search results",
1620         "Do NOT include hidden files in search results"
1621 };
1622 static const true_false_string tfs_search_attribute_system = {
1623         "Include SYSTEM files in search results",
1624         "Do NOT include system files in search results"
1625 };
1626 static const true_false_string tfs_search_attribute_volume = {
1627         "Include VOLUME IDs in search results",
1628         "Do NOT include volume IDs in search results"
1629 };
1630 static const true_false_string tfs_search_attribute_directory = {
1631         "Include DIRECTORIES in search results",
1632         "Do NOT include directories in search results"
1633 };
1634 static const true_false_string tfs_search_attribute_archive = {
1635         "Include ARCHIVE files in search results",
1636         "Do NOT include archive files in search results"
1637 };
1638
1639 static int
1640 dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1641 {
1642         guint16 mask;
1643         proto_item *item = NULL;
1644         proto_tree *tree = NULL;
1645
1646         mask = tvb_get_letohs(tvb, offset);
1647
1648         if(parent_tree){
1649                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1650                         "Search Attributes: 0x%04x", mask);
1651                 tree = proto_item_add_subtree(item, ett_smb_search);
1652         }
1653
1654         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1655                 tvb, offset, 2, mask);
1656         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1657                 tvb, offset, 2, mask);
1658         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1659                 tvb, offset, 2, mask);  
1660         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1661                 tvb, offset, 2, mask);
1662         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1663                 tvb, offset, 2, mask);
1664         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1665                 tvb, offset, 2, mask);
1666
1667         offset += 2;
1668         return offset;
1669 }
1670
1671 #if 0
1672 /*
1673  * XXX - this isn't used.
1674  * Is this used for anything?  NT Create AndX doesn't use it.
1675  * Is there some 16-bit attribute field with more bits than Read Only,
1676  * Hidden, System, Volume ID, Directory, and Archive?
1677  */
1678 static int
1679 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1680 {
1681         guint32 mask;
1682         proto_item *item = NULL;
1683         proto_tree *tree = NULL;
1684
1685         mask = tvb_get_letohl(tvb, offset);
1686
1687         if(parent_tree){
1688                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1689                         "File Attributes: 0x%08x", mask);
1690                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1691         }
1692         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1693                 tvb, offset, 2, mask);
1694         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1695                 tvb, offset, 2, mask);
1696         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1697                 tvb, offset, 2, mask);
1698         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1699                 tvb, offset, 2, mask);
1700         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1701                 tvb, offset, 2, mask);
1702         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1703                 tvb, offset, 2, mask);
1704         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1705                 tvb, offset, 2, mask);
1706         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1707                 tvb, offset, 2, mask);
1708         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1709                 tvb, offset, 2, mask);
1710         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1711                 tvb, offset, 2, mask);
1712         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1713                 tvb, offset, 2, mask);
1714         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1715                 tvb, offset, 2, mask);
1716         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1717                 tvb, offset, 2, mask);
1718         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1719                 tvb, offset, 2, mask);
1720         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1721                 tvb, offset, 2, mask);
1722
1723         offset += 2;
1724
1725         return offset;
1726 }
1727 #endif
1728
1729
1730 #define SERVER_CAP_RAW_MODE            0x00000001
1731 #define SERVER_CAP_MPX_MODE            0x00000002
1732 #define SERVER_CAP_UNICODE             0x00000004
1733 #define SERVER_CAP_LARGE_FILES         0x00000008
1734 #define SERVER_CAP_NT_SMBS             0x00000010
1735 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1736 #define SERVER_CAP_STATUS32            0x00000040
1737 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1738 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1739 #define SERVER_CAP_NT_FIND             0x00000200
1740 #define SERVER_CAP_DFS                 0x00001000
1741 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1742 #define SERVER_CAP_LARGE_READX         0x00004000
1743 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1744 #define SERVER_CAP_UNIX                0x00800000
1745 #define SERVER_CAP_RESERVED            0x02000000
1746 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1747 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1748 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1749 static const true_false_string tfs_server_cap_raw_mode = {
1750         "Read Raw and Write Raw are supported",
1751         "Read Raw and Write Raw are not supported"
1752 };
1753 static const true_false_string tfs_server_cap_mpx_mode = {
1754         "Read Mpx and Write Mpx are supported",
1755         "Read Mpx and Write Mpx are not supported"
1756 };
1757 static const true_false_string tfs_server_cap_unicode = {
1758         "Unicode strings are supported",
1759         "Unicode strings are not supported"
1760 };
1761 static const true_false_string tfs_server_cap_large_files = {
1762         "Large files are supported",
1763         "Large files are not supported",
1764 };
1765 static const true_false_string tfs_server_cap_nt_smbs = {
1766         "NT SMBs are supported",
1767         "NT SMBs are not supported"
1768 };
1769 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1770         "RPC remote APIs are supported",
1771         "RPC remote APIs are not supported"
1772 };
1773 static const true_false_string tfs_server_cap_nt_status = {
1774         "NT status codes are supported",
1775         "NT status codes are not supported"
1776 };
1777 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1778         "Level 2 oplocks are supported",
1779         "Level 2 oplocks are not supported"
1780 };
1781 static const true_false_string tfs_server_cap_lock_and_read = {
1782         "Lock and Read is supported",
1783         "Lock and Read is not supported"
1784 };
1785 static const true_false_string tfs_server_cap_nt_find = {
1786         "NT Find is supported",
1787         "NT Find is not supported"
1788 };
1789 static const true_false_string tfs_server_cap_dfs = {
1790         "Dfs is supported",
1791         "Dfs is not supported"
1792 };
1793 static const true_false_string tfs_server_cap_infolevel_passthru = {
1794         "NT information level request passthrough is supported",
1795         "NT information level request passthrough is not supported"
1796 };
1797 static const true_false_string tfs_server_cap_large_readx = {
1798         "Large Read andX is supported",
1799         "Large Read andX is not supported"
1800 };
1801 static const true_false_string tfs_server_cap_large_writex = {
1802         "Large Write andX is supported",
1803         "Large Write andX is not supported"
1804 };
1805 static const true_false_string tfs_server_cap_unix = {
1806         "UNIX extensions are supported",
1807         "UNIX extensions are not supported"
1808 };
1809 static const true_false_string tfs_server_cap_reserved = {
1810         "Reserved",
1811         "Reserved"
1812 };
1813 static const true_false_string tfs_server_cap_bulk_transfer = {
1814         "Bulk Read and Bulk Write are supported",
1815         "Bulk Read and Bulk Write are not supported"
1816 };
1817 static const true_false_string tfs_server_cap_compressed_data = {
1818         "Compressed data transfer is supported",
1819         "Compressed data transfer is not supported"
1820 };
1821 static const true_false_string tfs_server_cap_extended_security = {
1822         "Extended security exchanges are supported",
1823         "Extended security exchanges are not supported"
1824 };
1825 static int
1826 dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1827 {
1828         guint32 mask;
1829         proto_item *item = NULL;
1830         proto_tree *tree = NULL;
1831
1832         mask = tvb_get_letohl(tvb, offset);
1833
1834         if(parent_tree){
1835                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1836                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1837         }
1838
1839         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1840                 tvb, offset, 4, mask);
1841         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1842                 tvb, offset, 4, mask);
1843         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1844                 tvb, offset, 4, mask);
1845         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1846                 tvb, offset, 4, mask);
1847         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1848                 tvb, offset, 4, mask);
1849         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1850                 tvb, offset, 4, mask);
1851         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1852                 tvb, offset, 4, mask);
1853         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1854                 tvb, offset, 4, mask);
1855         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1856                 tvb, offset, 4, mask);
1857         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1858                 tvb, offset, 4, mask);
1859         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1860                 tvb, offset, 4, mask);
1861         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1862                 tvb, offset, 4, mask);
1863         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1864                 tvb, offset, 4, mask);
1865         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1866                 tvb, offset, 4, mask);
1867         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1868                 tvb, offset, 4, mask);
1869         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1870                 tvb, offset, 4, mask);
1871         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1872                 tvb, offset, 4, mask);
1873         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1874                 tvb, offset, 4, mask);
1875         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1876                 tvb, offset, 4, mask);
1877
1878         return mask;
1879 }
1880
1881 #define RAWMODE_READ   0x01
1882 #define RAWMODE_WRITE  0x02
1883 static const true_false_string tfs_rm_read = {
1884         "Read Raw is supported",
1885         "Read Raw is not supported"
1886 };
1887 static const true_false_string tfs_rm_write = {
1888         "Write Raw is supported",
1889         "Write Raw is not supported"
1890 };
1891
1892 static int
1893 dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1894 {
1895         guint16 mask;
1896         proto_item *item = NULL;
1897         proto_tree *tree = NULL;
1898
1899         mask = tvb_get_letohs(tvb, offset);
1900
1901         if(parent_tree){
1902                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1903                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1904         }
1905
1906         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1907         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1908
1909         offset += 2;
1910
1911         return offset;
1912 }
1913
1914 #define SECURITY_MODE_MODE             0x01
1915 #define SECURITY_MODE_PASSWORD         0x02
1916 #define SECURITY_MODE_SIGNATURES       0x04
1917 #define SECURITY_MODE_SIG_REQUIRED     0x08
1918 static const true_false_string tfs_sm_mode = {
1919         "USER security mode",
1920         "SHARE security mode"
1921 };
1922 static const true_false_string tfs_sm_password = {
1923         "ENCRYPTED password. Use challenge/response",
1924         "PLAINTEXT password"
1925 };
1926 static const true_false_string tfs_sm_signatures = {
1927         "Security signatures ENABLED",
1928         "Security signatures NOT enabled"
1929 };
1930 static const true_false_string tfs_sm_sig_required = {
1931         "Security signatures REQUIRED",
1932         "Security signatures NOT required"
1933 };
1934
1935 static int
1936 dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
1937 {
1938         guint16 mask = 0;
1939         proto_item *item = NULL;
1940         proto_tree *tree = NULL;
1941
1942         switch(wc){
1943         case 13:
1944                 mask = tvb_get_letohs(tvb, offset);
1945                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1946                                 "Security Mode: 0x%04x", mask);
1947                 tree = proto_item_add_subtree(item, ett_smb_mode);
1948                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1949                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1950                 offset += 2;
1951                 break;
1952
1953         case 17:
1954                 mask = tvb_get_guint8(tvb, offset);
1955                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1956                                 "Security Mode: 0x%02x", mask);
1957                 tree = proto_item_add_subtree(item, ett_smb_mode);
1958                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1959                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1960                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1961                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1962                 offset += 1;
1963                 break;
1964         }
1965
1966         return offset;
1967 }
1968
1969 static int
1970 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1971 {
1972         proto_item *it = NULL;
1973         proto_tree *tr = NULL;
1974         guint16 bc;
1975         guint8 wc;
1976
1977         WORD_COUNT;
1978
1979         BYTE_COUNT;
1980
1981         if(tree){
1982                 it = proto_tree_add_text(tree, tvb, offset, bc,
1983                                 "Requested Dialects");
1984                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1985         }
1986
1987         while(bc){
1988                 int len;
1989                 const guint8 *str;
1990                 proto_item *dit = NULL;
1991                 proto_tree *dtr = NULL;
1992
1993                 /* XXX - what if this runs past bc? */
1994                 len = tvb_strsize(tvb, offset+1);
1995                 str = tvb_get_ptr(tvb, offset+1, len);
1996
1997                 if(tr){
1998                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
1999                                         "Dialect: %s", str);
2000                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2001                 }
2002
2003                 /* Buffer Format */
2004                 CHECK_BYTE_COUNT(1);
2005                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2006                         TRUE);
2007                 COUNT_BYTES(1);
2008
2009                 /*Dialect Name */
2010                 CHECK_BYTE_COUNT(len);
2011                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2012                         len, str);
2013                 COUNT_BYTES(len);
2014         }
2015
2016         END_OF_SMB
2017
2018         return offset;
2019 }
2020
2021 static int
2022 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2023 {
2024         guint8 wc;
2025         guint16 dialect;
2026         const char *dn;
2027         int dn_len;
2028         guint16 bc;
2029         guint16 ekl=0;
2030         guint32 caps=0;
2031         gint16 tz;
2032
2033         WORD_COUNT;
2034
2035         /* Dialect Index */
2036         dialect = tvb_get_letohs(tvb, offset);
2037         switch(wc){
2038         case 1:
2039                 if(dialect==0xffff){
2040                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2041                                 tvb, offset, 2, dialect,
2042                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2043                 } else {
2044                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2045                                 tvb, offset, 2, dialect);
2046                 }
2047                 break;
2048         case 13:
2049                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2050                         tvb, offset, 2, dialect,
2051                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2052                 break;
2053         case 17:
2054                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2055                         tvb, offset, 2, dialect,
2056                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2057                 break;
2058         default:
2059                 proto_tree_add_text(tree, tvb, offset, wc*2,
2060                         "Words for unknown response format");
2061                 offset += wc*2;
2062                 goto bytecount;
2063         }
2064         offset += 2;
2065
2066         switch(wc){
2067         case 13:
2068                 /* Security Mode */
2069                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
2070                                 wc);
2071
2072                 /* Maximum Transmit Buffer Size */
2073                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2074                         tvb, offset, 2, TRUE);
2075                 offset += 2;
2076
2077                 /* Maximum Multiplex Count */
2078                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2079                         tvb, offset, 2, TRUE);
2080                 offset += 2;
2081
2082                 /* Maximum Vcs Number */
2083                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2084                         tvb, offset, 2, TRUE);
2085                 offset += 2;
2086
2087                 /* raw mode */
2088                 offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
2089
2090                 /* session key */
2091                 proto_tree_add_item(tree, hf_smb_session_key,
2092                         tvb, offset, 4, TRUE);
2093                 offset += 4;
2094
2095                 /* current time and date at server */
2096                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2097                     TRUE);
2098
2099                 /* time zone */
2100                 tz = tvb_get_letohs(tvb, offset);
2101                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2102                 offset += 2;
2103
2104                 /* encryption key length */
2105                 ekl = tvb_get_letohs(tvb, offset);
2106                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2107                 offset += 2;
2108
2109                 /* 2 reserved bytes */
2110                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2111                 offset += 2;
2112
2113                 break;
2114
2115         case 17:
2116                 /* Security Mode */
2117                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
2118
2119                 /* Maximum Multiplex Count */
2120                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2121                         tvb, offset, 2, TRUE);
2122                 offset += 2;
2123
2124                 /* Maximum Vcs Number */
2125                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2126                         tvb, offset, 2, TRUE);
2127                 offset += 2;
2128
2129                 /* Maximum Transmit Buffer Size */
2130                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2131                         tvb, offset, 4, TRUE);
2132                 offset += 4;
2133
2134                 /* maximum raw buffer size */
2135                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2136                         tvb, offset, 4, TRUE);
2137                 offset += 4;
2138
2139                 /* session key */
2140                 proto_tree_add_item(tree, hf_smb_session_key,
2141                         tvb, offset, 4, TRUE);
2142                 offset += 4;
2143
2144                 /* server capabilities */
2145                 caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
2146                 offset += 4;
2147
2148                 /* system time */
2149                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
2150                                 hf_smb_system_time);
2151
2152                 /* time zone */
2153                 tz = tvb_get_letohs(tvb, offset);
2154                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2155                         tvb, offset, 2, tz,
2156                         "Server Time Zone: %d min from UTC", tz);
2157                 offset += 2;
2158
2159                 /* encryption key length */
2160                 ekl = tvb_get_guint8(tvb, offset);
2161                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2162                         tvb, offset, 1, ekl);
2163                 offset += 1;
2164
2165                 break;
2166         }
2167
2168         BYTE_COUNT;
2169
2170         switch(wc){
2171         case 13:
2172                 /* challenge/response encryption key */
2173                 if(ekl){
2174                         CHECK_BYTE_COUNT(ekl);
2175                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2176                         COUNT_BYTES(ekl);
2177                 }
2178
2179                 /* domain */
2180                 dn = get_unicode_or_ascii_string(tvb, &offset,
2181                         pinfo, &dn_len, FALSE, FALSE, &bc);
2182                 if (dn == NULL)
2183                         goto endofcommand;
2184                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2185                         offset, dn_len,dn);
2186                 COUNT_BYTES(dn_len);
2187                 break;
2188
2189         case 17:
2190                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2191                         smb_info_t *si;
2192
2193                         /* challenge/response encryption key */
2194                         /* XXX - is this aligned on an even boundary? */
2195                         if(ekl){
2196                                 CHECK_BYTE_COUNT(ekl);
2197                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2198                                         tvb, offset, ekl, TRUE);
2199                                 COUNT_BYTES(ekl);
2200                         }
2201
2202                         /* domain */
2203                         /* this string is special, unicode is flagged in caps */
2204                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
2205                         si = pinfo->private_data;
2206                         si->unicode = (caps&SERVER_CAP_UNICODE);
2207                         dn = get_unicode_or_ascii_string(tvb,
2208                                 &offset, pinfo, &dn_len, TRUE, FALSE,
2209                                 &bc);
2210                         if (dn == NULL)
2211                                 goto endofcommand;
2212                         proto_tree_add_string(tree, hf_smb_primary_domain,
2213                                 tvb, offset, dn_len, dn);
2214                         COUNT_BYTES(dn_len);
2215                 } else {
2216                         /* guid */
2217                         /* XXX - show it in the standard Microsoft format
2218                            for GUIDs? */
2219                         CHECK_BYTE_COUNT(16);
2220                         proto_tree_add_item(tree, hf_smb_server_guid,
2221                                 tvb, offset, 16, TRUE);
2222                         COUNT_BYTES(16);
2223
2224                         /* security blob */
2225                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2226                            data structure, at least in NT 5.0-and-later
2227                            server replies? */
2228                         if(bc){
2229                                 proto_tree_add_item(tree, hf_smb_security_blob,
2230                                         tvb, offset, bc, TRUE);
2231                                 COUNT_BYTES(bc);
2232                         }
2233                 }
2234                 break;
2235         }
2236
2237         END_OF_SMB
2238
2239         return offset;
2240 }
2241
2242
2243 static int
2244 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2245 {
2246         int dn_len;
2247         const char *dn;
2248         guint8 wc;
2249         guint16 bc;
2250
2251         WORD_COUNT;
2252  
2253         BYTE_COUNT;
2254
2255         /* buffer format */
2256         CHECK_BYTE_COUNT(1);
2257         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2258         COUNT_BYTES(1);
2259
2260         /* dir name */
2261         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2262                 FALSE, FALSE, &bc);
2263         if (dn == NULL)
2264                 goto endofcommand;
2265         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2266                 dn);
2267         COUNT_BYTES(dn_len);
2268
2269         if (check_col(pinfo->cinfo, COL_INFO)) {
2270                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2271         }
2272
2273         END_OF_SMB
2274
2275         return offset;
2276 }
2277
2278 static int
2279 dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2280 {
2281         guint8 wc;
2282         guint16 bc;
2283  
2284         WORD_COUNT;
2285  
2286         BYTE_COUNT;
2287
2288         END_OF_SMB
2289
2290         return offset;
2291 }
2292
2293 static int
2294 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2295 {
2296         guint16 ec, bc;
2297         guint8 wc;
2298
2299         WORD_COUNT;
2300
2301         /* echo count */
2302         ec = tvb_get_letohs(tvb, offset);
2303         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2304         offset += 2;
2305
2306         BYTE_COUNT;
2307
2308         if (bc != 0) {
2309                 /* echo data */
2310                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2311                 COUNT_BYTES(bc);
2312         }
2313
2314         END_OF_SMB
2315
2316         return offset;
2317 }
2318
2319 static int
2320 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2321 {
2322         guint16 bc;
2323         guint8 wc;
2324
2325         WORD_COUNT;
2326
2327         /* echo sequence number */
2328         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2329         offset += 2;
2330
2331         BYTE_COUNT;
2332
2333         if (bc != 0) {
2334                 /* echo data */
2335                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2336                 COUNT_BYTES(bc);
2337         }
2338
2339         END_OF_SMB
2340
2341         return offset;
2342 }
2343
2344 static int
2345 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2346 {
2347         int an_len, pwlen;
2348         const char *an;
2349         guint8 wc;
2350         guint16 bc;
2351
2352         WORD_COUNT;
2353  
2354         BYTE_COUNT;
2355
2356         /* buffer format */
2357         CHECK_BYTE_COUNT(1);
2358         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2359         COUNT_BYTES(1);
2360
2361         /* Path */
2362         an = get_unicode_or_ascii_string(tvb, &offset,
2363                 pinfo, &an_len, FALSE, FALSE, &bc);
2364         if (an == NULL)
2365                 goto endofcommand;
2366         proto_tree_add_string(tree, hf_smb_path, tvb,
2367                 offset, an_len, an);
2368         COUNT_BYTES(an_len);
2369
2370         if (check_col(pinfo->cinfo, COL_INFO)) {
2371                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2372         }
2373
2374         /* buffer format */
2375         CHECK_BYTE_COUNT(1);
2376         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2377         COUNT_BYTES(1);
2378
2379         /* password, ANSI */
2380         /* XXX - what if this runs past bc? */
2381         pwlen = tvb_strsize(tvb, offset);
2382         CHECK_BYTE_COUNT(pwlen);
2383         proto_tree_add_item(tree, hf_smb_password,
2384                 tvb, offset, pwlen, TRUE);
2385         COUNT_BYTES(pwlen);
2386
2387         /* buffer format */
2388         CHECK_BYTE_COUNT(1);
2389         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2390         COUNT_BYTES(1);
2391
2392         /* Service */
2393         an = get_unicode_or_ascii_string(tvb, &offset,
2394                 pinfo, &an_len, FALSE, FALSE, &bc);
2395         if (an == NULL)
2396                 goto endofcommand;
2397         proto_tree_add_string(tree, hf_smb_service, tvb,
2398                 offset, an_len, an);
2399         COUNT_BYTES(an_len);
2400
2401         END_OF_SMB
2402
2403         return offset;
2404 }
2405
2406 static int
2407 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2408 {
2409         guint8 wc;
2410         guint16 bc;
2411
2412         WORD_COUNT;
2413  
2414         /* Maximum Buffer Size */
2415         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2416         offset += 2;
2417
2418         /* tid */
2419         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2420         offset += 2;
2421
2422         BYTE_COUNT;
2423
2424         END_OF_SMB
2425
2426         return offset;
2427 }
2428  
2429
2430 static const true_false_string tfs_of_create = {
2431         "Create file if it does not exist",
2432         "Fail if file does not exist"
2433 };
2434 static const value_string of_open[] = {
2435         { 0,            "Fail if file exists"},
2436         { 1,            "Open file if it exists"},
2437         { 2,            "Truncate file if it exists"},
2438         {0, NULL}
2439 };
2440 static int
2441 dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2442 {
2443         guint16 mask;
2444         proto_item *item = NULL;
2445         proto_tree *tree = NULL;
2446
2447         mask = tvb_get_letohs(tvb, offset);
2448
2449         if(parent_tree){
2450                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2451                         "Open Function: 0x%04x", mask);
2452                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2453         }
2454
2455         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2456                 tvb, offset, 2, mask);
2457         proto_tree_add_uint(tree, hf_smb_open_function_open,
2458                 tvb, offset, 2, mask);
2459
2460         offset += 2;
2461
2462         return offset;
2463 }
2464
2465
2466 static const true_false_string tfs_mf_file = {
2467         "Target must be a file",
2468         "Target needn't be a file"
2469  };
2470 static const true_false_string tfs_mf_dir = {
2471         "Target must be a directory",
2472         "Target needn't be a directory"
2473 };
2474 static const true_false_string tfs_mf_verify = {
2475         "MUST verify all writes",
2476         "Don't have to verify writes"
2477 };
2478 static int
2479 dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2480 {
2481         guint16 mask;
2482         proto_item *item = NULL;
2483         proto_tree *tree = NULL;
2484
2485         mask = tvb_get_letohs(tvb, offset);
2486
2487         if(parent_tree){
2488                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2489                         "Flags: 0x%04x", mask);
2490                 tree = proto_item_add_subtree(item, ett_smb_move_flags);
2491         }
2492  
2493         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2494                 tvb, offset, 2, mask);
2495         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2496                 tvb, offset, 2, mask);
2497         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2498                 tvb, offset, 2, mask);
2499
2500         offset += 2;
2501
2502         return offset;
2503 }
2504
2505 static int
2506 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2507 {
2508         int fn_len;
2509         guint16 tid;
2510         guint16 bc;
2511         guint8 wc;
2512         const char *fn;
2513
2514         WORD_COUNT;
2515
2516         /* tid */
2517         tid = tvb_get_letohs(tvb, offset);
2518         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2519                 "TID (target): 0x%04x", tid);
2520         offset += 2;
2521
2522         /* open function */
2523         offset = dissect_open_function(tvb, pinfo, tree, offset);
2524
2525         /* move flags */
2526         offset = dissect_move_flags(tvb, pinfo, tree, offset);
2527
2528         BYTE_COUNT;
2529
2530         /* buffer format */
2531         CHECK_BYTE_COUNT(1);
2532         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2533         COUNT_BYTES(1);
2534
2535         /* file name */
2536         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2537                 FALSE, FALSE, &bc);
2538         if (fn == NULL)
2539                 goto endofcommand;
2540         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2541                 fn_len, fn, "Old File Name: %s", fn);
2542         COUNT_BYTES(fn_len);
2543
2544         if (check_col(pinfo->cinfo, COL_INFO)) {
2545                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2546         }
2547
2548         /* buffer format */
2549         CHECK_BYTE_COUNT(1);
2550         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2551         COUNT_BYTES(1);
2552
2553         /* file name */
2554         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2555                 FALSE, FALSE, &bc);
2556         if (fn == NULL)
2557                 goto endofcommand;
2558         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2559                 fn_len, fn, "New File Name: %s", fn);
2560         COUNT_BYTES(fn_len);
2561
2562         if (check_col(pinfo->cinfo, COL_INFO)) {
2563                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2564         }
2565
2566         END_OF_SMB
2567
2568         return offset;
2569 }
2570
2571 static int
2572 dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2573 {
2574         int fn_len;
2575         const char *fn;
2576         guint8 wc;
2577         guint16 bc;
2578
2579         WORD_COUNT;
2580
2581         /* # of files moved */
2582         proto_tree_add_item(tree, hf_smb_move_files_moved, tvb, offset, 2, TRUE);
2583         offset += 2;
2584
2585         BYTE_COUNT;
2586
2587         /* buffer format */
2588         CHECK_BYTE_COUNT(1);
2589         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2590         COUNT_BYTES(1);
2591
2592         /* file name */
2593         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2594                 FALSE, FALSE, &bc);
2595         if (fn == NULL)
2596                 goto endofcommand;
2597         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2598                 fn);
2599         COUNT_BYTES(fn_len);
2600
2601         END_OF_SMB
2602
2603         return offset;
2604 }
2605
2606 static int
2607 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2608 {
2609         int fn_len;
2610         const char *fn;
2611         guint8 wc;
2612         guint16 bc;
2613
2614         WORD_COUNT;
2615
2616         /* desired access */
2617         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
2618
2619         /* Search Attributes */
2620         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2621
2622         BYTE_COUNT;
2623
2624         /* buffer format */
2625         CHECK_BYTE_COUNT(1);
2626         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2627         COUNT_BYTES(1);
2628
2629         /* file name */
2630         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2631                 FALSE, FALSE, &bc);
2632         if (fn == NULL)
2633                 goto endofcommand;
2634         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2635                 fn);
2636         COUNT_BYTES(fn_len);
2637
2638         if (check_col(pinfo->cinfo, COL_INFO)) {
2639                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2640         }
2641
2642         END_OF_SMB
2643
2644         return offset;
2645 }
2646
2647 void
2648 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2649     int len, guint16 fid)
2650 {
2651         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2652         if (check_col(pinfo->cinfo, COL_INFO))
2653                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2654 }
2655
2656 static int
2657 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2658 {
2659         guint8 wc;
2660         guint16 bc;
2661         guint16 fid;
2662
2663         WORD_COUNT;
2664
2665         /* fid */
2666         fid = tvb_get_letohs(tvb, offset);
2667         add_fid(tvb, pinfo, tree, offset, 2, fid);
2668         offset += 2;
2669
2670         /* File Attributes */
2671         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2672
2673         /* last write time */
2674         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2675         
2676         /* File Size */
2677         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2678         offset += 4;
2679
2680         /* granted access */
2681         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
2682
2683         BYTE_COUNT;
2684
2685         END_OF_SMB
2686
2687         return offset;
2688 }
2689
2690 static int
2691 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2692 {
2693         guint8 wc;
2694         guint16 bc;
2695         guint16 fid;
2696
2697         WORD_COUNT;
2698
2699         /* fid */
2700         fid = tvb_get_letohs(tvb, offset);
2701         add_fid(tvb, pinfo, tree, offset, 2, fid);
2702         offset += 2;
2703
2704         BYTE_COUNT;
2705
2706         END_OF_SMB
2707
2708         return offset;
2709 }
2710
2711 static int
2712 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2713 {
2714         int fn_len;
2715         const char *fn;
2716         guint8 wc;
2717         guint16 bc;
2718
2719         WORD_COUNT;
2720
2721         /* file attributes */
2722         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2723
2724         /* creation time */
2725         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
2726
2727         BYTE_COUNT;
2728
2729         /* buffer format */
2730         CHECK_BYTE_COUNT(1);
2731         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2732         COUNT_BYTES(1);
2733
2734         /* File Name */
2735         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2736                 FALSE, FALSE, &bc);
2737         if (fn == NULL)
2738                 goto endofcommand;
2739         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2740                 fn);
2741         COUNT_BYTES(fn_len);
2742
2743         if (check_col(pinfo->cinfo, COL_INFO)) {
2744                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2745         }
2746
2747         END_OF_SMB
2748
2749         return offset;
2750 }
2751
2752 static int
2753 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2754 {
2755         guint8 wc;
2756         guint16 bc, fid;
2757
2758         WORD_COUNT;
2759
2760         /* fid */
2761         fid = tvb_get_letohs(tvb, offset);
2762         add_fid(tvb, pinfo, tree, offset, 2, fid);
2763         offset += 2;
2764
2765         /* last write time */
2766         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2767
2768         BYTE_COUNT;
2769
2770         END_OF_SMB
2771
2772         return offset;
2773 }
2774
2775 static int
2776 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2777 {
2778         int fn_len;
2779         const char *fn;
2780         guint8 wc;
2781         guint16 bc;
2782
2783         WORD_COUNT;
2784
2785         /* search attributes */
2786         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2787
2788         BYTE_COUNT;
2789
2790         /* buffer format */
2791         CHECK_BYTE_COUNT(1);
2792         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2793         COUNT_BYTES(1);
2794
2795         /* file name */
2796         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2797                 FALSE, FALSE, &bc);
2798         if (fn == NULL)
2799                 goto endofcommand;
2800         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2801                 fn);
2802         COUNT_BYTES(fn_len);
2803
2804         if (check_col(pinfo->cinfo, COL_INFO)) {
2805                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2806         }
2807
2808         END_OF_SMB
2809
2810         return offset;
2811 }
2812
2813 static int
2814 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2815 {
2816         int fn_len;
2817         const char *fn;
2818         guint8 wc;
2819         guint16 bc;
2820
2821         WORD_COUNT;
2822
2823         /* search attributes */
2824         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2825
2826         BYTE_COUNT;
2827
2828         /* buffer format */
2829         CHECK_BYTE_COUNT(1);
2830         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2831         COUNT_BYTES(1);
2832
2833         /* old file name */
2834         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2835                 FALSE, FALSE, &bc);
2836         if (fn == NULL)
2837                 goto endofcommand;
2838         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2839                 fn);
2840         COUNT_BYTES(fn_len);
2841
2842         if (check_col(pinfo->cinfo, COL_INFO)) {
2843                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2844         }
2845
2846         /* buffer format */
2847         CHECK_BYTE_COUNT(1);
2848         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2849         COUNT_BYTES(1);
2850
2851         /* file name */
2852         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2853                 FALSE, FALSE, &bc);
2854         if (fn == NULL)
2855                 goto endofcommand;
2856         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2857                 fn);
2858         COUNT_BYTES(fn_len);
2859
2860         if (check_col(pinfo->cinfo, COL_INFO)) {
2861                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2862         }
2863
2864         END_OF_SMB
2865
2866         return offset;
2867 }
2868
2869 static int
2870 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2871 {
2872         guint16 bc;
2873         guint8 wc;
2874         const char *fn;
2875         int fn_len;
2876
2877         WORD_COUNT;
2878
2879         BYTE_COUNT;
2880
2881         /* Buffer Format */
2882         CHECK_BYTE_COUNT(1);
2883         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2884         COUNT_BYTES(1);
2885
2886         /* File Name */
2887         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2888                 FALSE, FALSE, &bc);
2889         if (fn == NULL)
2890                 goto endofcommand;
2891         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2892                 fn);
2893         COUNT_BYTES(fn_len);
2894
2895         if (check_col(pinfo->cinfo, COL_INFO)) {
2896                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2897         }
2898
2899         END_OF_SMB
2900
2901         return offset;
2902 }
2903  
2904 static int
2905 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2906 {
2907         guint16 bc;
2908         guint8 wc;
2909
2910         WORD_COUNT;
2911
2912         /* File Attributes */
2913         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2914
2915         /* Last Write Time */
2916         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2917
2918         /* File Size */
2919         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2920         offset += 4;
2921
2922         /* 10 reserved bytes */
2923         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2924         offset += 10;
2925
2926         BYTE_COUNT;
2927
2928         END_OF_SMB
2929
2930         return offset;
2931 }
2932
2933 static int
2934 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2935 {
2936         int fn_len;
2937         const char *fn;
2938         guint8 wc;
2939         guint16 bc;
2940
2941         WORD_COUNT;
2942
2943         /* file attributes */
2944         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2945
2946         /* last write time */
2947         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2948
2949         /* 10 reserved bytes */
2950         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2951         offset += 10;
2952
2953         BYTE_COUNT;
2954
2955         /* buffer format */
2956         CHECK_BYTE_COUNT(1);
2957         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2958         COUNT_BYTES(1);
2959
2960         /* file name */
2961         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2962                 FALSE, FALSE, &bc);
2963         if (fn == NULL)
2964                 goto endofcommand;
2965         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2966                 fn);
2967         COUNT_BYTES(fn_len);
2968
2969         if (check_col(pinfo->cinfo, COL_INFO)) {
2970                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2971         }
2972
2973         END_OF_SMB
2974
2975         return offset;
2976 }
2977
2978 static int
2979 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2980 {
2981         guint8 wc;
2982         guint16 bc, fid;
2983
2984         WORD_COUNT;
2985
2986         /* fid */
2987         fid = tvb_get_letohs(tvb, offset);
2988         add_fid(tvb, pinfo, tree, offset, 2, fid);
2989         offset += 2;
2990
2991         /* read count */
2992         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
2993         offset += 2;
2994
2995         /* offset */
2996         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
2997         offset += 4;
2998
2999         /* remaining */
3000         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3001         offset += 2;
3002
3003         BYTE_COUNT;
3004
3005         END_OF_SMB
3006
3007         return offset;
3008 }
3009
3010 int
3011 dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3012 {
3013         int tvblen;
3014
3015         if(bc>datalen){
3016                 /* We have some initial padding bytes. */
3017                 /* XXX - use the data offset here instead? */
3018                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3019                         TRUE);
3020                 offset += bc-datalen;
3021                 bc = datalen;
3022         }
3023         tvblen = tvb_length_remaining(tvb, offset);
3024         if(bc>tvblen){
3025                 proto_tree_add_bytes_format(tree, hf_smb_file_data, tvb, offset, tvblen, tvb_get_ptr(tvb, offset, tvblen),"File Data: Incomplete. Only %d of %u bytes", tvblen, bc);
3026                 offset += tvblen;
3027         } else {
3028                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3029                 offset += bc;
3030         }
3031         return offset;
3032 }
3033
3034 static int
3035 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3036 {
3037         guint16 cnt=0, bc;
3038         guint8 wc;
3039
3040         WORD_COUNT;
3041
3042         /* read count */
3043         cnt = tvb_get_letohs(tvb, offset);
3044         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3045         offset += 2;
3046
3047         /* 8 reserved bytes */
3048         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3049         offset += 8;
3050
3051         BYTE_COUNT;
3052
3053         /* buffer format */
3054         CHECK_BYTE_COUNT(1);
3055         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3056         COUNT_BYTES(1);
3057
3058         /* data len */
3059         CHECK_BYTE_COUNT(2);
3060         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3061         COUNT_BYTES(2);
3062
3063         if (bc != 0) {
3064                 /* file data */
3065                 offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3066                 bc = 0;
3067         }
3068
3069         END_OF_SMB
3070
3071         return offset;
3072 }
3073
3074 static int
3075 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3076 {
3077         guint16 cnt, bc;
3078         guint8 wc;
3079
3080         WORD_COUNT;
3081
3082         /* read count */
3083         cnt = tvb_get_letohs(tvb, offset);
3084         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3085         offset += 2;
3086
3087         /* 8 reserved bytes */
3088         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3089         offset += 8;
3090
3091         BYTE_COUNT;
3092
3093         /* buffer format */
3094         CHECK_BYTE_COUNT(1);
3095         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3096         COUNT_BYTES(1);
3097
3098         /* data len */
3099         CHECK_BYTE_COUNT(2);
3100         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3101         COUNT_BYTES(2);
3102
3103         END_OF_SMB
3104
3105         return offset;
3106 }
3107
3108
3109 static int
3110 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3111 {
3112         guint32 ofs=0;
3113         guint16 cnt=0, bc, fid;
3114         guint8 wc;
3115
3116         WORD_COUNT;
3117
3118         /* fid */
3119         fid = tvb_get_letohs(tvb, offset);
3120         add_fid(tvb, pinfo, tree, offset, 2, fid);
3121         offset += 2;
3122
3123         /* write count */
3124         cnt = tvb_get_letohs(tvb, offset);
3125         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3126         offset += 2;
3127
3128         /* offset */
3129         ofs = tvb_get_letohl(tvb, offset);
3130         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3131         offset += 4;
3132
3133         if (check_col(pinfo->cinfo, COL_INFO))
3134                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3135                                 ", %d byte%s at offset %d", cnt, 
3136                                 (cnt == 1) ? "" : "s", ofs);
3137
3138         /* remaining */
3139         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3140         offset += 2;
3141
3142         BYTE_COUNT;
3143
3144         /* buffer format */
3145         CHECK_BYTE_COUNT(1);
3146         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3147         COUNT_BYTES(1);
3148
3149         /* data len */
3150         CHECK_BYTE_COUNT(2);
3151         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3152         COUNT_BYTES(2);
3153
3154         if (bc != 0) {
3155                 /* file data */
3156                 offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
3157                 bc = 0;
3158         }
3159
3160         END_OF_SMB
3161
3162         return offset;
3163 }
3164  
3165 static int
3166 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3167 {
3168         guint8 wc;
3169         guint16 bc, cnt;
3170
3171         WORD_COUNT;
3172
3173         /* write count */
3174         cnt = tvb_get_letohs(tvb, offset);
3175         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3176         offset += 2;
3177
3178         if (check_col(pinfo->cinfo, COL_INFO))
3179                 col_append_fstr(pinfo->cinfo, COL_INFO, 
3180                                 ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
3181
3182         BYTE_COUNT;
3183
3184         END_OF_SMB
3185
3186         return offset;
3187 }
3188
3189 static int
3190 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3191 {
3192         guint8 wc;
3193         guint16 bc, fid;
3194
3195         WORD_COUNT;
3196
3197         /* fid */
3198         fid = tvb_get_letohs(tvb, offset);
3199         add_fid(tvb, pinfo, tree, offset, 2, fid);
3200         offset += 2;
3201
3202         /* lock count */
3203         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3204         offset += 4;
3205
3206         /* offset */
3207         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3208         offset += 4;
3209
3210         BYTE_COUNT;
3211
3212         END_OF_SMB
3213
3214         return offset;
3215 }
3216
3217 static int
3218 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3219 {
3220         int fn_len;
3221         const char *fn;
3222         guint8 wc;
3223         guint16 bc;
3224
3225         WORD_COUNT;
3226
3227         /* 2 reserved bytes */
3228         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3229         offset += 2;
3230
3231         /* Creation time */
3232         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
3233
3234         BYTE_COUNT;
3235
3236         /* buffer format */
3237         CHECK_BYTE_COUNT(1);
3238         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3239         COUNT_BYTES(1);
3240
3241         /* directory name */
3242         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3243                 FALSE, FALSE, &bc);
3244         if (fn == NULL)
3245                 goto endofcommand;
3246         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3247                 fn);
3248         COUNT_BYTES(fn_len);
3249
3250         if (check_col(pinfo->cinfo, COL_INFO)) {
3251                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3252         }
3253
3254         END_OF_SMB
3255
3256         return offset;
3257 }
3258
3259 static int
3260 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3261 {
3262         int fn_len;
3263         const char *fn;
3264         guint8 wc;
3265         guint16 bc, fid;
3266
3267         WORD_COUNT;
3268
3269         /* fid */
3270         fid = tvb_get_letohs(tvb, offset);
3271         add_fid(tvb, pinfo, tree, offset, 2, fid);
3272         offset += 2;
3273
3274         BYTE_COUNT;
3275
3276         /* buffer format */
3277         CHECK_BYTE_COUNT(1);
3278         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3279         COUNT_BYTES(1);
3280
3281         /* file name */
3282         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3283                 FALSE, FALSE, &bc);
3284         if (fn == NULL)
3285                 goto endofcommand;
3286         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3287                 fn);
3288         COUNT_BYTES(fn_len);
3289
3290         END_OF_SMB
3291
3292         return offset;
3293 }
3294
3295 static const value_string seek_mode_vals[] = {
3296         {0,     "From Start Of File"},
3297         {1,     "From Current Position"},
3298         {2,     "From End Of File"},
3299         {0,     NULL}
3300 };
3301
3302 static int
3303 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3304 {
3305         guint8 wc;
3306         guint16 bc, fid;
3307
3308         WORD_COUNT;
3309
3310         /* fid */
3311         fid = tvb_get_letohs(tvb, offset);
3312         add_fid(tvb, pinfo, tree, offset, 2, fid);
3313         offset += 2;
3314
3315         /* Seek Mode */
3316         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3317         offset += 2;
3318
3319         /* offset */
3320         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3321         offset += 4;
3322
3323         BYTE_COUNT;
3324
3325         END_OF_SMB
3326
3327         return offset;
3328 }
3329
3330 static int
3331 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3332 {
3333         guint8 wc;
3334         guint16 bc;
3335
3336         WORD_COUNT;
3337
3338         /* offset */
3339         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3340         offset += 4;
3341
3342         BYTE_COUNT;
3343
3344         END_OF_SMB
3345
3346         return offset;
3347 }
3348  
3349 static int
3350 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3351 {
3352         guint8 wc;
3353         guint16 bc, fid;
3354
3355         WORD_COUNT;
3356
3357         /* fid */
3358         fid = tvb_get_letohs(tvb, offset);
3359         add_fid(tvb, pinfo, tree, offset, 2, fid);
3360         offset += 2;
3361
3362         /* create time */
3363         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3364                 hf_smb_create_time,
3365                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3366
3367         /* access time */
3368         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3369                 hf_smb_access_time,
3370                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3371
3372         /* last write time */
3373         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3374                 hf_smb_last_write_time,
3375                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3376
3377         BYTE_COUNT;
3378
3379         END_OF_SMB
3380
3381         return offset;
3382 }
3383
3384 static int
3385 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3386 {
3387         guint8 wc;
3388         guint16 bc;
3389
3390         WORD_COUNT;
3391
3392         /* create time */
3393         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3394                 hf_smb_create_time,
3395                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3396
3397         /* access time */
3398         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3399                 hf_smb_access_time,
3400                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3401
3402         /* last write time */
3403         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3404                 hf_smb_last_write_time,
3405                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3406
3407         /* data size */
3408         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3409         offset += 4;
3410
3411         /* allocation size */
3412         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3413         offset += 4;
3414
3415         /* File Attributes */
3416         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3417
3418         BYTE_COUNT;
3419
3420         END_OF_SMB
3421
3422         return offset;
3423 }
3424
3425 static int
3426 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3427 {
3428         guint8 wc;
3429         guint16 cnt=0;
3430         guint16 bc, fid;
3431
3432         WORD_COUNT;
3433
3434         /* fid */
3435         fid = tvb_get_letohs(tvb, offset);
3436         add_fid(tvb, pinfo, tree, offset, 2, fid);
3437         offset += 2;
3438
3439         /* write count */
3440         cnt = tvb_get_letohs(tvb, offset);
3441         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3442         offset += 2;
3443
3444         /* offset */
3445         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3446         offset += 4;
3447
3448         /* last write time */
3449         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3450         
3451         if(wc==12){
3452                 /* 12 reserved bytes */
3453                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3454                 offset += 12;
3455         }
3456
3457         BYTE_COUNT;
3458
3459         /* 1 pad byte */
3460         CHECK_BYTE_COUNT(1);
3461         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3462         COUNT_BYTES(1);
3463         
3464         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
3465         bc = 0; /* XXX */
3466
3467         END_OF_SMB
3468
3469         return offset;
3470 }
3471  
3472 static int
3473 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3474 {
3475         guint8 wc;
3476         guint16 bc;
3477
3478         WORD_COUNT;
3479
3480         /* write count */
3481         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3482         offset += 2;
3483
3484         BYTE_COUNT;
3485
3486         END_OF_SMB
3487
3488         return offset;
3489 }
3490
3491 static int
3492 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3493 {
3494         guint8 wc;
3495         guint16 bc, fid;
3496         guint32 to;
3497
3498         WORD_COUNT;
3499
3500         /* fid */
3501         fid = tvb_get_letohs(tvb, offset);
3502         add_fid(tvb, pinfo, tree, offset, 2, fid);
3503         offset += 2;
3504
3505         /* offset */
3506         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3507         offset += 4;
3508
3509         /* max count */
3510         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3511         offset += 2;
3512
3513         /* min count */
3514         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3515         offset += 2;
3516
3517         /* timeout */
3518         to = tvb_get_letohl(tvb, offset);
3519         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3520         offset += 4;
3521
3522         /* 2 reserved bytes */
3523         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3524         offset += 2;
3525
3526         if(wc==10){
3527                 /* high offset */
3528                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3529                 offset += 4;
3530         }
3531
3532         BYTE_COUNT;
3533
3534         END_OF_SMB
3535
3536         return offset;
3537 }
3538
3539 static int
3540 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3541 {
3542         guint8 wc;
3543         guint16 bc;
3544
3545         WORD_COUNT;
3546
3547         /* units */
3548         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3549         offset += 2;
3550
3551         /* bpu */
3552         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3553         offset += 2;
3554
3555         /* block size */
3556         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3557         offset += 2;
3558
3559         /* free units */
3560         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3561         offset += 2;
3562
3563         /* 2 reserved bytes */
3564         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3565         offset += 2;
3566
3567         BYTE_COUNT;
3568
3569         END_OF_SMB
3570
3571         return offset;
3572 }
3573
3574 static int
3575 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3576 {
3577         guint8 wc;
3578         guint16 bc, fid;
3579
3580         WORD_COUNT;
3581
3582         /* fid */
3583         fid = tvb_get_letohs(tvb, offset);
3584         add_fid(tvb, pinfo, tree, offset, 2, fid);
3585         offset += 2;
3586
3587         /* offset */
3588         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3589         offset += 4;
3590
3591         /* max count */
3592         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3593         offset += 2;
3594
3595         /* min count */
3596         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3597         offset += 2;
3598
3599         /* 6 reserved bytes */
3600         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3601         offset += 6;
3602
3603         BYTE_COUNT;
3604
3605         END_OF_SMB
3606
3607         return offset;
3608 }
3609
3610 static int
3611 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3612 {
3613         guint16 datalen=0, bc;
3614         guint8 wc;
3615
3616         WORD_COUNT;
3617
3618         /* offset */
3619         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3620         offset += 4;
3621
3622         /* count */
3623         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3624         offset += 2;
3625
3626         /* 2 reserved bytes */
3627         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3628         offset += 2;
3629
3630         /* data compaction mode */
3631         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3632         offset += 2;
3633
3634         /* 2 reserved bytes */
3635         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3636         offset += 2;
3637
3638         /* data len */
3639         datalen = tvb_get_letohs(tvb, offset);
3640         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3641         offset += 2;
3642
3643         /* data offset */
3644         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3645         offset += 2;
3646
3647         BYTE_COUNT;
3648
3649         /* file data */
3650         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3651         bc = 0;
3652
3653         END_OF_SMB
3654
3655         return offset;
3656 }
3657
3658
3659 static const true_false_string tfs_write_mode_write_through = {
3660         "WRITE THROUGH requested",
3661         "Write through not requested"
3662 };
3663 static const true_false_string tfs_write_mode_return_remaining = {
3664         "RETURN REMAINING (pipe/dev) requested",
3665         "DON'T return remaining (pipe/dev)"
3666 };
3667 static const true_false_string tfs_write_mode_raw = {
3668         "Use WriteRawNamedPipe (pipe)",
3669         "DON'T use WriteRawNamedPipe (pipe)"
3670 };
3671 static const true_false_string tfs_write_mode_message_start = {
3672         "This is the START of a MESSAGE (pipe)",
3673         "This is NOT the start of a message (pipe)"
3674 };
3675 static const true_false_string tfs_write_mode_connectionless = {
3676         "CONNECTIONLESS mode requested",
3677         "Connectionless mode NOT requested"
3678 };
3679 static int
3680 dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
3681 {
3682         guint16 mask;
3683         proto_item *item = NULL;
3684         proto_tree *tree = NULL;
3685
3686         mask = tvb_get_letohs(tvb, offset);
3687
3688         if(parent_tree){
3689                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3690                         "Write Mode: 0x%04x", mask);
3691                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3692         }
3693
3694         if(bm&0x0080){
3695                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3696                         tvb, offset, 2, mask);
3697         }
3698         if(bm&0x0008){
3699                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3700                         tvb, offset, 2, mask);
3701         }
3702         if(bm&0x0004){
3703                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3704                         tvb, offset, 2, mask);
3705         }
3706         if(bm&0x0002){
3707                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3708                         tvb, offset, 2, mask);
3709         }
3710         if(bm&0x0001){
3711                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
3712                         tvb, offset, 2, mask);
3713         }
3714
3715         offset += 2;
3716         return offset;
3717 }
3718
3719 static int
3720 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3721 {
3722         guint32 to;
3723         guint16 datalen=0, bc, fid;
3724         guint8 wc;
3725
3726         WORD_COUNT;
3727
3728         /* fid */
3729         fid = tvb_get_letohs(tvb, offset);
3730         add_fid(tvb, pinfo, tree, offset, 2, fid);
3731         offset += 2;
3732
3733         /* total data length */
3734         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3735         offset += 2;
3736
3737         /* 2 reserved bytes */
3738         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3739         offset += 2;
3740
3741         /* offset */
3742         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3743         offset += 4;
3744
3745         /* timeout */
3746         to = tvb_get_letohl(tvb, offset);
3747         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3748         offset += 4;
3749
3750         /* mode */
3751         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
3752
3753         /* 4 reserved bytes */
3754         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
3755         offset += 4;
3756
3757         /* data len */
3758         datalen = tvb_get_letohs(tvb, offset);
3759         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3760         offset += 2;
3761
3762         /* data offset */
3763         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3764         offset += 2;
3765
3766         BYTE_COUNT;
3767
3768         /* file data */
3769         /* XXX - use the data offset to determine where the data starts? */
3770         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3771         bc = 0;
3772
3773         END_OF_SMB
3774
3775         return offset;
3776 }
3777  
3778 static int
3779 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3780 {
3781         guint8 wc;
3782         guint16 bc;
3783
3784         WORD_COUNT;
3785
3786         /* remaining */
3787         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3788         offset += 2;
3789
3790         BYTE_COUNT;
3791
3792         END_OF_SMB
3793
3794         return offset;
3795 }
3796
3797 static int
3798 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3799 {
3800         guint32 to;
3801         guint16 datalen=0, bc, fid;
3802         guint8 wc;
3803
3804         WORD_COUNT;
3805
3806         /* fid */
3807         fid = tvb_get_letohs(tvb, offset);
3808         add_fid(tvb, pinfo, tree, offset, 2, fid);
3809         offset += 2;
3810
3811         /* total data length */
3812         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3813         offset += 2;
3814
3815         /* 2 reserved bytes */
3816         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3817         offset += 2;
3818
3819         /* offset */
3820         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3821         offset += 4;
3822
3823         /* timeout */
3824         to = tvb_get_letohl(tvb, offset);
3825         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3826         offset += 4;
3827
3828         /* mode */
3829         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
3830
3831         /* request mask */
3832         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
3833         offset += 4;
3834         
3835         /* data len */
3836         datalen = tvb_get_letohs(tvb, offset);
3837         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3838         offset += 2;
3839
3840         /* data offset */
3841         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3842         offset += 2;
3843
3844         BYTE_COUNT;
3845
3846         /* file data */
3847         /* XXX - use the data offset to determine where the data starts? */
3848         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3849         bc = 0;
3850
3851         END_OF_SMB
3852
3853         return offset;
3854 }
3855  
3856 static int
3857 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3858 {
3859         guint8 wc;
3860         guint16 bc;
3861
3862         WORD_COUNT;
3863
3864         /* response mask */
3865         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
3866         offset += 4;
3867         
3868         BYTE_COUNT;
3869
3870         END_OF_SMB
3871
3872         return offset;
3873 }
3874
3875 static int
3876 dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3877 {
3878         guint8 wc;
3879         guint16 bc;
3880
3881         WORD_COUNT;
3882
3883         /* sid */
3884         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
3885         offset += 2;
3886
3887         BYTE_COUNT;
3888
3889         END_OF_SMB
3890
3891         return offset;
3892 }
3893
3894 static int
3895 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
3896     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3897 {
3898         proto_item *item = NULL;
3899         proto_tree *tree = NULL;
3900         int fn_len;
3901         const char *fn;
3902         char fname[11+1];
3903
3904         if(parent_tree){
3905                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
3906                         "Resume Key");
3907                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
3908         }
3909
3910         /* reserved byte */
3911         CHECK_BYTE_COUNT_SUBR(1);
3912         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
3913         COUNT_BYTES_SUBR(1);
3914
3915         /* file name */
3916         fn_len = 11;
3917         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3918                 TRUE, TRUE, bcp);
3919         CHECK_STRING_SUBR(fn);
3920         /* ensure that it's null-terminated */
3921         strncpy(fname, fn, 11);
3922         fname[11] = '\0';
3923         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
3924                 fname);
3925         COUNT_BYTES_SUBR(fn_len);
3926
3927         /* server cookie */
3928         CHECK_BYTE_COUNT_SUBR(5);
3929         proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
3930         COUNT_BYTES_SUBR(5);
3931
3932         /* client cookie */
3933         CHECK_BYTE_COUNT_SUBR(4);
3934         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
3935         COUNT_BYTES_SUBR(4);
3936
3937         *trunc = FALSE;
3938         return offset;
3939 }
3940
3941 static int
3942 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
3943     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3944 {
3945         proto_item *item = NULL;
3946         proto_tree *tree = NULL;
3947         int fn_len;
3948         const char *fn;
3949         char fname[13+1];
3950
3951         if(parent_tree){
3952                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
3953                         "Directory Information");
3954                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
3955         }
3956
3957         /* resume key */
3958         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
3959         if (*trunc)
3960                 return offset;
3961
3962         /* File Attributes */
3963         CHECK_BYTE_COUNT_SUBR(1);
3964         offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
3965         *bcp -= 1;
3966
3967         /* last write time */
3968         CHECK_BYTE_COUNT_SUBR(4);
3969         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3970                 hf_smb_last_write_time,
3971                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
3972                 TRUE);
3973         *bcp -= 4;
3974
3975         /* File Size */
3976         CHECK_BYTE_COUNT_SUBR(4);
3977         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3978         COUNT_BYTES_SUBR(4);
3979
3980         /* file name */
3981         fn_len = 13;
3982         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3983                 TRUE, TRUE, bcp);
3984         CHECK_STRING_SUBR(fn);
3985         /* ensure that it's null-terminated */
3986         strncpy(fname, fn, 13);
3987         fname[13] = '\0';
3988         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3989                 fname);
3990         COUNT_BYTES_SUBR(fn_len);
3991
3992         *trunc = FALSE;
3993         return offset;
3994 }
3995
3996
3997 static int
3998 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3999 {
4000         int fn_len;
4001         const char *fn;
4002         guint16 rkl;
4003         guint8 wc;
4004         guint16 bc;
4005         gboolean trunc;
4006
4007         WORD_COUNT;
4008
4009         /* max count */
4010         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4011         offset += 2;
4012
4013         /* Search Attributes */
4014         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4015
4016         BYTE_COUNT;
4017
4018         /* buffer format */
4019         CHECK_BYTE_COUNT(1);
4020         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4021         COUNT_BYTES(1);
4022
4023         /* file name */
4024         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4025                 TRUE, FALSE, &bc);
4026         if (fn == NULL)
4027                 goto endofcommand;
4028         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4029                 fn);
4030         COUNT_BYTES(fn_len);
4031
4032         if (check_col(pinfo->cinfo, COL_INFO)) {
4033                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4034         }
4035
4036         /* buffer format */
4037         CHECK_BYTE_COUNT(1);
4038         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4039         COUNT_BYTES(1);
4040
4041         /* resume key length */
4042         CHECK_BYTE_COUNT(2);
4043         rkl = tvb_get_letohs(tvb, offset);
4044         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4045         COUNT_BYTES(2);
4046
4047         /* resume key */
4048         if(rkl){
4049                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4050                     &bc, &trunc);
4051                 if (trunc)
4052                         goto endofcommand;
4053         }
4054
4055         END_OF_SMB
4056
4057         return offset;
4058 }
4059
4060 static int
4061 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4062 {
4063         guint16 count=0;
4064         guint8 wc;
4065         guint16 bc;
4066         gboolean trunc;
4067
4068         WORD_COUNT;
4069
4070         /* count */
4071         count = tvb_get_letohs(tvb, offset);
4072         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4073         offset += 2;
4074
4075         BYTE_COUNT;
4076
4077         /* buffer format */
4078         CHECK_BYTE_COUNT(1);
4079         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4080         COUNT_BYTES(1);
4081
4082         /* data len */
4083         CHECK_BYTE_COUNT(2);
4084         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4085         COUNT_BYTES(2);
4086
4087         while(count--){
4088                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4089                     &bc, &trunc);
4090                 if (trunc)
4091                         goto endofcommand;
4092         }
4093
4094         END_OF_SMB
4095
4096         return offset;
4097 }
4098
4099 static const value_string locking_ol_vals[] = {
4100         {0,     "Client is not holding oplock on this file"},
4101         {1,     "Level 2 oplock currently held by client"},
4102         {0, NULL}
4103 };
4104
4105 static const true_false_string tfs_lock_type_large = {
4106         "Large file locking format requested",
4107         "Large file locking format not requested"
4108 };
4109 static const true_false_string tfs_lock_type_cancel = {
4110         "Cancel outstanding lock request",
4111         "Don't cancel outstanding lock request"
4112 };
4113 static const true_false_string tfs_lock_type_change = {
4114         "Change lock type",
4115         "Don't change lock type"
4116 };
4117 static const true_false_string tfs_lock_type_oplock = {
4118         "This is an oplock break notification/response",
4119         "This is not an oplock break notification/response"
4120 };
4121 static const true_false_string tfs_lock_type_shared = {
4122         "This is a shared lock",
4123         "This is an exclusive lock"
4124 };
4125 static int
4126 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4127 {
4128         guint8  wc, cmd=0xff, lt=0;
4129         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4130         guint32 to;
4131         proto_item *litem = NULL;
4132         proto_tree *ltree = NULL;
4133         proto_item *it = NULL;
4134         proto_tree *tr = NULL;
4135         int old_offset = offset;
4136
4137         WORD_COUNT;
4138
4139         /* next smb command */
4140         cmd = tvb_get_guint8(tvb, offset);
4141         if(cmd!=0xff){
4142                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4143         } else {
4144                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4145         }
4146         offset += 1;
4147
4148         /* reserved byte */
4149         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4150         offset += 1;
4151
4152         /* andxoffset */
4153         andxoffset = tvb_get_letohs(tvb, offset);
4154         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4155         offset += 2;
4156
4157         /* fid */
4158         fid = tvb_get_letohs(tvb, offset);
4159         add_fid(tvb, pinfo, tree, offset, 2, fid);
4160         offset += 2;
4161
4162         /* lock type */
4163         lt = tvb_get_guint8(tvb, offset);
4164         if(tree){
4165                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4166                         "Lock Type: 0x%02x", lt);
4167                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4168         }
4169         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4170                 tvb, offset, 1, lt);
4171         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4172                 tvb, offset, 1, lt);
4173         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4174                 tvb, offset, 1, lt);
4175         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4176                 tvb, offset, 1, lt);
4177         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4178                 tvb, offset, 1, lt);
4179         offset += 1;
4180
4181         /* oplock level */
4182         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4183         offset += 1;
4184
4185         /* timeout */
4186         to = tvb_get_letohl(tvb, offset);
4187         if (to == 0)
4188                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4189         else if (to == 0xffffffff)
4190                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4191         else
4192                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4193         offset += 4;
4194
4195         /* number of unlocks */
4196         un = tvb_get_letohs(tvb, offset);
4197         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4198         offset += 2;
4199
4200         /* number of locks */
4201         ln = tvb_get_letohs(tvb, offset);
4202         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4203         offset += 2;
4204
4205         BYTE_COUNT;
4206
4207         /* unlocks */
4208         if(un){
4209                 old_offset = offset;
4210
4211                 it = proto_tree_add_text(tree, tvb, offset, -1,
4212                         "Unlocks");
4213                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4214                 while(un--){
4215                         proto_item *litem = NULL;
4216                         proto_tree *ltree = NULL;
4217                         if(lt&0x10){
4218                                 /* large lock format */
4219                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4220                                         "Unlock");
4221                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4222                                 
4223                                 /* PID */
4224                                 CHECK_BYTE_COUNT(2);
4225                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4226                                 COUNT_BYTES(2);
4227
4228                                 /* 2 reserved bytes */
4229                                 CHECK_BYTE_COUNT(2);
4230                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4231                                 COUNT_BYTES(2);
4232
4233                                 /* offset */
4234                                 CHECK_BYTE_COUNT(8);
4235                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4236                                 COUNT_BYTES(8);
4237
4238                                 /* length */
4239                                 CHECK_BYTE_COUNT(8);
4240                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4241                                 COUNT_BYTES(8);
4242                         } else {
4243                                 /* normal lock format */
4244                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4245                                         "Unlock");
4246                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4247                                 
4248                                 /* PID */
4249                                 CHECK_BYTE_COUNT(2);
4250                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4251                                 COUNT_BYTES(2);
4252
4253                                 /* offset */
4254                                 CHECK_BYTE_COUNT(4);
4255                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4256                                 COUNT_BYTES(4);
4257
4258                                 /* lock count */
4259                                 CHECK_BYTE_COUNT(4);
4260                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4261                                 COUNT_BYTES(4);
4262                         }
4263                 }
4264                 proto_item_set_len(it, offset-old_offset);
4265                 it = NULL;
4266         }
4267
4268         /* locks */
4269         if(ln){
4270                 old_offset = offset;
4271
4272                 it = proto_tree_add_text(tree, tvb, offset, -1,
4273                         "Locks");
4274                 tr = proto_item_add_subtree(it, ett_smb_locks);
4275                 while(ln--){
4276                         proto_item *litem = NULL;
4277                         proto_tree *ltree = NULL;
4278                         if(lt&0x10){
4279                                 /* large lock format */
4280                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4281                                         "Lock");
4282                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4283                                 
4284                                 /* PID */
4285                                 CHECK_BYTE_COUNT(2);
4286                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4287                                 COUNT_BYTES(2);
4288
4289                                 /* 2 reserved bytes */
4290                                 CHECK_BYTE_COUNT(2);
4291                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4292                                 COUNT_BYTES(2);
4293
4294                                 /* offset */
4295                                 CHECK_BYTE_COUNT(8);
4296                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4297                                 COUNT_BYTES(8);
4298
4299                                 /* length */
4300                                 CHECK_BYTE_COUNT(8);
4301                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4302                                 COUNT_BYTES(8);
4303                         } else {
4304                                 /* normal lock format */
4305                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4306                                         "Unlock");
4307                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4308                                 
4309                                 /* PID */
4310                                 CHECK_BYTE_COUNT(2);
4311                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4312                                 COUNT_BYTES(2);
4313
4314                                 /* offset */
4315                                 CHECK_BYTE_COUNT(4);
4316                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4317                                 COUNT_BYTES(4);
4318
4319                                 /* lock count */
4320                                 CHECK_BYTE_COUNT(4);
4321                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4322                                 COUNT_BYTES(4);
4323                         }
4324                 }
4325                 proto_item_set_len(it, offset-old_offset);
4326                 it = NULL;
4327         }
4328
4329         END_OF_SMB
4330
4331         if (it != NULL) {
4332                 /*
4333                  * We ran out of byte count in the middle of dissecting
4334                  * the locks or the unlocks; set the site of the item
4335                  * we were dissecting.
4336                  */
4337                 proto_item_set_len(it, offset-old_offset);
4338         }
4339
4340         /* call AndXCommand (if there are any) */
4341         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4342
4343         return offset;
4344 }
4345
4346 static int
4347 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4348 {
4349         guint8  wc, cmd=0xff;
4350         guint16 andxoffset=0;
4351         guint16 bc;
4352
4353         WORD_COUNT;
4354
4355         /* next smb command */
4356         cmd = tvb_get_guint8(tvb, offset);
4357         if(cmd!=0xff){
4358                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4359         } else {
4360                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4361         }
4362         offset += 1;
4363
4364         /* reserved byte */
4365         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4366         offset += 1;
4367
4368         /* andxoffset */
4369         andxoffset = tvb_get_letohs(tvb, offset);
4370         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4371         offset += 2;
4372
4373         BYTE_COUNT;
4374
4375         END_OF_SMB
4376
4377         /* call AndXCommand (if there are any) */
4378         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4379
4380         return offset;
4381 }
4382
4383
4384 static const value_string oa_open_vals[] = {
4385         { 0,            "No action taken?"},
4386         { 1,            "The file existed and was opened"},
4387         { 2,            "The file did not exist but was created"},
4388         { 3,            "The file existed and was truncated"},
4389         {0,     NULL}
4390 };
4391 static const true_false_string tfs_oa_lock = {
4392         "File is currently opened only by this user",
4393         "File is opened by another user (or mode not supported by server)"
4394 };
4395 static int
4396 dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4397 {
4398         guint16 mask;
4399         proto_item *item = NULL;
4400         proto_tree *tree = NULL;
4401
4402         mask = tvb_get_letohs(tvb, offset);
4403
4404         if(parent_tree){
4405                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4406                         "Action: 0x%04x", mask);
4407                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4408         }
4409
4410         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4411                 tvb, offset, 2, mask);
4412         proto_tree_add_uint(tree, hf_smb_open_action_open,
4413                 tvb, offset, 2, mask);
4414
4415         offset += 2;
4416
4417         return offset;
4418 }
4419
4420 static const true_false_string tfs_open_flags_add_info = {
4421         "Additional information requested",
4422         "Additional information not requested"
4423 };
4424 static const true_false_string tfs_open_flags_ex_oplock = {
4425         "Exclusive oplock requested",
4426         "Exclusive oplock not requested"
4427 };
4428 static const true_false_string tfs_open_flags_batch_oplock = {
4429         "Batch oplock requested",
4430         "Batch oplock not requested"
4431 };
4432 static const true_false_string tfs_open_flags_ealen = {
4433         "Total length of EAs requested",
4434         "Total length of EAs not requested"
4435 };
4436 static int
4437 dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
4438 {
4439         guint16 mask;
4440         proto_item *item = NULL;
4441         proto_tree *tree = NULL;
4442
4443         mask = tvb_get_letohs(tvb, offset);
4444
4445         if(parent_tree){
4446                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4447                         "Flags: 0x%04x", mask);
4448                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4449         }
4450
4451         if(bm&0x0001){
4452                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4453                         tvb, offset, 2, mask);
4454         }
4455         if(bm&0x0002){
4456                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4457                         tvb, offset, 2, mask);
4458         }
4459         if(bm&0x0004){
4460                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4461                         tvb, offset, 2, mask);
4462         }
4463         if(bm&0x0008){
4464                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4465                         tvb, offset, 2, mask);
4466         }
4467
4468         offset += 2;
4469
4470         return offset;
4471 }
4472
4473 static const value_string filetype_vals[] = {
4474         { 0,            "Disk file or directory"},
4475         { 1,            "Named pipe in byte mode"},
4476         { 2,            "Named pipe in message mode"},
4477         { 3,            "Spooled printer"},
4478         {0, NULL}
4479 };
4480 static int
4481 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4482 {
4483         guint8  wc, cmd=0xff;
4484         guint16 andxoffset=0, bc;
4485         int fn_len;
4486         const char *fn;
4487
4488         WORD_COUNT;
4489
4490         /* next smb command */
4491         cmd = tvb_get_guint8(tvb, offset);
4492         if(cmd!=0xff){
4493                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4494         } else {
4495                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4496         }
4497         offset += 1;
4498
4499         /* reserved byte */
4500         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4501         offset += 1;
4502
4503         /* andxoffset */
4504         andxoffset = tvb_get_letohs(tvb, offset);
4505         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4506         offset += 2;
4507
4508         /* open flags */
4509         offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
4510
4511         /* desired access */
4512         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
4513
4514         /* Search Attributes */
4515         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4516
4517         /* File Attributes */
4518         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4519
4520         /* creation time */
4521         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
4522         
4523         /* open function */
4524         offset = dissect_open_function(tvb, pinfo, tree, offset);
4525
4526         /* allocation size */
4527         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4528         offset += 4;
4529
4530         /* 8 reserved bytes */
4531         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4532         offset += 8;
4533
4534         BYTE_COUNT;
4535
4536         /* file name */
4537         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4538                 FALSE, FALSE, &bc);
4539         if (fn == NULL)
4540                 goto endofcommand;
4541         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4542                 fn);
4543         COUNT_BYTES(fn_len);
4544
4545         if (check_col(pinfo->cinfo, COL_INFO)) {
4546                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
4547         }
4548
4549         END_OF_SMB
4550
4551         /* call AndXCommand (if there are any) */
4552         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4553
4554         return offset;
4555 }
4556
4557 static const true_false_string tfs_ipc_state_nonblocking = {
4558         "Reads/writes return immediately if no data available",
4559         "Reads/writes block if no data available"
4560 };
4561 static const value_string ipc_state_endpoint_vals[] = {
4562         { 0,            "Consumer end of pipe"},
4563         { 1,            "Server end of pipe"},
4564         {0,     NULL}
4565 };
4566 static const value_string ipc_state_pipe_type_vals[] = {
4567         { 0,            "Byte stream pipe"},
4568         { 1,            "Message pipe"},
4569         {0,     NULL}
4570 };
4571 static const value_string ipc_state_read_mode_vals[] = {
4572         { 0,            "Read pipe as a byte stream"},
4573         { 1,            "Read messages from pipe"},
4574         {0,     NULL}
4575 };
4576
4577 int
4578 dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
4579     int offset, gboolean setstate)
4580 {
4581         guint16 mask;
4582         proto_item *item = NULL;
4583         proto_tree *tree = NULL;
4584
4585         mask = tvb_get_letohs(tvb, offset);
4586
4587         if(parent_tree){
4588                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4589                         "IPC State: 0x%04x", mask);
4590                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4591         }
4592
4593         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
4594                 tvb, offset, 2, mask);
4595         if (!setstate) {
4596                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
4597                         tvb, offset, 2, mask);
4598                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
4599                         tvb, offset, 2, mask);
4600         }
4601         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
4602                 tvb, offset, 2, mask);
4603         if (!setstate) {
4604                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
4605                         tvb, offset, 2, mask);
4606         }
4607
4608         offset += 2;
4609
4610         return offset;
4611 }
4612
4613 static int
4614 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4615 {
4616         guint8  wc, cmd=0xff;
4617         guint16 andxoffset=0, bc;
4618         guint16 fid;
4619
4620         WORD_COUNT;
4621
4622         /* next smb command */
4623         cmd = tvb_get_guint8(tvb, offset);
4624         if(cmd!=0xff){
4625                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4626         } else {
4627                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4628         }
4629         offset += 1;
4630
4631         /* reserved byte */
4632         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4633         offset += 1;
4634
4635         /* andxoffset */
4636         andxoffset = tvb_get_letohs(tvb, offset);
4637         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4638         offset += 2;
4639
4640         /* fid */
4641         fid = tvb_get_letohs(tvb, offset);
4642         add_fid(tvb, pinfo, tree, offset, 2, fid);
4643         offset += 2;
4644
4645         /* File Attributes */
4646         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4647
4648         /* last write time */
4649         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
4650         
4651         /* File Size */
4652         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4653         offset += 4;
4654
4655         /* granted access */
4656         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
4657
4658         /* File Type */
4659         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
4660         offset += 2;
4661
4662         /* IPC State */
4663         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
4664
4665         /* open_action */
4666         offset = dissect_open_action(tvb, pinfo, tree, offset);
4667
4668         /* server fid */
4669         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
4670         offset += 4;
4671
4672         /* 2 reserved bytes */
4673         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4674         offset += 2;
4675
4676         BYTE_COUNT;
4677
4678         END_OF_SMB
4679
4680         /* call AndXCommand (if there are any) */
4681         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4682
4683         return offset;
4684 }
4685
4686 static int
4687 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4688 {
4689         guint8  wc, cmd=0xff;
4690         guint16 andxoffset=0, bc, maxcnt = 0;
4691         guint32 ofs = 0;
4692         smb_info_t *si;
4693         unsigned int fid;
4694
4695         WORD_COUNT;
4696
4697         /* next smb command */
4698         cmd = tvb_get_guint8(tvb, offset);
4699         if(cmd!=0xff){
4700                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4701         } else {
4702                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4703         }
4704         offset += 1;
4705
4706         /* reserved byte */
4707         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4708         offset += 1;
4709
4710         /* andxoffset */
4711         andxoffset = tvb_get_letohs(tvb, offset);
4712         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4713         offset += 2;
4714
4715         /* fid */
4716         fid = tvb_get_letohs(tvb, offset);
4717         add_fid(tvb, pinfo, tree, offset, 2, fid);
4718         offset += 2;
4719         if (!pinfo->fd->flags.visited) {
4720                 /* remember the FID for the processing of the response */
4721                 si = (smb_info_t *)pinfo->private_data;
4722                 si->sip->extra_info=(void *)fid;
4723         }
4724
4725         /* offset */
4726         ofs = tvb_get_letohl(tvb, offset);
4727         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4728         offset += 4;
4729
4730         /* max count */
4731         maxcnt = tvb_get_letohs(tvb, offset);
4732         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4733         offset += 2;
4734
4735         if (check_col(pinfo->cinfo, COL_INFO))
4736                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4737                                 ", %d byte%s at offset %d", maxcnt, 
4738                                 (maxcnt == 1) ? "" : "s", ofs);
4739
4740         /* min count */
4741         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4742         offset += 2;
4743
4744         /* XXX - max count high */
4745         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4746         offset += 4;
4747
4748         /* remaining */
4749         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4750         offset += 2;
4751
4752         if(wc==12){
4753                 /* high offset */
4754                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4755                 offset += 4;
4756         }
4757
4758         BYTE_COUNT;
4759
4760         END_OF_SMB
4761
4762         /* call AndXCommand (if there are any) */
4763         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4764
4765         return offset;
4766 }
4767
4768 static int
4769 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4770 {
4771         guint8  wc, cmd=0xff;
4772         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
4773         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4774
4775         WORD_COUNT;
4776
4777         /* next smb command */
4778         cmd = tvb_get_guint8(tvb, offset);
4779         if(cmd!=0xff){
4780                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4781         } else {
4782                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4783         }
4784         offset += 1;
4785  
4786         /* reserved byte */
4787         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4788         offset += 1;
4789
4790         /* andxoffset */
4791         andxoffset = tvb_get_letohs(tvb, offset);
4792         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4793         offset += 2;
4794
4795         /* If we have seen the request, then print which FID this refers to */
4796         /* first check if we have seen the request */
4797         if(si->sip != NULL && si->sip->frame_req>0){
4798                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
4799         }
4800
4801         /* remaining */
4802         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4803         offset += 2;
4804
4805         /* data compaction mode */
4806         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4807         offset += 2;
4808
4809         /* 2 reserved bytes */
4810         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4811         offset += 2;
4812
4813         /* data len */
4814         datalen = tvb_get_letohs(tvb, offset);
4815         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4816         offset += 2;
4817
4818         if (check_col(pinfo->cinfo, COL_INFO))
4819                 col_append_fstr(pinfo->cinfo, COL_INFO, 
4820                                 ", %d byte%s", datalen, 
4821                                 (datalen == 1) ? "" : "s");
4822
4823         /* data offset */
4824         dataoffset=tvb_get_letohs(tvb, offset);
4825         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
4826         offset += 2;
4827
4828         /* 10 reserved bytes */
4829         /* XXX - first 2 bytes are data length high, not reserved */
4830         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4831         offset += 10;
4832
4833         BYTE_COUNT;
4834
4835         /* is this part of DCERPC over SMB reassembly?*/
4836         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
4837             && (bc<=tvb_length_remaining(tvb, offset)) ){
4838                 gpointer hash_value;
4839                 if (si->sip != NULL && (hash_value = g_hash_table_lookup(
4840                                                 si->ct->dcerpc_fid_to_frame,
4841                                                 si->sip->extra_info)) != NULL) {
4842                         fragment_data *fd_head;
4843                         guint32 frame = GPOINTER_TO_UINT(hash_value);
4844
4845                         /* first fragment is always from a SMB Trans command and
4846                            offset 0 of the following read/write SMB commands start
4847                            BEYOND the first Trans SMB payload. Look for offset
4848                            in first read fragment */
4849                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
4850                         if(fd_head){
4851                                 /* skip to last fragment  and add this data there*/
4852                                 while(fd_head->next){
4853                                         fd_head=fd_head->next;
4854                                 }
4855                                 /* if dataoffset was not specified in the SMB command
4856                                    then we try to guess it as good as we can
4857                                 */
4858                                 if(dataoffset==0){
4859                                         dataoffset=offset+bc-datalen;
4860                                 }
4861                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
4862                                         frame, dcerpc_fragment_table,
4863                                         fd_head->offset+fd_head->len, 
4864                                         datalen, TRUE);
4865                                 /* we completed reassembly, abort searching for more 
4866                                    fragments*/
4867                                 if(fd_head){
4868                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
4869                                                 si->sip->extra_info);   
4870                                 }
4871                         }
4872                 }
4873         }
4874
4875         /* file data */
4876         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
4877         bc = 0;
4878
4879         END_OF_SMB
4880
4881         /* call AndXCommand (if there are any) */
4882         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4883
4884         return offset;
4885 }
4886
4887 static int
4888 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4889 {
4890         guint8  wc, cmd=0xff;
4891         guint16 andxoffset=0, bc, datalen=0, dataoffset=0;
4892         smb_info_t *si = (smb_info_t *)pinfo->private_data;
4893         unsigned int fid;
4894
4895         WORD_COUNT;
4896
4897         /* next smb command */
4898         cmd = tvb_get_guint8(tvb, offset);
4899         if(cmd!=0xff){
4900                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4901         } else {
4902                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4903         }
4904         offset += 1;
4905
4906         /* reserved byte */
4907         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4908         offset += 1;
4909
4910         /* andxoffset */
4911         andxoffset = tvb_get_letohs(tvb, offset);
4912         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4913         offset += 2;
4914
4915         /* fid */
4916         fid = tvb_get_letohs(tvb, offset);
4917         add_fid(tvb, pinfo, tree, offset, 2, fid);
4918         offset += 2;
4919         if (!pinfo->fd->flags.visited) {
4920                 /* remember the FID for the processing of the response */
4921                 si->sip->extra_info=(void *)fid;
4922         }
4923
4924         /* offset */
4925         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4926         offset += 4;
4927
4928         /* reserved */
4929         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4930         offset += 4;
4931
4932         /* mode */
4933         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
4934
4935         /* remaining */
4936         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4937         offset += 2;
4938
4939         /* XXX - data length high */
4940         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4941         offset += 2;
4942
4943         /* data len */
4944         datalen = tvb_get_letohs(tvb, offset);
4945         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4946         offset += 2;
4947
4948         /* data offset */
4949         dataoffset=tvb_get_letohs(tvb, offset);
4950         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
4951         offset += 2;
4952
4953         /* FIXME: add byte/offset to COL_INFO */
4954
4955         if(wc==14){
4956                 /* high offset */
4957                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4958                 offset += 4;
4959         }
4960
4961         BYTE_COUNT;
4962
4963         /* is this part of DCERPC over SMB reassembly?*/
4964         if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
4965                 gpointer hash_value;
4966                 hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
4967                         si->sip->extra_info);
4968                 if(hash_value){
4969                         fragment_data *fd_head;
4970                         guint32 frame = GPOINTER_TO_UINT(hash_value);
4971
4972                         /* first fragment is always from a SMB Trans command and
4973                            offset 0 of the following read/write SMB commands start
4974                            BEYOND the first Trans SMB payload. Look for offset
4975                            in first read fragment */
4976                         fd_head=fragment_get(pinfo, frame, dcerpc_fragment_table);
4977                         if(fd_head){
4978                                 /* skip to last fragment  and add this data there*/
4979                                 while(fd_head->next){
4980                                         fd_head=fd_head->next;
4981                                 }
4982                                 /* if dataoffset was not specified in the SMB command
4983                                    then we try to guess it as good as we can
4984                                 */
4985                                 if(dataoffset==0){
4986                                         dataoffset=offset+bc-datalen;
4987                                 }
4988                                 fd_head=fragment_add(tvb, dataoffset, pinfo,
4989                                         frame, dcerpc_fragment_table,
4990                                         fd_head->offset+fd_head->len, 
4991                                         datalen, TRUE);
4992                                 /* we completed reassembly, abort searching for more 
4993                                    fragments*/
4994                                 if(fd_head){
4995                                         g_hash_table_remove(si->ct->dcerpc_fid_to_frame,
4996                                                 si->sip->extra_info);   
4997                                 }
4998                         }
4999                 }
5000         }
5001
5002         /* file data */
5003         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
5004         bc = 0;
5005
5006         END_OF_SMB
5007
5008         /* call AndXCommand (if there are any) */
5009         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5010
5011         return offset;
5012 }
5013
5014 static int
5015 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5016 {
5017         guint8  wc, cmd=0xff;
5018         guint16 andxoffset=0, bc;
5019         smb_info_t *si;
5020
5021         WORD_COUNT;
5022
5023         /* next smb command */
5024         cmd = tvb_get_guint8(tvb, offset);
5025         if(cmd!=0xff){
5026                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5027         } else {
5028                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5029         }
5030         offset += 1;
5031  
5032         /* reserved byte */
5033         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5034         offset += 1;
5035
5036         /* andxoffset */
5037         andxoffset = tvb_get_letohs(tvb, offset);
5038         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5039         offset += 2;
5040
5041         /* If we have seen the request, then print which FID this refers to */
5042         si = (smb_info_t *)pinfo->private_data;
5043         /* first check if we have seen the request */
5044         if(si->sip != NULL && si->sip->frame_req>0){
5045                 add_fid(tvb, pinfo, tree, 0, 0, (int)si->sip->extra_info);
5046         }
5047
5048         /* write count */
5049         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
5050         offset += 2;
5051
5052         /* remaining */
5053         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5054         offset += 2;
5055
5056         /* 4 reserved bytes */
5057         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5058         offset += 4;
5059
5060         BYTE_COUNT;
5061
5062         END_OF_SMB
5063
5064         /* call AndXCommand (if there are any) */
5065         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5066
5067         return offset;
5068 }
5069
5070
5071 static const true_false_string tfs_setup_action_guest = {
5072         "Logged in as GUEST",
5073         "Not logged in as GUEST"
5074 };
5075 static int
5076 dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5077 {
5078         guint16 mask;
5079         proto_item *item = NULL;
5080         proto_tree *tree = NULL;
5081
5082         mask = tvb_get_letohs(tvb, offset);
5083
5084         if(parent_tree){
5085                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5086                         "Action: 0x%04x", mask);
5087                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5088         }
5089
5090         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5091                 tvb, offset, 2, mask);
5092
5093         offset += 2;
5094
5095         return offset;
5096 }
5097  
5098
5099 static int
5100 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5101 {
5102         guint8  wc, cmd=0xff;
5103         guint16 bc;
5104         guint16 andxoffset=0;
5105         int an_len;
5106         const char *an;
5107         int dn_len;
5108         const char *dn;
5109         guint16 pwlen=0;
5110         guint16 sbloblen=0;
5111         guint16 apwlen=0, upwlen=0;
5112
5113         WORD_COUNT;
5114
5115         /* next smb command */
5116         cmd = tvb_get_guint8(tvb, offset);
5117         if(cmd!=0xff){
5118                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5119         } else {
5120                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5121         }
5122         offset += 1;
5123
5124         /* reserved byte */
5125         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5126         offset += 1;
5127
5128         /* andxoffset */
5129         andxoffset = tvb_get_letohs(tvb, offset);
5130         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5131         offset += 2;
5132
5133         /* Maximum Buffer Size */
5134         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5135         offset += 2;
5136
5137         /* Maximum Multiplex Count */
5138         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5139         offset += 2;
5140
5141         /* VC Number */
5142         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5143         offset += 2;
5144
5145         /* session key */
5146         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5147         offset += 4;
5148
5149         switch (wc) {
5150         case 10:
5151                 /* password length, ASCII*/
5152                 pwlen = tvb_get_letohs(tvb, offset);
5153                 proto_tree_add_uint(tree, hf_smb_password_len,
5154                         tvb, offset, 2, pwlen);
5155                 offset += 2;
5156
5157                 /* 4 reserved bytes */
5158                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5159                 offset += 4;
5160
5161                 break;
5162
5163         case 12:
5164                 /* security blob length */
5165                 sbloblen = tvb_get_letohs(tvb, offset);
5166                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5167                 offset += 2;
5168
5169                 /* 4 reserved bytes */
5170                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5171                 offset += 4;
5172
5173                 /* capabilities */
5174                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5175                 offset += 4;
5176
5177                 break;
5178
5179         case 13:
5180                 /* password length, ANSI*/
5181                 apwlen = tvb_get_letohs(tvb, offset);
5182                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5183                         tvb, offset, 2, apwlen);
5184                 offset += 2;
5185
5186                 /* password length, Unicode*/
5187                 upwlen = tvb_get_letohs(tvb, offset);
5188                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5189                         tvb, offset, 2, upwlen);
5190                 offset += 2;
5191
5192                 /* 4 reserved bytes */
5193                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5194                 offset += 4;
5195
5196                 /* capabilities */
5197                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
5198                 offset += 4;
5199
5200                 break;
5201         }
5202
5203         BYTE_COUNT;
5204
5205         if (wc==12) {
5206                 /* security blob */
5207                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5208                    data structure, at least in NT 5.0-and-later
5209                    server replies? */
5210                 if(sbloblen){
5211                         CHECK_BYTE_COUNT(sbloblen);
5212                         proto_tree_add_item(tree, hf_smb_security_blob,
5213                                 tvb, offset, sbloblen, TRUE);
5214                         COUNT_BYTES(sbloblen);
5215                 }
5216
5217                 /* OS */
5218                 an = get_unicode_or_ascii_string(tvb, &offset,
5219                         pinfo, &an_len, FALSE, FALSE, &bc);
5220                 if (an == NULL)
5221                         goto endofcommand;
5222                 proto_tree_add_string(tree, hf_smb_os, tvb,
5223                         offset, an_len, an);
5224                 COUNT_BYTES(an_len);
5225
5226                 /* LANMAN */
5227                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5228                  * padding/null string/whatever in front of this. W2K doesn't
5229                  * appear to. I suspect that's a bug that got fixed; I also
5230                  * suspect that, in practice, nobody ever looks at that field
5231                  * because the bug didn't appear to get fixed until NT 5.0....
5232                  */
5233                 an = get_unicode_or_ascii_string(tvb, &offset,
5234                         pinfo, &an_len, FALSE, FALSE, &bc);
5235                 if (an == NULL)
5236                         goto endofcommand;
5237                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5238                         offset, an_len, an);
5239                 COUNT_BYTES(an_len);
5240
5241                 /* Primary domain */
5242                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5243                  * byte in front of this, at least if all the strings are
5244                  * ASCII and the account name is empty. Another bug?
5245                  */
5246                 dn = get_unicode_or_ascii_string(tvb, &offset,
5247                         pinfo, &dn_len, FALSE, FALSE, &bc);
5248                 if (dn == NULL)
5249                         goto endofcommand;
5250                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5251                         offset, dn_len, dn);
5252                 COUNT_BYTES(dn_len);
5253         } else {
5254                 switch (wc) {
5255
5256                 case 10:
5257                         if(pwlen){
5258                                 /* password, ASCII */
5259                                 CHECK_BYTE_COUNT(pwlen);
5260                                 proto_tree_add_item(tree, hf_smb_password, 
5261                                         tvb, offset, pwlen, TRUE);
5262                                 COUNT_BYTES(pwlen);
5263                         }
5264
5265                         break;
5266
5267                 case 13:
5268                         if(apwlen){
5269                                 /* password, ANSI */
5270                                 CHECK_BYTE_COUNT(apwlen);
5271                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
5272                                         tvb, offset, apwlen, TRUE);
5273                                 COUNT_BYTES(apwlen);
5274                         }
5275
5276                         if(upwlen){
5277                                 /* password, Unicode */
5278                                 CHECK_BYTE_COUNT(upwlen);
5279                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
5280                                         tvb, offset, upwlen, TRUE);
5281                                 COUNT_BYTES(upwlen);
5282                         }
5283
5284                         break;
5285                 }
5286
5287                 /* Account Name */
5288                 an = get_unicode_or_ascii_string(tvb, &offset,
5289                         pinfo, &an_len, FALSE, FALSE, &bc);
5290                 if (an == NULL)
5291                         goto endofcommand;
5292                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5293                         an);
5294                 COUNT_BYTES(an_len);
5295
5296                 /* Primary domain */
5297                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5298                  * byte in front of this, at least if all the strings are
5299                  * ASCII and the account name is empty. Another bug?
5300                  */
5301                 dn = get_unicode_or_ascii_string(tvb, &offset,
5302                         pinfo, &dn_len, FALSE, FALSE, &bc);
5303                 if (dn == NULL)
5304                         goto endofcommand;
5305                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5306                         offset, dn_len, dn);
5307                 COUNT_BYTES(dn_len);
5308
5309                 if (check_col(pinfo->cinfo, COL_INFO)) {
5310                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5311
5312                         if (!dn[0] && !an[0])
5313                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5314                                                 "anonymous");
5315                         else
5316                                 col_append_fstr(pinfo->cinfo, COL_INFO, 
5317                                                 "%s\\%s", dn,an);
5318                 }
5319
5320                 /* OS */
5321                 an = get_unicode_or_ascii_string(tvb, &offset,
5322                         pinfo, &an_len, FALSE, FALSE, &bc);
5323                 if (an == NULL)
5324                         goto endofcommand;
5325                 proto_tree_add_string(tree, hf_smb_os, tvb,
5326                         offset, an_len, an);
5327                 COUNT_BYTES(an_len);
5328
5329                 /* LANMAN */
5330                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5331                  * padding/null string/whatever in front of this. W2K doesn't
5332                  * appear to. I suspect that's a bug that got fixed; I also
5333                  * suspect that, in practice, nobody ever looks at that field
5334                  * because the bug didn't appear to get fixed until NT 5.0....
5335                  */
5336                 an = get_unicode_or_ascii_string(tvb, &offset,
5337                         pinfo, &an_len, FALSE, FALSE, &bc);
5338                 if (an == NULL)
5339                         goto endofcommand;
5340                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5341                         offset, an_len, an);
5342                 COUNT_BYTES(an_len);
5343         }
5344
5345         END_OF_SMB
5346
5347         /* call AndXCommand (if there are any) */
5348         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5349
5350         return offset;
5351 }
5352
5353 static int
5354 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5355 {
5356         guint8  wc, cmd=0xff;
5357         guint16 andxoffset=0, bc;
5358         guint16 sbloblen=0;
5359         int an_len;
5360         const char *an;
5361
5362         WORD_COUNT;
5363
5364         /* next smb command */
5365         cmd = tvb_get_guint8(tvb, offset);
5366         if(cmd!=0xff){
5367                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5368         } else {
5369                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5370         }
5371         offset += 1;
5372
5373         /* reserved byte */
5374         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5375         offset += 1;
5376
5377         /* andxoffset */
5378         andxoffset = tvb_get_letohs(tvb, offset);
5379         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5380         offset += 2;
5381
5382         /* flags */
5383         offset = dissect_setup_action(tvb, pinfo, tree, offset);
5384
5385         if(wc==4){
5386                 /* security blob length */
5387                 sbloblen = tvb_get_letohs(tvb, offset);
5388                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5389                 offset += 2;
5390         }
5391
5392         BYTE_COUNT;
5393
5394         if(wc==4) {
5395                 /* security blob */
5396                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5397                    data structure, at least in NT 5.0-and-later
5398                    server replies? */
5399                 if(sbloblen){
5400                         CHECK_BYTE_COUNT(sbloblen);
5401                         proto_tree_add_item(tree, hf_smb_security_blob,
5402                                 tvb, offset, sbloblen, TRUE);
5403                         COUNT_BYTES(sbloblen);
5404                 }
5405         }
5406
5407         /* OS */
5408         an = get_unicode_or_ascii_string(tvb, &offset,
5409                 pinfo, &an_len, FALSE, FALSE, &bc);
5410         if (an == NULL)
5411                 goto endofcommand;
5412         proto_tree_add_string(tree, hf_smb_os, tvb,
5413                 offset, an_len, an);
5414         COUNT_BYTES(an_len);
5415
5416         /* LANMAN */
5417         an = get_unicode_or_ascii_string(tvb, &offset,
5418                 pinfo, &an_len, FALSE, FALSE, &bc);
5419         if (an == NULL)
5420                 goto endofcommand;
5421         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5422                 offset, an_len, an);
5423         COUNT_BYTES(an_len);
5424
5425         if(wc==3) {
5426                 /* Primary domain */
5427                 an = get_unicode_or_ascii_string(tvb, &offset,
5428                         pinfo, &an_len, FALSE, FALSE, &bc);
5429                 if (an == NULL)
5430                         goto endofcommand;
5431                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5432                         offset, an_len, an);
5433                 COUNT_BYTES(an_len);
5434         }
5435
5436         END_OF_SMB
5437
5438         /* call AndXCommand (if there are any) */
5439         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5440
5441         return offset;
5442 }
5443
5444  
5445 static int
5446 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5447 {
5448         guint8  wc, cmd=0xff;
5449         guint16 andxoffset=0;
5450         guint16 bc;
5451
5452         WORD_COUNT;
5453
5454         /* next smb command */
5455         cmd = tvb_get_guint8(tvb, offset);
5456         if(cmd!=0xff){
5457                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5458         } else {
5459                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5460         }
5461         offset += 1;
5462
5463         /* reserved byte */
5464         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5465         offset += 1;
5466
5467         /* andxoffset */
5468         andxoffset = tvb_get_letohs(tvb, offset);
5469         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5470         offset += 2;
5471
5472         BYTE_COUNT;
5473
5474         END_OF_SMB
5475
5476         /* call AndXCommand (if there are any) */
5477         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5478
5479         return offset;
5480 }
5481
5482  
5483 static const true_false_string tfs_connect_support_search = {
5484         "Exclusive search bits supported",
5485         "Exclusive search bits not supported"
5486 };
5487 static const true_false_string tfs_connect_support_in_dfs = {
5488         "Share is in Dfs",
5489         "Share isn't in Dfs"
5490 };
5491
5492 static int
5493 dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5494 {
5495         guint16 mask;
5496         proto_item *item = NULL;
5497         proto_tree *tree = NULL;
5498
5499         mask = tvb_get_letohs(tvb, offset);
5500
5501         if(parent_tree){
5502                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5503                         "Optional Support: 0x%04x", mask);
5504                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5505         }
5506
5507         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5508                 tvb, offset, 2, mask);
5509         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5510                 tvb, offset, 2, mask);
5511
5512         offset += 2;
5513
5514         return offset;
5515 }
5516
5517 static const true_false_string tfs_disconnect_tid = {
5518         "DISCONNECT TID",
5519         "Do NOT disconnect TID"
5520 };
5521
5522 static int
5523 dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5524 {
5525         guint16 mask;
5526         proto_item *item = NULL;
5527         proto_tree *tree = NULL;
5528
5529         mask = tvb_get_letohs(tvb, offset);
5530
5531         if(parent_tree){
5532                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5533                         "Flags: 0x%04x", mask);
5534                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5535         }
5536
5537         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5538                 tvb, offset, 2, mask);
5539
5540         offset += 2;
5541
5542         return offset;
5543 }
5544
5545 static int
5546 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5547 {
5548         guint8  wc, cmd=0xff;
5549         guint16 bc;
5550         guint16 andxoffset=0, pwlen=0;
5551         int an_len;
5552         const char *an;
5553
5554         WORD_COUNT;
5555
5556         /* next smb command */
5557         cmd = tvb_get_guint8(tvb, offset);
5558         if(cmd!=0xff){
5559                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5560         } else {
5561                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5562         }
5563         offset += 1;
5564
5565         /* reserved byte */
5566         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5567         offset += 1;
5568
5569         /* andxoffset */
5570         andxoffset = tvb_get_letohs(tvb, offset);
5571         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5572         offset += 2;
5573
5574         /* flags */
5575         offset = dissect_connect_flags(tvb, pinfo, tree, offset);
5576
5577         /* password length*/
5578         pwlen = tvb_get_letohs(tvb, offset);
5579         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
5580         offset += 2;
5581
5582         BYTE_COUNT;
5583
5584         /* password */
5585         CHECK_BYTE_COUNT(pwlen);
5586         proto_tree_add_item(tree, hf_smb_password, 
5587                 tvb, offset, pwlen, TRUE);
5588         COUNT_BYTES(pwlen);
5589
5590         /* Path */
5591         an = get_unicode_or_ascii_string(tvb, &offset,
5592                 pinfo, &an_len, FALSE, FALSE, &bc);
5593         if (an == NULL)
5594                 goto endofcommand;
5595         proto_tree_add_string(tree, hf_smb_path, tvb,
5596                 offset, an_len, an);
5597         COUNT_BYTES(an_len);
5598
5599         if (check_col(pinfo->cinfo, COL_INFO)) {
5600                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
5601         }
5602
5603         /*
5604          * NOTE: the Service string is always ASCII, even if the
5605          * "strings are Unicode" bit is set in the flags2 field
5606          * of the SMB.
5607          */
5608
5609         /* Service */
5610         /* XXX - what if this runs past bc? */
5611         an_len = tvb_strsize(tvb, offset);
5612         CHECK_BYTE_COUNT(an_len);
5613         an = tvb_get_ptr(tvb, offset, an_len);
5614         proto_tree_add_string(tree, hf_smb_service, tvb,
5615                 offset, an_len, an);
5616         COUNT_BYTES(an_len);
5617
5618         END_OF_SMB
5619
5620         /* call AndXCommand (if there are any) */
5621         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5622
5623         return offset;
5624 }
5625
5626
5627 static int
5628 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5629 {
5630         guint8  wc, wleft, cmd=0xff;
5631         guint16 andxoffset=0;
5632         guint16 bc;
5633         int an_len;
5634         const char *an;
5635
5636         WORD_COUNT;
5637
5638         wleft = wc;     /* this is at least 1 */
5639
5640         /* next smb command */
5641         cmd = tvb_get_guint8(tvb, offset);
5642         if(cmd!=0xff){
5643                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5644         } else {
5645                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5646         }
5647         offset += 1;
5648
5649         /* reserved byte */
5650         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5651         offset += 1;
5652
5653         wleft--;
5654         if (wleft == 0)
5655                 goto bytecount;
5656
5657         /* andxoffset */
5658         andxoffset = tvb_get_letohs(tvb, offset);
5659         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5660         offset += 2;
5661         wleft--;
5662         if (wleft == 0)
5663                 goto bytecount;
5664
5665         /* flags */
5666         offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
5667         wleft--;
5668
5669         /* XXX - I've seen captures where this is 7, but I have no
5670            idea how to dissect it.  I'm guessing the third word
5671            contains connect support bits, which looks plausible
5672            from the values I've seen. */
5673
5674         while (wleft != 0) {
5675                 proto_tree_add_text(tree, tvb, offset, 2,
5676                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
5677                 offset += 2;
5678                 wleft--;
5679         }
5680
5681         BYTE_COUNT;
5682
5683         /*
5684          * NOTE: even though the SNIA CIFS spec doesn't say there's
5685          * a "Service" string if there's a word count of 2, the
5686          * document at
5687          *
5688          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
5689          *
5690          * (it's in an ugly format - text intended to be sent to a
5691          * printer, with backspaces and overstrikes used for boldfacing
5692          * and underlining; UNIX "col -b" can be used to strip the
5693          * overstrikes out) says there's a "Service" string there, and
5694          * some network traffic has it.
5695          */
5696
5697         /*
5698          * NOTE: the Service string is always ASCII, even if the
5699          * "strings are Unicode" bit is set in the flags2 field
5700          * of the SMB.
5701          */
5702
5703         /* Service */
5704         /* XXX - what if this runs past bc? */
5705         an_len = tvb_strsize(tvb, offset);
5706         CHECK_BYTE_COUNT(an_len);
5707         an = tvb_get_ptr(tvb, offset, an_len);
5708         proto_tree_add_string(tree, hf_smb_service, tvb,
5709                 offset, an_len, an);
5710         COUNT_BYTES(an_len);
5711
5712         if(wc==3){
5713                 if (bc != 0) {
5714                         /*
5715                          * Sometimes this isn't present.
5716                          */
5717
5718                         /* Native FS */
5719                         an = get_unicode_or_ascii_string(tvb, &offset,
5720                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
5721                         if (an == NULL)
5722                                 goto endofcommand;
5723                         proto_tree_add_string(tree, hf_smb_fs, tvb,
5724                                 offset, an_len, an);
5725                         COUNT_BYTES(an_len);
5726                 }
5727         }
5728
5729         END_OF_SMB
5730
5731         /* call AndXCommand (if there are any) */
5732         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5733
5734         return offset;
5735 }
5736
5737
5738
5739 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5740    NT Transaction command  begins here
5741    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
5742 #define NT_TRANS_CREATE         1
5743 #define NT_TRANS_IOCTL          2
5744 #define NT_TRANS_SSD            3
5745 #define NT_TRANS_NOTIFY         4
5746 #define NT_TRANS_RENAME         5
5747 #define NT_TRANS_QSD            6
5748 static const value_string nt_cmd_vals[] = {
5749         {NT_TRANS_CREATE,       "NT CREATE"},
5750         {NT_TRANS_IOCTL,        "NT IOCTL"},
5751         {NT_TRANS_SSD,          "NT SET SECURITY DESC"},
5752         {NT_TRANS_NOTIFY,       "NT NOTIFY"},
5753         {NT_TRANS_RENAME,       "NT RENAME"},
5754         {NT_TRANS_QSD,          "NT QUERY SECURITY DESC"},
5755         {0, NULL}
5756 };
5757
5758 static const value_string nt_ioctl_isfsctl_vals[] = {
5759         {0,     "Device IOCTL"},
5760         {1,     "FS control : FSCTL"},
5761         {0, NULL}
5762 };
5763
5764 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
5765 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
5766         "Apply the command to share root handle (MUST BE Dfs)",
5767         "Apply to this share",
5768 };
5769
5770 static const value_string nt_notify_action_vals[] = {
5771         {1,     "ADDED (object was added"},
5772         {2,     "REMOVED (object was removed)"},
5773         {3,     "MODIFIED (object was modified)"},
5774         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
5775         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
5776         {6,     "ADDED_STREAM (a stream was added)"},
5777         {7,     "REMOVED_STREAM (a stream was removed)"},
5778         {8,     "MODIFIED_STREAM (a stream was modified)"},
5779         {0, NULL}
5780 };
5781
5782 static const value_string watch_tree_vals[] = {
5783         {0,     "Current directory only"},
5784         {1,     "Subdirectories also"},
5785         {0, NULL}
5786 };
5787
5788 #define NT_NOTIFY_STREAM_WRITE  0x00000800
5789 #define NT_NOTIFY_STREAM_SIZE   0x00000400
5790 #define NT_NOTIFY_STREAM_NAME   0x00000200
5791 #define NT_NOTIFY_SECURITY      0x00000100
5792 #define NT_NOTIFY_EA            0x00000080
5793 #define NT_NOTIFY_CREATION      0x00000040
5794 #define NT_NOTIFY_LAST_ACCESS   0x00000020
5795 #define NT_NOTIFY_LAST_WRITE    0x00000010
5796 #define NT_NOTIFY_SIZE          0x00000008
5797 #define NT_NOTIFY_ATTRIBUTES    0x00000004
5798 #define NT_NOTIFY_DIR_NAME      0x00000002
5799 #define NT_NOTIFY_FILE_NAME     0x00000001
5800 static const true_false_string tfs_nt_notify_stream_write = {
5801         "Notify on changes to STREAM WRITE",
5802         "Do NOT notify on changes to stream write",
5803 };
5804 static const true_false_string tfs_nt_notify_stream_size = {
5805         "Notify on changes to STREAM SIZE",
5806         "Do NOT notify on changes to stream size",
5807 };
5808 static const true_false_string tfs_nt_notify_stream_name = {
5809         "Notify on changes to STREAM NAME",
5810         "Do NOT notify on changes to stream name",
5811 };
5812 static const true_false_string tfs_nt_notify_security = {
5813         "Notify on changes to SECURITY",
5814         "Do NOT notify on changes to security",
5815 };
5816 static const true_false_string tfs_nt_notify_ea = {
5817         "Notify on changes to EA",
5818         "Do NOT notify on changes to EA",
5819 };
5820 static const true_false_string tfs_nt_notify_creation = {
5821         "Notify on changes to CREATION TIME",
5822         "Do NOT notify on changes to creation time",
5823 };
5824 static const true_false_string tfs_nt_notify_last_access = {
5825         "Notify on changes to LAST ACCESS TIME",
5826         "Do NOT notify on changes to last access time",
5827 };
5828 static const true_false_string tfs_nt_notify_last_write = {
5829         "Notify on changes to LAST WRITE TIME",
5830         "Do NOT notify on changes to last write time",
5831 };
5832 static const true_false_string tfs_nt_notify_size = {
5833         "Notify on changes to SIZE",
5834         "Do NOT notify on changes to size",
5835 };
5836 static const true_false_string tfs_nt_notify_attributes = {
5837         "Notify on changes to ATTRIBUTES",
5838         "Do NOT notify on changes to attributes",
5839 };
5840 static const true_false_string tfs_nt_notify_dir_name = {
5841         "Notify on changes to DIR NAME",
5842         "Do NOT notify on changes to dir name",
5843 };
5844 static const true_false_string tfs_nt_notify_file_name = {
5845         "Notify on changes to FILE NAME",
5846         "Do NOT notify on changes to file name",
5847 };
5848
5849 static const value_string create_disposition_vals[] = {
5850         {0,     "Supersede (supersede existing file (if it exists))"},
5851         {1,     "Open (if file exists open it, else fail)"},
5852         {2,     "Create (if file exists fail, else create it)"},
5853         {3,     "Open If (if file exists open it, else create it)"},
5854         {4,     "Overwrite (if file exists overwrite, else fail)"},
5855         {5,     "Overwrite If (if file exists overwrite, else create it)"},
5856         {0, NULL}
5857 };
5858
5859 static const value_string impersonation_level_vals[] = {
5860         {0,     "Anonymous"},
5861         {1,     "Identification"},
5862         {2,     "Impersonation"},
5863         {3,     "Delegation"},
5864         {0, NULL}
5865 };
5866
5867 static const true_false_string tfs_nt_security_flags_context_tracking = {
5868         "Security tracking mode is DYNAMIC",
5869         "Security tracking mode is STATIC",
5870 };
5871
5872 static const true_false_string tfs_nt_security_flags_effective_only = {
5873         "ONLY ENABLED aspects of the client's security context are available",
5874         "ALL aspects of the client's security context are available",
5875 };
5876
5877 static const true_false_string tfs_nt_create_bits_oplock = {
5878         "Requesting OPLOCK",
5879         "Does NOT request oplock"
5880 };
5881
5882 static const true_false_string tfs_nt_create_bits_boplock = {
5883         "Requesting BATCH OPLOCK",
5884         "Does NOT request batch oplock"
5885 };
5886
5887 /*
5888  * XXX - must be a directory, and can be a file, or can be a directory,
5889  * and must be a file?
5890  */
5891 static const true_false_string tfs_nt_create_bits_dir = {
5892         "Target of open MUST be a DIRECTORY",
5893         "Target of open can be a file"
5894 };
5895
5896 static const true_false_string tfs_nt_access_mask_generic_read = {
5897         "GENERIC READ is set",
5898         "Generic read is NOT set"
5899 };
5900 static const true_false_string tfs_nt_access_mask_generic_write = {
5901         "GENERIC WRITE is set",
5902         "Generic write is NOT set"
5903 };
5904 static const true_false_string tfs_nt_access_mask_generic_execute = {
5905         "GENERIC EXECUTE is set",
5906         "Generic execute is NOT set"
5907 };
5908 static const true_false_string tfs_nt_access_mask_generic_all = {
5909         "GENERIC ALL is set",
5910         "Generic all is NOT set"
5911 };
5912 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
5913         "MAXIMUM ALLOWED is set",
5914         "Maximum allowed is NOT set"
5915 };
5916 static const true_false_string tfs_nt_access_mask_system_security = {
5917         "SYSTEM SECURITY is set",
5918         "System security is NOT set"
5919 };
5920 static const true_false_string tfs_nt_access_mask_synchronize = {
5921         "Can wait on handle to SYNCHRONIZE on completion of I/O",
5922         "Can NOT wait on handle to synchronize on completion of I/O"
5923 };
5924 static const true_false_string tfs_nt_access_mask_write_owner = {
5925         "Can WRITE OWNER (take ownership)",
5926         "Can NOT write owner (take ownership)"
5927 };
5928 static const true_false_string tfs_nt_access_mask_write_dac = {
5929         "OWNER may WRITE the DAC",
5930         "Owner may NOT write to the DAC"
5931 };
5932 static const true_false_string tfs_nt_access_mask_read_control = {
5933         "READ ACCESS to owner, group and ACL of the SID",
5934         "Read access is NOT granted to owner, group and ACL of the SID"
5935 };
5936 static const true_false_string tfs_nt_access_mask_delete = {
5937         "DELETE access",
5938         "NO delete access"
5939 };
5940 static const true_false_string tfs_nt_access_mask_write_attributes = {
5941         "WRITE ATTRIBUTES access",
5942         "NO write attributes access"
5943 };
5944 static const true_false_string tfs_nt_access_mask_read_attributes = {
5945         "READ ATTRIBUTES access",
5946         "NO read attributes access"
5947 };
5948 static const true_false_string tfs_nt_access_mask_delete_child = {
5949         "DELETE CHILD access",
5950         "NO delete child access"
5951 };
5952 static const true_false_string tfs_nt_access_mask_execute = {
5953         "EXECUTE access",
5954         "NO execute access"
5955 };
5956 static const true_false_string tfs_nt_access_mask_write_ea = {
5957         "WRITE EXTENDED ATTRIBUTES access",
5958         "NO write extended attributes access"
5959 };
5960 static const true_false_string tfs_nt_access_mask_read_ea = {
5961         "READ EXTENDED ATTRIBUTES access",
5962         "NO read extended attributes access"
5963 };
5964 static const true_false_string tfs_nt_access_mask_append = {
5965         "APPEND access",
5966         "NO append access"
5967 };
5968 static const true_false_string tfs_nt_access_mask_write = {
5969         "WRITE access",
5970         "NO write access"
5971 };
5972 static const true_false_string tfs_nt_access_mask_read = {
5973         "READ access",
5974         "NO read access"
5975 };
5976
5977 static const true_false_string tfs_nt_share_access_delete = {
5978         "Object can be shared for DELETE",
5979         "Object can NOT be shared for delete"
5980 };
5981 static const true_false_string tfs_nt_share_access_write = {
5982         "Object can be shared for WRITE",
5983         "Object can NOT be shared for write"
5984 };
5985 static const true_false_string tfs_nt_share_access_read = {
5986         "Object can be shared for READ",
5987         "Object can NOT be shared for delete"
5988 };
5989
5990 static const value_string oplock_level_vals[] = {
5991         {0,     "No oplock granted"},
5992         {1,     "Exclusive oplock granted"},
5993         {2,     "Batch oplock granted"},
5994         {3,     "Level II oplock granted"},
5995         {0, NULL}
5996 };
5997
5998 static const value_string device_type_vals[] = {
5999         {0x00000001,    "Beep"},
6000         {0x00000002,    "CDROM"},
6001         {0x00000003,    "CDROM Filesystem"},
6002         {0x00000004,    "Controller"},
6003         {0x00000005,    "Datalink"},
6004         {0x00000006,    "Dfs"},
6005         {0x00000007,    "Disk"},
6006         {0x00000008,    "Disk Filesystem"},
6007         {0x00000009,    "Filesystem"},
6008         {0x0000000a,    "Inport Port"},
6009         {0x0000000b,    "Keyboard"},
6010         {0x0000000c,    "Mailslot"},
6011         {0x0000000d,    "MIDI-In"},
6012         {0x0000000e,    "MIDI-Out"},
6013         {0x0000000f,    "Mouse"},
6014         {0x00000010,    "Multi UNC Provider"},
6015         {0x00000011,    "Named Pipe"},
6016         {0x00000012,    "Network"},
6017         {0x00000013,    "Network Browser"},
6018         {0x00000014,    "Network Filesystem"},
6019         {0x00000015,    "NULL"},
6020         {0x00000016,    "Parallel Port"},
6021         {0x00000017,    "Physical card"},
6022         {0x00000018,    "Printer"},
6023         {0x00000019,    "Scanner"},
6024         {0x0000001a,    "Serial Mouse port"},
6025         {0x0000001b,    "Serial port"},
6026         {0x0000001c,    "Screen"},
6027         {0x0000001d,    "Sound"},
6028         {0x0000001e,    "Streams"},
6029         {0x0000001f,    "Tape"},
6030         {0x00000020,    "Tape Filesystem"},
6031         {0x00000021,    "Transport"},
6032         {0x00000022,    "Unknown"},
6033         {0x00000023,    "Video"},
6034         {0x00000024,    "Virtual Disk"},
6035         {0x00000025,    "WAVE-In"},
6036         {0x00000026,    "WAVE-Out"},
6037         {0x00000027,    "8042 Port"},
6038         {0x00000028,    "Network Redirector"},
6039         {0x00000029,    "Battery"},
6040         {0x0000002a,    "Bus Extender"},
6041         {0x0000002b,    "Modem"},
6042         {0x0000002c,    "VDM"},
6043         {0,     NULL}
6044 };
6045
6046 static const value_string is_directory_vals[] = {
6047         {0,     "This is NOT a directory"},
6048         {1,     "This is a DIRECTORY"},
6049         {0, NULL}
6050 };
6051
6052 typedef struct _nt_trans_data {
6053         int subcmd;
6054         guint32 sd_len;
6055         guint32 ea_len;
6056 } nt_trans_data;
6057
6058
6059
6060 static int
6061 dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6062 {
6063         guint8 mask;
6064         proto_item *item = NULL;
6065         proto_tree *tree = NULL;
6066
6067         mask = tvb_get_guint8(tvb, offset);
6068
6069         if(parent_tree){
6070                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6071                         "Security Flags: 0x%02x", mask);
6072                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6073         }
6074
6075         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6076                 tvb, offset, 1, mask);
6077         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6078                 tvb, offset, 1, mask);
6079
6080         offset += 1;
6081
6082         return offset;
6083 }
6084
6085 static int
6086 dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6087 {
6088         guint32 mask;
6089         proto_item *item = NULL;
6090         proto_tree *tree = NULL;
6091
6092         mask = tvb_get_letohl(tvb, offset);
6093
6094         if(parent_tree){
6095                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6096                         "Share Access: 0x%08x", mask);
6097                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6098         }
6099
6100         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6101                 tvb, offset, 4, mask);
6102         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6103                 tvb, offset, 4, mask);
6104         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6105                 tvb, offset, 4, mask);
6106
6107         offset += 4;
6108
6109         return offset;
6110 }
6111
6112
6113 static int
6114 dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6115 {
6116         guint32 mask;
6117         proto_item *item = NULL;
6118         proto_tree *tree = NULL;
6119
6120         mask = tvb_get_letohl(tvb, offset);
6121
6122         if(parent_tree){
6123                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6124                         "Access Mask: 0x%08x", mask);
6125                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6126         }
6127
6128         /*
6129          * Some of these bits come from 
6130          *
6131          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6132          *
6133          * and others come from the section on ZwOpenFile in "Windows(R)
6134          * NT(R)/2000 Native API Reference".
6135          */
6136         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6137                 tvb, offset, 4, mask);
6138         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6139                 tvb, offset, 4, mask);
6140         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6141                 tvb, offset, 4, mask);
6142         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6143                 tvb, offset, 4, mask);
6144         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6145                 tvb, offset, 4, mask);
6146         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6147                 tvb, offset, 4, mask);
6148         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6149                 tvb, offset, 4, mask);
6150         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6151                 tvb, offset, 4, mask);
6152         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6153                 tvb, offset, 4, mask);
6154         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6155                 tvb, offset, 4, mask);
6156         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6157                 tvb, offset, 4, mask);
6158         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6159                 tvb, offset, 4, mask);
6160         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6161                 tvb, offset, 4, mask);
6162         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6163                 tvb, offset, 4, mask);
6164         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6165                 tvb, offset, 4, mask);
6166         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6167                 tvb, offset, 4, mask);
6168         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6169                 tvb, offset, 4, mask);
6170         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6171                 tvb, offset, 4, mask);
6172         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6173                 tvb, offset, 4, mask);
6174         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6175                 tvb, offset, 4, mask);
6176
6177         offset += 4;
6178
6179         return offset;
6180 }
6181
6182 static int
6183 dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6184 {
6185         guint32 mask;
6186         proto_item *item = NULL;
6187         proto_tree *tree = NULL;
6188
6189         mask = tvb_get_letohl(tvb, offset);
6190
6191         if(parent_tree){
6192                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6193                         "Create Flags: 0x%08x", mask);
6194                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6195         }
6196
6197         /*
6198          * XXX - it's 0x00000016 in at least one capture, but
6199          * Network Monitor doesn't say what the 0x00000010 bit is.
6200          * Does the Win32 API documentation, or NT Native API book,
6201          * suggest anything?
6202          */
6203         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6204                 tvb, offset, 4, mask);
6205         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6206                 tvb, offset, 4, mask);
6207         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6208                 tvb, offset, 4, mask);
6209
6210         offset += 4;
6211
6212         return offset;
6213 }
6214
6215 /*
6216  * XXX - there are some more flags in the description of "ZwOpenFile()"
6217  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6218  * the wire as well?  (The spec at
6219  *
6220  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6221  *
6222  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6223  * via the SMB protocol.  The NT redirector should convert this option
6224  * to FILE_WRITE_THROUGH."
6225  *
6226  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6227  * values one would infer from their position in the list of flags for
6228  * "ZwOpenFile()".  Most of the others probably have those values
6229  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6230  * which might go over the wire (for the benefit of backup/restore software).
6231  */
6232 static const true_false_string tfs_nt_create_options_directory = {
6233         "File being created/opened must be a directory",
6234         "File being created/opened must not be a directory"
6235 };
6236 static const true_false_string tfs_nt_create_options_write_through = {
6237         "Writes should flush buffered data before completing",
6238         "Writes need not flush buffered data before completing"
6239 };
6240 static const true_false_string tfs_nt_create_options_sequential_only = {
6241         "The file will only be accessed sequentially",
6242         "The file might not only be accessed sequentially"
6243 };
6244 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6245         "All operations SYNCHRONOUS, waits subject to termination from alert",
6246         "Operations NOT necessarily synchronous"
6247 };
6248 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6249         "All operations SYNCHRONOUS, waits not subject to alert",
6250         "Operations NOT necessarily synchronous"
6251 };
6252 static const true_false_string tfs_nt_create_options_non_directory = {
6253         "File being created/opened must not be a directory",
6254         "File being created/opened must be a directory"
6255 };
6256 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6257         "The client does not understand extended attributes",
6258         "The client understands extended attributes"
6259 };
6260 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6261         "The client understands only 8.3 file names",
6262         "The client understands long file names"
6263 };
6264 static const true_false_string tfs_nt_create_options_random_access = {
6265         "The file will be accessed randomly",
6266         "The file will not be accessed randomly"
6267 };
6268 static const true_false_string tfs_nt_create_options_delete_on_close = {
6269         "The file should be deleted when it is closed",
6270         "The file should not be deleted when it is closed"
6271 };
6272
6273 static int
6274 dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6275 {
6276         guint32 mask;
6277         proto_item *item = NULL;
6278         proto_tree *tree = NULL;
6279
6280         mask = tvb_get_letohl(tvb, offset);
6281
6282         if(parent_tree){
6283                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6284                         "Create Options: 0x%08x", mask);
6285                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
6286         }
6287
6288         /*
6289          * From
6290          *
6291          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6292          */
6293         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
6294                 tvb, offset, 4, mask);
6295         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
6296                 tvb, offset, 4, mask);
6297         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
6298                 tvb, offset, 4, mask);
6299         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
6300                 tvb, offset, 4, mask);
6301         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
6302                 tvb, offset, 4, mask);
6303         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
6304                 tvb, offset, 4, mask);
6305         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
6306                 tvb, offset, 4, mask);
6307         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
6308                 tvb, offset, 4, mask);
6309         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
6310                 tvb, offset, 4, mask);
6311         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
6312                 tvb, offset, 4, mask);
6313
6314         offset += 4;
6315
6316         return offset;
6317 }
6318  
6319 static int
6320 dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6321 {
6322         guint32 mask;
6323         proto_item *item = NULL;
6324         proto_tree *tree = NULL;
6325
6326         mask = tvb_get_letohl(tvb, offset);
6327
6328         if(parent_tree){
6329                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6330                         "Completion Filter: 0x%08x", mask);
6331                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
6332         }
6333  
6334         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
6335                 tvb, offset, 4, mask);
6336         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
6337                 tvb, offset, 4, mask);
6338         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
6339                 tvb, offset, 4, mask);
6340         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
6341                 tvb, offset, 4, mask);
6342         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
6343                 tvb, offset, 4, mask);
6344         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
6345                 tvb, offset, 4, mask);
6346         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
6347                 tvb, offset, 4, mask);
6348         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
6349                 tvb, offset, 4, mask);
6350         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
6351                 tvb, offset, 4, mask);
6352         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
6353                 tvb, offset, 4, mask);
6354         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
6355                 tvb, offset, 4, mask);
6356         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
6357                 tvb, offset, 4, mask);
6358
6359         offset += 4;
6360         return offset;
6361 }
6362  
6363 static int
6364 dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6365 {
6366         guint8 mask;
6367         proto_item *item = NULL;
6368         proto_tree *tree = NULL;
6369
6370         mask = tvb_get_guint8(tvb, offset);
6371
6372         if(parent_tree){
6373                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6374                         "Completion Filter: 0x%02x", mask);
6375                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6376         }
6377
6378         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6379                 tvb, offset, 1, mask);
6380
6381         offset += 1;
6382         return offset;
6383 }
6384
6385 /*
6386  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6387  * Native API Reference".
6388  */
6389 static const true_false_string tfs_nt_qsd_owner = {
6390         "Requesting OWNER security information",
6391         "NOT requesting owner security information",
6392 };
6393
6394 static const true_false_string tfs_nt_qsd_group = {
6395         "Requesting GROUP security information",
6396         "NOT requesting group security information",
6397 };
6398
6399 static const true_false_string tfs_nt_qsd_dacl = {
6400         "Requesting DACL security information",
6401         "NOT requesting DACL security information",
6402 };
6403
6404 static const true_false_string tfs_nt_qsd_sacl = {
6405         "Requesting SACL security information",
6406         "NOT requesting SACL security information",
6407 };
6408
6409 #define NT_QSD_OWNER    0x00000001
6410 #define NT_QSD_GROUP    0x00000002
6411 #define NT_QSD_DACL     0x00000004
6412 #define NT_QSD_SACL     0x00000008
6413
6414 static int
6415 dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6416 {
6417         guint32 mask;
6418         proto_item *item = NULL;
6419         proto_tree *tree = NULL;
6420
6421         mask = tvb_get_letohl(tvb, offset);
6422
6423         if(parent_tree){
6424                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6425                         "Security Information: 0x%08x", mask);
6426                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6427         }
6428
6429         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6430                 tvb, offset, 4, mask);
6431         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6432                 tvb, offset, 4, mask);
6433         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6434                 tvb, offset, 4, mask);
6435         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6436                 tvb, offset, 4, mask);
6437
6438         offset += 4;
6439
6440         return offset;
6441 }
6442
6443 static void
6444 free_g_string(void *arg)
6445 {
6446         GString *gstring = arg;
6447
6448         g_string_free(arg, TRUE);
6449 }
6450
6451 int
6452 dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6453 {
6454         proto_item *item = NULL;
6455         proto_tree *tree = NULL;
6456         int old_offset = offset;
6457         guint8 revision;
6458         guint8 num_auth;
6459         int i;
6460         GString *gstr;
6461
6462         if(parent_tree){
6463                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6464                                            "NT %s SID", name);
6465                 tree = proto_item_add_subtree(item, ett_smb_sid);
6466         }
6467
6468         /* revision of sid */
6469         revision = tvb_get_guint8(tvb, offset);
6470         proto_tree_add_item(tree, hf_smb_sid_revision, tvb, offset, 1, TRUE);
6471         offset += 1;
6472
6473         switch(revision){
6474         case 1:  
6475         case 2:  /* Not sure what the different revision numbers mean */
6476           /* number of authorities*/
6477           num_auth = tvb_get_guint8(tvb, offset);
6478           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
6479           offset += 1;
6480
6481           /* XXX perhaps we should have these thing searchable?
6482              a new FT_xxx thingie? SMB is quite common!*/
6483           /* identifier authorities */
6484           gstr = g_string_new(NULL);
6485
6486           CLEANUP_PUSH(free_g_string, gstr);
6487           
6488           g_string_sprintf(gstr, "S-1");
6489
6490           proto_tree_add_text(tree, tvb, offset, 6, "Authorities");
6491
6492           for(i=0;i<6;i++){
6493             guint8 auth = tvb_get_guint8(tvb, offset);
6494
6495             if (auth > 0)
6496               g_string_sprintfa(gstr,"-%u", auth);
6497             offset++;
6498           }
6499
6500           proto_tree_add_text(tree, tvb, offset, num_auth * 4, "Sub-authorities");
6501
6502           /* sub authorities */
6503           for(i=0;i<num_auth;i++){
6504             /* XXX should not be letohl but native byteorder according to
6505                samba header files. considering that all non-x86 NT ports
6506                are dead we can (?) assume that non le byte encodings
6507                will be "uncommon"?*/
6508             g_string_sprintfa(gstr, "-%u",tvb_get_letohl(tvb, offset));
6509             offset+=4;
6510           }
6511
6512           proto_item_append_text(item, ": %s", gstr->str);  
6513
6514           CLEANUP_CALL_AND_POP;
6515         }
6516
6517         proto_item_set_len(item, offset-old_offset);
6518         return offset;
6519 }
6520
6521
6522 static const value_string ace_type_vals[] = {
6523   { 0, "Access Allowed"},
6524   { 1, "Access Denied"},
6525   { 2, "System Audit"},
6526   { 3, "System Alarm"},
6527   { 0, NULL}
6528 };
6529 static const true_false_string tfs_ace_flags_object_inherit = {
6530   "Subordinate files will inherit this ACE",
6531   "Subordinate files will not inherit this ACE"
6532 };
6533 static const true_false_string tfs_ace_flags_container_inherit = {
6534   "Subordinate containers will inherit this ACE",
6535   "Subordinate containers will not inherit this ACE"
6536 };
6537 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
6538   "Subordinate object will not propagate the inherited ACE further",
6539   "Subordinate object will propagate the inherited ACE further"
6540 };
6541 static const true_false_string tfs_ace_flags_inherit_only = {
6542   "This ACE does not apply to the current object",
6543   "This ACE applies to the current object"
6544 };
6545 static const true_false_string tfs_ace_flags_inherited_ace = {
6546   "This ACE was inherited from its parent object",
6547   "This ACE was not inherited from its parent object"
6548 };
6549 static const true_false_string tfs_ace_flags_successful_access = {
6550   "Successful accesses will be audited",
6551   "Successful accesses will not be audited"
6552 };
6553 static const true_false_string tfs_ace_flags_failed_access = {
6554   "Failed accesses will be audited",
6555   "Failed accesses will not be audited"
6556 };
6557
6558 #define APPEND_ACE_TEXT(flag, item, string) \
6559         if(item && flag){                                     \
6560                   proto_item_append_text(item, string);       \
6561         }
6562
6563 static int
6564 dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6565 {
6566         proto_item *item = NULL;
6567         proto_tree *tree = NULL;
6568         guint8 mask;
6569
6570         mask = tvb_get_guint8(tvb, offset);
6571         if(parent_tree){
6572                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6573                                            "NT ACE Flags:0x%02x", mask);
6574                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
6575         }
6576
6577         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
6578                        tvb, offset, 1, mask);
6579         APPEND_ACE_TEXT(mask&0x80, item, "  Failed Access,");
6580
6581         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
6582                        tvb, offset, 1, mask);
6583         APPEND_ACE_TEXT(mask&0x40, item, "  Successful Access,");
6584
6585         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
6586                        tvb, offset, 1, mask);
6587         APPEND_ACE_TEXT(mask&0x10, item, "  Inherited ACE,");
6588
6589         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
6590                        tvb, offset, 1, mask);
6591         APPEND_ACE_TEXT(mask&0x08, item, "  Inherit Only,");
6592
6593         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
6594                        tvb, offset, 1, mask);
6595         APPEND_ACE_TEXT(mask&0x04, item, "  No Propagate Inherit,");
6596
6597         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
6598                        tvb, offset, 1, mask);
6599         APPEND_ACE_TEXT(mask&0x02, item, "  Container Inherit,");
6600
6601         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
6602                        tvb, offset, 1, mask);
6603         APPEND_ACE_TEXT(mask&0x01, item, "  Object Inherit,");
6604
6605
6606         offset += 1;
6607         return offset;
6608 }
6609
6610 static int
6611 dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6612 {
6613         proto_item *item = NULL;
6614         proto_tree *tree = NULL;
6615         int old_offset = offset;
6616         
6617         if(parent_tree){
6618                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6619                                            "NT ACE: ");
6620                 tree = proto_item_add_subtree(item, ett_smb_ace);
6621         }
6622
6623         /* type */
6624         if(item){
6625           proto_item_append_text(item, val_to_str(tvb_get_guint8(tvb, offset), ace_type_vals, "Unknown ACE type (%u)"));
6626         }
6627         proto_tree_add_item(tree, hf_smb_ace_type, tvb, offset, 1, TRUE);
6628         offset += 1;
6629
6630         /* flags */
6631         offset = dissect_nt_v2_ace_flags(tvb, pinfo, offset, tree);
6632
6633         /* size */
6634         proto_tree_add_item(tree, hf_smb_ace_size, tvb, offset, 2, TRUE);
6635         offset += 2;
6636
6637         /* access mask */
6638         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
6639
6640         /* SID */
6641         offset = dissect_nt_sid(tvb, pinfo, offset, tree, "ACE");
6642
6643         proto_item_set_len(item, offset-old_offset);
6644         return offset;
6645 }
6646
6647 static int
6648 dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
6649 {
6650         proto_item *item = NULL;
6651         proto_tree *tree = NULL;
6652         int old_offset = offset;
6653         guint16 revision, size;
6654         guint32 num_aces;
6655
6656         if(parent_tree){
6657                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
6658                                            "NT %s ACL", name);
6659                 tree = proto_item_add_subtree(item, ett_smb_acl);
6660         }
6661
6662         /* revision */
6663         revision = tvb_get_letohs(tvb, offset);
6664         proto_tree_add_uint(tree, hf_smb_acl_revision,
6665                 tvb, offset, 2, revision);
6666         offset += 2;
6667
6668         switch(revision){
6669         case 2:  /* only version we will ever see of this structure?*/
6670         case 3:
6671           /* size */
6672           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
6673           offset += 2;
6674
6675           /* number of ace structures */
6676           num_aces = tvb_get_letohl(tvb, offset);
6677           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
6678                               tvb, offset, 4, num_aces);
6679           offset += 4;
6680
6681           while(num_aces--){
6682             offset=dissect_nt_v2_ace(tvb, pinfo, offset, tree);
6683           }
6684         }
6685
6686         proto_item_set_len(item, offset-old_offset);
6687         return offset;
6688 }
6689
6690 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
6691   "OWNER is DEFAULTED",
6692   "Owner is NOT defaulted"
6693 };
6694 static const true_false_string tfs_sec_desc_type_group_defaulted = {
6695   "GROUP is DEFAULTED",
6696   "Group is NOT defaulted"
6697 };
6698 static const true_false_string tfs_sec_desc_type_dacl_present = {
6699   "DACL is PRESENT",
6700   "DACL is NOT present"
6701 };
6702 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
6703   "DACL is DEFAULTED",
6704   "DACL is NOT defaulted"
6705 };
6706 static const true_false_string tfs_sec_desc_type_sacl_present = {
6707   "SACL is PRESENT",
6708   "SACL is NOT present"
6709 };
6710 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
6711   "SACL is DEFAULTED",
6712   "SACL is NOT defaulted"
6713 };
6714 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
6715   "DACL has AUTO INHERIT REQUIRED",
6716   "DACL does NOT require auto inherit"
6717 };
6718 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
6719   "SACL has AUTO INHERIT REQUIRED",
6720   "SACL does NOT require auto inherit"
6721 };
6722 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
6723   "DACL is AUTO INHERITED",
6724   "DACL is NOT auto inherited"
6725 };
6726 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
6727   "SACL is AUTO INHERITED",
6728   "SACL is NOT auto inherited"
6729 };
6730 static const true_false_string tfs_sec_desc_type_dacl_protected = {
6731   "The DACL is PROTECTED",
6732   "The DACL is NOT protected"
6733 };
6734 static const true_false_string tfs_sec_desc_type_sacl_protected = {
6735   "The SACL is PROTECTED",
6736   "The SACL is NOT protected"
6737 };
6738 static const true_false_string tfs_sec_desc_type_self_relative = {
6739   "This SecDesc is SELF RELATIVE",
6740   "This SecDesc is NOT self relative"
6741 };
6742
6743
6744 static int
6745 dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
6746 {
6747         proto_item *item = NULL;
6748         proto_tree *tree = NULL;
6749         guint16 mask;
6750
6751         mask = tvb_get_letohs(tvb, offset);
6752         if(parent_tree){
6753                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6754                                            "Type: 0x%04x", mask);
6755                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
6756         }
6757
6758         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
6759                                tvb, offset, 2, mask);
6760         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
6761                                tvb, offset, 2, mask);
6762         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
6763                                tvb, offset, 2, mask);
6764         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
6765                                tvb, offset, 2, mask);
6766         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
6767                                tvb, offset, 2, mask);
6768         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
6769                                tvb, offset, 2, mask);
6770         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
6771                                tvb, offset, 2, mask);
6772         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
6773                                tvb, offset, 2, mask);
6774         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
6775                                tvb, offset, 2, mask);
6776         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
6777                                tvb, offset, 2, mask);
6778         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
6779                                tvb, offset, 2, mask);
6780         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
6781                                tvb, offset, 2, mask);
6782         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
6783                                tvb, offset, 2, mask);
6784
6785
6786         offset += 2;
6787         return offset;
6788 }
6789
6790
6791 int
6792 dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
6793 {
6794         proto_item *item = NULL;
6795         proto_tree *tree = NULL;
6796         guint16 revision;
6797         int old_offset = offset;
6798         guint32 owner_sid_offset;
6799         guint32 group_sid_offset;
6800         guint32 sacl_offset;
6801         guint32 dacl_offset;
6802
6803         if(parent_tree){
6804                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6805                                            "NT Security Descriptor");
6806                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
6807         }
6808
6809         /* revision */
6810         revision = tvb_get_letohs(tvb, offset);
6811         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
6812                 tvb, offset, 2, revision);
6813         offset += 2;
6814
6815         switch(revision){
6816         case 1:  /* only version we will ever see of this structure?*/
6817           /* type */
6818           offset = dissect_nt_sec_desc_type(tvb, pinfo, offset, tree);
6819
6820           /* offset to owner sid */
6821           owner_sid_offset = tvb_get_letohl(tvb, offset);
6822           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
6823           offset += 4;
6824
6825           /* offset to group sid */
6826           group_sid_offset = tvb_get_letohl(tvb, offset);
6827           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
6828           offset += 4;
6829
6830           /* offset to sacl */
6831           sacl_offset = tvb_get_letohl(tvb, offset);
6832           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
6833           offset += 4;
6834
6835           /* offset to dacl */
6836           dacl_offset = tvb_get_letohl(tvb, offset);
6837           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
6838           offset += 4;
6839
6840           /*owner SID*/
6841           if(owner_sid_offset){
6842             dissect_nt_sid(tvb, pinfo, old_offset+owner_sid_offset, tree, "Owner");
6843           }
6844
6845           /*group SID*/
6846           if(group_sid_offset){
6847             dissect_nt_sid(tvb, pinfo, old_offset+group_sid_offset, tree, "Group");
6848           }
6849
6850           /* sacl */
6851           if(sacl_offset){
6852             dissect_nt_acl(tvb, pinfo, old_offset+sacl_offset, tree, "System (SACL)");
6853           }
6854
6855           /* dacl */
6856           if(dacl_offset){
6857             dissect_nt_acl(tvb, pinfo, old_offset+dacl_offset, tree, "User (DACL)");
6858           }
6859
6860         }
6861
6862         return offset+len;
6863 }
6864
6865 static int
6866 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
6867 {
6868         proto_item *item = NULL;
6869         proto_tree *tree = NULL;
6870         smb_info_t *si;
6871
6872         si = (smb_info_t *)pinfo->private_data;
6873
6874         if(parent_tree){
6875                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6876                                 "%s Data",
6877                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
6878                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6879         }
6880
6881         switch(ntd->subcmd){
6882         case NT_TRANS_CREATE:
6883                 /* security descriptor */
6884                 if(ntd->sd_len){
6885                         offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, ntd->sd_len);
6886                 }
6887
6888                 /* extended attributes */
6889                 if(ntd->ea_len){
6890                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
6891                         offset += ntd->ea_len;
6892                 }
6893
6894                 break;
6895         case NT_TRANS_IOCTL:
6896                 /* ioctl data */
6897                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
6898                 offset += len;
6899
6900                 break;
6901         case NT_TRANS_SSD:
6902                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
6903                 break;
6904         case NT_TRANS_NOTIFY:
6905                 break;
6906         case NT_TRANS_RENAME:
6907                 /* XXX not documented */
6908                 break;
6909         case NT_TRANS_QSD:
6910                 break;
6911         }
6912
6913         return offset;
6914 }
6915
6916 static int
6917 dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc)
6918 {
6919         proto_item *item = NULL;
6920         proto_tree *tree = NULL;
6921         smb_info_t *si;
6922         guint32 fn_len;
6923         const char *fn;
6924
6925         si = (smb_info_t *)pinfo->private_data;
6926
6927         if(parent_tree){
6928                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6929                                 "%s Parameters",
6930                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
6931                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6932         }
6933
6934         switch(ntd->subcmd){
6935         case NT_TRANS_CREATE:
6936                 /* Create flags */
6937                 offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
6938                 bc -= 4;
6939
6940                 /* root directory fid */
6941                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
6942                 COUNT_BYTES(4);
6943
6944                 /* nt access mask */
6945                 offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
6946                 bc -= 4;
6947         
6948                 /* allocation size */
6949                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
6950                 COUNT_BYTES(8);
6951         
6952                 /* Extended File Attributes */
6953                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
6954                 bc -= 4;
6955
6956                 /* share access */
6957                 offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
6958                 bc -= 4;
6959         
6960                 /* create disposition */
6961                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
6962                 COUNT_BYTES(4);
6963
6964                 /* create options */
6965                 offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
6966                 bc -= 4;
6967
6968                 /* sd length */
6969                 ntd->sd_len = tvb_get_letohl(tvb, offset);
6970                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
6971                 COUNT_BYTES(4);
6972
6973                 /* ea length */
6974                 ntd->ea_len = tvb_get_letohl(tvb, offset);
6975                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
6976                 COUNT_BYTES(4);
6977
6978                 /* file name len */
6979                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
6980                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
6981                 COUNT_BYTES(4);
6982
6983                 /* impersonation level */
6984                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
6985                 COUNT_BYTES(4);
6986         
6987                 /* security flags */
6988                 offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
6989                 bc -= 1;
6990
6991                 /* file name */
6992                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
6993                 if (fn != NULL) {
6994                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6995                                 fn);
6996                         COUNT_BYTES(fn_len);
6997                 }
6998
6999                 break;
7000         case NT_TRANS_IOCTL:
7001                 break;
7002         case NT_TRANS_SSD: {
7003                 guint16 fid;
7004
7005                 /* fid */
7006                 fid = tvb_get_letohs(tvb, offset);
7007                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7008                 offset += 2;
7009
7010                 /* 2 reserved bytes */
7011                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7012                 offset += 2;
7013
7014                 /* security information */
7015                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7016                 break;
7017         }
7018         case NT_TRANS_NOTIFY:
7019                 break;
7020         case NT_TRANS_RENAME:
7021                 /* XXX not documented */
7022                 break;
7023         case NT_TRANS_QSD: {
7024                 guint16 fid;
7025
7026                 /* fid */
7027                 fid = tvb_get_letohs(tvb, offset);
7028                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7029                 offset += 2;
7030
7031                 /* 2 reserved bytes */
7032                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7033                 offset += 2;
7034
7035                 /* security information */
7036                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
7037                 break;
7038         }
7039         }
7040
7041         return offset;
7042 }
7043
7044 static int
7045 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7046 {
7047         proto_item *item = NULL;
7048         proto_tree *tree = NULL;
7049         smb_info_t *si;
7050         int old_offset = offset;
7051
7052         si = (smb_info_t *)pinfo->private_data;
7053
7054         if(parent_tree){
7055                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7056                                 "%s Setup",
7057                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
7058                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7059         }
7060  
7061         switch(ntd->subcmd){
7062         case NT_TRANS_CREATE:
7063                 break;
7064         case NT_TRANS_IOCTL: {
7065                 guint16 fid;
7066
7067                 /* function code */
7068                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
7069                 offset += 4;
7070
7071                 /* fid */
7072                 fid = tvb_get_letohs(tvb, offset);
7073                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7074                 offset += 2;
7075
7076                 /* isfsctl */
7077                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
7078                 offset += 1;
7079
7080                 /* isflags */
7081                 offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
7082
7083                 break;
7084         }
7085         case NT_TRANS_SSD:
7086                 break;
7087         case NT_TRANS_NOTIFY: {
7088                 guint16 fid;
7089
7090                 /* completion filter */
7091                 offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
7092
7093                 /* fid */
7094                 fid = tvb_get_letohs(tvb, offset);
7095                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7096                 offset += 2;
7097
7098                 /* watch tree */
7099                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
7100                 offset += 1;
7101
7102                 /* reserved byte */
7103                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7104                 offset += 1;
7105
7106                 break;
7107         }
7108         case NT_TRANS_RENAME:
7109                 /* XXX not documented */
7110                 break;
7111         case NT_TRANS_QSD:
7112                 break;
7113         }
7114  
7115         return old_offset+len;
7116 }
7117
7118
7119 static int
7120 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7121 {
7122         guint8 wc, sc;
7123         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
7124         smb_info_t *si;
7125         smb_saved_info_t *sip;
7126         int subcmd;
7127         nt_trans_data ntd;
7128         guint16 bc;
7129         int padcnt;
7130         smb_nt_transact_info_t *nti;
7131
7132         si = (smb_info_t *)pinfo->private_data;
7133         sip = si->sip;
7134
7135         WORD_COUNT;
7136
7137         if(wc>=19){
7138                 /* primary request */
7139                 /* max setup count */
7140                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
7141                 offset += 1;
7142
7143                 /* 2 reserved bytes */
7144                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7145                 offset += 2;
7146         } else {
7147                 /* secondary request */
7148                 /* 3 reserved bytes */
7149                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7150                 offset += 3;
7151         }
7152
7153
7154         /* total param count */
7155         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
7156         offset += 4;
7157         
7158         /* total data count */
7159         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
7160         offset += 4;
7161
7162         if(wc>=19){
7163                 /* primary request */
7164                 /* max param count */
7165                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
7166                 offset += 4;
7167
7168                 /* max data count */
7169                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
7170                 offset += 4;
7171         }
7172
7173         /* param count */
7174         pc = tvb_get_letohl(tvb, offset);
7175         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7176         offset += 4;
7177         
7178         /* param offset */
7179         po = tvb_get_letohl(tvb, offset);
7180         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7181         offset += 4;
7182
7183         /* param displacement */
7184         if(wc>=19){
7185                 /* primary request*/
7186                 pd = 0;
7187         } else {
7188                 /* secondary request */
7189                 pd = tvb_get_letohl(tvb, offset);
7190                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7191                 offset += 4;
7192         }
7193
7194         /* data count */
7195         dc = tvb_get_letohl(tvb, offset);
7196         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7197         offset += 4;
7198
7199         /* data offset */
7200         od = tvb_get_letohl(tvb, offset);
7201         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7202         offset += 4;
7203
7204         /* data displacement */
7205         if(wc>=19){
7206                 /* primary request */
7207                 dd = 0;
7208         } else {
7209                 /* secondary request */
7210                 dd = tvb_get_letohl(tvb, offset);
7211                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7212                 offset += 4;
7213         }
7214
7215         /* setup count */
7216         if(wc>=19){
7217                 /* primary request */
7218                 sc = tvb_get_guint8(tvb, offset);
7219                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7220                 offset += 1;
7221         } else {
7222                 /* secondary request */
7223                 sc = 0;
7224         }
7225
7226         /* function */
7227         if(wc>=19){
7228                 /* primary request */
7229                 subcmd = tvb_get_letohs(tvb, offset);
7230                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
7231                 if(check_col(pinfo->cinfo, COL_INFO)){
7232                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7233                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
7234                 }
7235                 ntd.subcmd = subcmd;
7236                 if (!si->unidir) {
7237                         if(!pinfo->fd->flags.visited){
7238                                 /* 
7239                                  * Allocate a new smb_nt_transact_info_t
7240                                  * structure.
7241                                  */
7242                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
7243                                 nti->subcmd = subcmd;
7244                                 sip->extra_info = nti;
7245                         }
7246                 }
7247         } else {
7248                 /* secondary request */
7249                 if(check_col(pinfo->cinfo, COL_INFO)){
7250                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
7251                 }
7252         }
7253         offset += 2;
7254
7255         /* this is a padding byte */
7256         if(offset%1){
7257                 /* pad byte */
7258                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
7259                 offset += 1;
7260         }
7261
7262         /* if there were any setup bytes, decode them */
7263         if(sc){
7264                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
7265                 offset += sc*2;
7266         }
7267
7268         BYTE_COUNT;
7269         
7270         /* parameters */
7271         if(po>(guint32)offset){
7272                 /* We have some initial padding bytes.
7273                 */
7274                 padcnt = po-offset;
7275                 if (padcnt > bc)
7276                         padcnt = bc;
7277                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7278                 COUNT_BYTES(padcnt);
7279         }
7280         if(pc){
7281                 CHECK_BYTE_COUNT(pc);
7282                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
7283                 COUNT_BYTES(pc);
7284         }
7285
7286         /* data */
7287         if(od>(guint32)offset){
7288                 /* We have some initial padding bytes.
7289                 */
7290                 padcnt = od-offset;
7291                 if (padcnt > bc)
7292                         padcnt = bc;
7293                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7294                 COUNT_BYTES(padcnt);
7295         }
7296         if(dc){
7297                 CHECK_BYTE_COUNT(dc);
7298                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
7299                 COUNT_BYTES(dc);
7300         }
7301
7302         END_OF_SMB
7303
7304         return offset;
7305 }
7306
7307
7308
7309 static int
7310 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7311 {
7312         proto_item *item = NULL;
7313         proto_tree *tree = NULL;
7314         smb_info_t *si;
7315         smb_nt_transact_info_t *nti;
7316
7317         si = (smb_info_t *)pinfo->private_data;
7318         if (si->sip != NULL)
7319                 nti = si->sip->extra_info;
7320         else
7321                 nti = NULL;
7322
7323         if(parent_tree){
7324                 if(nti != NULL){
7325                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7326                                 "%s Data",
7327                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7328                 } else {
7329                         /*
7330                          * We never saw the request to which this is a
7331                          * response.
7332                          */
7333                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7334                                 "Unknown NT Transaction Data (matching request not seen)");
7335                 }
7336                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7337         }
7338
7339         if (nti == NULL) {
7340                 offset += len;
7341                 return offset;
7342         }
7343         switch(nti->subcmd){
7344         case NT_TRANS_CREATE:
7345                 break;
7346         case NT_TRANS_IOCTL:
7347                 /* ioctl data */
7348                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
7349                 offset += len;
7350
7351                 break;
7352         case NT_TRANS_SSD:
7353                 break;
7354         case NT_TRANS_NOTIFY:
7355                 break;
7356         case NT_TRANS_RENAME:
7357                 /* XXX not documented */
7358                 break;
7359         case NT_TRANS_QSD:
7360                 /*
7361                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
7362                  * which may be documented in the Win32 documentation
7363                  * somewhere.
7364                  */
7365                 offset = dissect_nt_sec_desc(tvb, pinfo, offset, tree, len);
7366                 break;
7367         }
7368
7369         return offset;
7370 }
7371  
7372 static int
7373 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd, guint16 bc)
7374 {
7375         proto_item *item = NULL;
7376         proto_tree *tree = NULL;
7377         guint32 fn_len;
7378         const char *fn;
7379         smb_info_t *si;
7380         smb_nt_transact_info_t *nti;
7381         guint16 fid;
7382
7383         si = (smb_info_t *)pinfo->private_data;
7384         if (si->sip != NULL)
7385                 nti = si->sip->extra_info;
7386         else
7387                 nti = NULL;
7388
7389         if(parent_tree){
7390                 if(nti != NULL){
7391                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7392                                 "%s Parameters",
7393                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7394                 } else {
7395                         /*
7396                          * We never saw the request to which this is a
7397                          * response.
7398                          */
7399                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7400                                 "Unknown NT Transaction Parameters (matching request not seen)");
7401                 }
7402                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7403         }
7404
7405         if (nti == NULL) {
7406                 offset += len;
7407                 return offset;
7408         }
7409         switch(nti->subcmd){
7410         case NT_TRANS_CREATE:
7411                 /* oplock level */
7412                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7413                 offset += 1;
7414
7415                 /* reserved byte */
7416                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7417                 offset += 1;
7418                 
7419                 /* fid */
7420                 fid = tvb_get_letohs(tvb, offset);
7421                 add_fid(tvb, pinfo, tree, offset, 2, fid);
7422                 offset += 2;
7423
7424                 /* create action */
7425                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7426                 offset += 4;
7427
7428                 /* ea error offset */
7429                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
7430                 offset += 4;
7431
7432                 /* create time */
7433                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7434                         hf_smb_create_time);
7435         
7436                 /* access time */
7437                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7438                         hf_smb_access_time);
7439         
7440                 /* last write time */
7441                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7442                         hf_smb_last_write_time);
7443         
7444                 /* last change time */
7445                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7446                         hf_smb_change_time);
7447         
7448                 /* Extended File Attributes */
7449                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7450
7451                 /* allocation size */
7452                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7453                 offset += 8;
7454
7455                 /* end of file */
7456                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
7457                 offset += 8;
7458
7459                 /* File Type */
7460                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
7461                 offset += 2;
7462
7463                 /* device state */
7464                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
7465
7466                 /* is directory */
7467                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
7468                 offset += 1;
7469                 break;
7470         case NT_TRANS_IOCTL:
7471                 break;
7472         case NT_TRANS_SSD:
7473                 break;
7474         case NT_TRANS_NOTIFY:
7475                 while(len){
7476                         /* next entry offset */
7477                         proto_tree_add_item(tree, hf_smb_next_entry_offset, tvb, offset, 4, TRUE);
7478                         COUNT_BYTES(4);
7479                         len -= 4;
7480                         /* broken implementations */
7481                         if(len<0)break;
7482         
7483                         /* action */
7484                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
7485                         COUNT_BYTES(4);
7486                         len -= 4;
7487                         /* broken implementations */
7488                         if(len<0)break;
7489
7490                         /* file name len */
7491                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
7492                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
7493                         COUNT_BYTES(4);
7494                         len -= 4;
7495                         /* broken implementations */
7496                         if(len<0)break;
7497
7498                         /* file name */
7499                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
7500                         if (fn == NULL)
7501                                 break;
7502                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7503                                 fn);
7504                         COUNT_BYTES(fn_len);
7505                         len -= fn_len;
7506                         /* broken implementations */
7507                         if(len<0)break;
7508
7509                 }
7510                 break;
7511         case NT_TRANS_RENAME:
7512                 /* XXX not documented */
7513                 break;
7514         case NT_TRANS_QSD:
7515                 /*
7516                  * This appears to be the size of the security
7517                  * descriptor; the calling sequence of
7518                  * "ZwQuerySecurityObject()" suggests that it would
7519                  * be.  The actual security descriptor wouldn't
7520                  * follow if the max data count in the request
7521                  * was smaller; this lets the client know how
7522                  * big a buffer it needs to provide.
7523                  */
7524                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
7525                 offset += 4;
7526                 break;
7527         }
7528
7529         return offset;
7530 }
7531  
7532 static int
7533 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
7534 {
7535         proto_item *item = NULL;
7536         proto_tree *tree = NULL;
7537         smb_info_t *si;
7538         smb_nt_transact_info_t *nti;
7539
7540         si = (smb_info_t *)pinfo->private_data;
7541         if (si->sip != NULL)
7542                 nti = si->sip->extra_info;
7543         else
7544                 nti = NULL;
7545
7546         if(parent_tree){
7547                 if(nti != NULL){
7548                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7549                                 "%s Setup",
7550                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
7551                 } else {
7552                         /*
7553                          * We never saw the request to which this is a
7554                          * response.
7555                          */
7556                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
7557                                 "Unknown NT Transaction Setup (matching request not seen)");
7558                 }
7559                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
7560         }
7561
7562         if (nti == NULL) {
7563                 offset += len;
7564                 return offset;
7565         }
7566         switch(nti->subcmd){
7567         case NT_TRANS_CREATE:
7568                 break;
7569         case NT_TRANS_IOCTL:
7570                 break;
7571         case NT_TRANS_SSD:
7572                 break;
7573         case NT_TRANS_NOTIFY:
7574                 break;
7575         case NT_TRANS_RENAME:
7576                 /* XXX not documented */
7577                 break;
7578         case NT_TRANS_QSD:
7579                 break;
7580         }
7581
7582         return offset;
7583 }
7584
7585 static int
7586 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7587 {
7588         guint8 wc, sc;
7589         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
7590         guint32 td=0, tp=0;
7591         smb_info_t *si;
7592         smb_nt_transact_info_t *nti;
7593         static nt_trans_data ntd;
7594         guint16 bc;
7595         int padcnt;
7596         fragment_data *r_fd = NULL;
7597         tvbuff_t *pd_tvb=NULL;
7598         gboolean save_fragmented;
7599
7600         si = (smb_info_t *)pinfo->private_data;
7601         if (si->sip != NULL)
7602                 nti = si->sip->extra_info;
7603         else
7604                 nti = NULL;
7605
7606         /* primary request */
7607         if(nti != NULL){
7608                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
7609                 if(check_col(pinfo->cinfo, COL_INFO)){
7610                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
7611                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
7612                 }
7613         } else {
7614                 proto_tree_add_text(tree, tvb, offset, 0,
7615                         "Function: <unknown function - could not find matching request>");
7616                 if(check_col(pinfo->cinfo, COL_INFO)){
7617                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
7618                 }
7619         }
7620
7621         WORD_COUNT;
7622
7623         /* 3 reserved bytes */
7624         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
7625         offset += 3;
7626
7627         /* total param count */
7628         tp = tvb_get_letohl(tvb, offset);
7629         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
7630         offset += 4;
7631         
7632         /* total data count */
7633         td = tvb_get_letohl(tvb, offset);
7634         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
7635         offset += 4;
7636
7637         /* param count */
7638         pc = tvb_get_letohl(tvb, offset);
7639         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
7640         offset += 4;
7641         
7642         /* param offset */
7643         po = tvb_get_letohl(tvb, offset);
7644         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
7645         offset += 4;
7646
7647         /* param displacement */
7648         pd = tvb_get_letohl(tvb, offset);
7649         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
7650         offset += 4;
7651
7652         /* data count */
7653         dc = tvb_get_letohl(tvb, offset);
7654         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
7655         offset += 4;
7656
7657         /* data offset */
7658         od = tvb_get_letohl(tvb, offset);
7659         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
7660         offset += 4;
7661
7662         /* data displacement */
7663         dd = tvb_get_letohl(tvb, offset);
7664         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
7665         offset += 4;
7666
7667         /* setup count */
7668         sc = tvb_get_guint8(tvb, offset);
7669         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
7670         offset += 1;
7671
7672         /* setup data */        
7673         if(sc){
7674                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
7675                 offset += sc*2;
7676         }
7677
7678         BYTE_COUNT;
7679
7680         /* reassembly of SMB NT Transaction data payload.
7681            In this section we do reassembly of both the data and parameters
7682            blocks of the SMB transaction command.
7683         */
7684         save_fragmented = pinfo->fragmented;
7685         /* do we need reassembly? */
7686         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
7687                 /* oh yeah, either data or parameter section needs 
7688                    reassembly...
7689                 */
7690                 pinfo->fragmented = TRUE;
7691                 if(smb_trans_reassembly){
7692                         /* ...and we were told to do reassembly */
7693                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
7694                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
7695                                                              po, pc, pd, td+tp);
7696                                 
7697                         }
7698                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
7699                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
7700                                                              od, dc, dd+tp, td+tp);
7701                         }
7702                 }
7703         }
7704
7705         /* if we got a reassembled fd structure from the reassembly routine we
7706            must create pd_tvb from it 
7707         */
7708         if(r_fd){
7709                 proto_tree *tr;
7710                 proto_item *it;
7711                 fragment_data *fd;
7712                 
7713                 it = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
7714                 tr = proto_item_add_subtree(it, ett_smb_segments);
7715                 for(fd=r_fd->next;fd;fd=fd->next){
7716                         proto_tree_add_text(tr, tvb, 0, 0, "Frame:%u Data:%u-%u",
7717                                             fd->frame, fd->offset, fd->offset+fd->len-1);
7718                 }
7719                 
7720                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
7721                                              r_fd->datalen);
7722                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
7723                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
7724                 pinfo->fragmented = FALSE;
7725         }
7726
7727
7728         if(pd_tvb){
7729           /* we have reassembled data, grab param and data from there */
7730           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
7731                                           &ntd, tvb_length(pd_tvb));
7732           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
7733         } else {
7734           /* we do not have reassembled data, just use what we have in the 
7735              packet as well as we can */
7736           /* parameters */
7737           if(po>(guint32)offset){
7738             /* We have some initial padding bytes.
7739              */
7740             padcnt = po-offset;
7741             if (padcnt > bc)
7742               padcnt = bc;
7743             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7744             COUNT_BYTES(padcnt);
7745           }
7746           if(pc){
7747             CHECK_BYTE_COUNT(pc);
7748             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
7749             COUNT_BYTES(pc);
7750           }
7751           
7752           /* data */
7753           if(od>(guint32)offset){
7754             /* We have some initial padding bytes.
7755              */
7756             padcnt = od-offset;
7757             if (padcnt > bc)
7758               padcnt = bc;
7759             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
7760             COUNT_BYTES(padcnt);
7761           }
7762           if(dc){
7763             CHECK_BYTE_COUNT(dc);
7764             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
7765             COUNT_BYTES(dc);
7766           }
7767         }
7768         pinfo->fragmented = save_fragmented;
7769
7770         END_OF_SMB
7771
7772         return offset;
7773 }
7774
7775 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7776    NT Transaction command  ends here
7777    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7778
7779 static const value_string print_mode_vals[] = {
7780         {0,     "Text Mode"},
7781         {1,     "Graphics Mode"},
7782         {0, NULL}
7783 };
7784  
7785 static int
7786 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7787 {
7788         int fn_len;
7789         const char *fn;
7790         guint8 wc;
7791         guint16 bc;
7792
7793         WORD_COUNT;
7794
7795         /* setup len */
7796         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
7797         offset += 2;
7798
7799         /* print mode */
7800         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
7801         offset += 2;
7802
7803         BYTE_COUNT;
7804
7805         /* buffer format */
7806         CHECK_BYTE_COUNT(1);
7807         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
7808         COUNT_BYTES(1);
7809
7810         /* print identifier */
7811         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
7812         if (fn == NULL)
7813                 goto endofcommand;
7814         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
7815                 fn);
7816         COUNT_BYTES(fn_len);
7817
7818         END_OF_SMB
7819
7820         return offset;
7821 }
7822
7823
7824 static int
7825 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7826 {
7827         int cnt;
7828         guint8 wc;
7829         guint16 bc, fid;
7830
7831         WORD_COUNT;
7832
7833         /* fid */
7834         fid = tvb_get_letohs(tvb, offset);
7835         add_fid(tvb, pinfo, tree, offset, 2, fid);
7836         offset += 2;
7837
7838         BYTE_COUNT;
7839
7840         /* buffer format */
7841         CHECK_BYTE_COUNT(1);
7842         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
7843         COUNT_BYTES(1);
7844
7845         /* data len */
7846         CHECK_BYTE_COUNT(2);
7847         cnt = tvb_get_letohs(tvb, offset);
7848         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
7849         COUNT_BYTES(2);
7850
7851         /* file data */
7852         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
7853
7854         END_OF_SMB
7855
7856         return offset;
7857 }
7858
7859
7860 static const value_string print_status_vals[] = {
7861         {1,     "Held or Stopped"},
7862         {2,     "Printing"},
7863         {3,     "Awaiting print"},
7864         {4,     "In intercept"},
7865         {5,     "File had error"},
7866         {6,     "Printer error"},
7867         {0, NULL}
7868 };
7869  
7870 static int
7871 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7872 {
7873         guint8 wc;
7874         guint16 bc;
7875
7876         WORD_COUNT;
7877
7878         /* max count */
7879         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
7880         offset += 2;
7881
7882         /* start index */
7883         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
7884         offset += 2;
7885
7886         BYTE_COUNT;
7887
7888         END_OF_SMB
7889
7890         return offset;
7891 }
7892
7893 static int
7894 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
7895     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
7896 {
7897         proto_item *item = NULL;
7898         proto_tree *tree = NULL;
7899         int fn_len;
7900         const char *fn;
7901
7902         if(parent_tree){
7903                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
7904                         "Queue entry");
7905                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
7906         }
7907
7908         /* queued time */
7909         CHECK_BYTE_COUNT_SUBR(4);
7910         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
7911                 hf_smb_print_queue_date,
7912                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
7913         *bcp -= 4;
7914
7915         /* status */
7916         CHECK_BYTE_COUNT_SUBR(1);
7917         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
7918         COUNT_BYTES_SUBR(1);
7919
7920         /* spool file number */
7921         CHECK_BYTE_COUNT_SUBR(2);
7922         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
7923         COUNT_BYTES_SUBR(2);
7924
7925         /* spool file size */
7926         CHECK_BYTE_COUNT_SUBR(4);
7927         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
7928         COUNT_BYTES_SUBR(4);
7929
7930         /* reserved byte */
7931         CHECK_BYTE_COUNT_SUBR(1);
7932         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7933         COUNT_BYTES_SUBR(1);
7934
7935         /* file name */
7936         fn_len = 16;
7937         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
7938         CHECK_STRING_SUBR(fn);
7939         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
7940                 fn);
7941         COUNT_BYTES_SUBR(fn_len);
7942
7943         *trunc = FALSE;
7944         return offset;
7945 }
7946
7947 static int
7948 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7949 {
7950         guint16 cnt=0, len;
7951         guint8 wc;
7952         guint16 bc;
7953         gboolean trunc;
7954
7955         WORD_COUNT;
7956
7957         /* count */
7958         cnt = tvb_get_letohs(tvb, offset);
7959         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
7960         offset += 2;
7961
7962         /* restart index */
7963         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
7964         offset += 2;
7965
7966         BYTE_COUNT;
7967
7968         /* buffer format */
7969         CHECK_BYTE_COUNT(1);
7970         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
7971         COUNT_BYTES(1);
7972
7973         /* data len */
7974         CHECK_BYTE_COUNT(2);
7975         len = tvb_get_letohs(tvb, offset);
7976         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
7977         COUNT_BYTES(2);
7978
7979         /* queue elements */
7980         while(cnt--){
7981                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
7982                     &bc, &trunc);
7983                 if (trunc)
7984                         goto endofcommand;
7985         }
7986
7987         END_OF_SMB
7988
7989         return offset;
7990 }
7991
7992
7993 static int
7994 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7995 {
7996         guint8  wc, cmd=0xff;
7997         guint16 andxoffset=0;
7998         guint16 bc;
7999         int fn_len;
8000         const char *fn;
8001
8002         WORD_COUNT;
8003
8004         /* next smb command */
8005         cmd = tvb_get_guint8(tvb, offset);
8006         if(cmd!=0xff){
8007                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8008         } else {
8009                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
8010         }
8011         offset += 1;
8012
8013         /* reserved byte */
8014         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8015         offset += 1;
8016
8017         /* andxoffset */
8018         andxoffset = tvb_get_letohs(tvb, offset);
8019         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8020         offset += 2;
8021
8022         /* reserved byte */
8023         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8024         offset += 1;
8025
8026         /* file name len */
8027         fn_len = tvb_get_letohs(tvb, offset);
8028         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
8029         offset += 2;
8030
8031         /* Create flags */
8032         offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
8033
8034         /* root directory fid */
8035         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8036         offset += 4;
8037
8038         /* nt access mask */
8039         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
8040
8041         /* allocation size */
8042         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8043         offset += 8;
8044
8045         /* Extended File Attributes */
8046         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8047
8048         /* share access */
8049         offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
8050
8051         /* create disposition */
8052         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8053         offset += 4;
8054
8055         /* create options */
8056         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
8057
8058         /* impersonation level */
8059         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8060         offset += 4;
8061
8062         /* security flags */
8063         offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
8064
8065         BYTE_COUNT;
8066
8067         /* file name */
8068         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8069         if (fn == NULL)
8070                 goto endofcommand;
8071         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8072                 fn);
8073         COUNT_BYTES(fn_len);
8074
8075         if (check_col(pinfo->cinfo, COL_INFO)) {
8076                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
8077         }
8078
8079         END_OF_SMB
8080
8081         /* call AndXCommand (if there are any) */
8082         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8083
8084         return offset;
8085 }
8086  
8087
8088 static int
8089 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8090 {
8091         guint8  wc, cmd=0xff;
8092         guint16 andxoffset=0;
8093         guint16 bc;
8094         guint16 fid;
8095
8096         WORD_COUNT;
8097
8098         /* next smb command */
8099         cmd = tvb_get_guint8(tvb, offset);
8100         if(cmd!=0xff){
8101                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
8102         } else {
8103                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
8104         }
8105         offset += 1;
8106
8107         /* reserved byte */
8108         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8109         offset += 1;
8110
8111         /* andxoffset */
8112         andxoffset = tvb_get_letohs(tvb, offset);
8113         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
8114         offset += 2;
8115
8116         /* oplock level */
8117         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8118         offset += 1;
8119
8120         /* fid */
8121         fid = tvb_get_letohs(tvb, offset);
8122         add_fid(tvb, pinfo, tree, offset, 2, fid);
8123         offset += 2;
8124
8125         /* create action */
8126         /*XXX is this really the same as create disposition in the request? it looks so*/
8127         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8128         offset += 4;
8129
8130         /* create time */
8131         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8132                 hf_smb_create_time);
8133         
8134         /* access time */
8135         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8136                 hf_smb_access_time);
8137         
8138         /* last write time */
8139         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8140                 hf_smb_last_write_time);
8141
8142         /* last change time */
8143         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8144                 hf_smb_change_time);
8145         
8146         /* Extended File Attributes */
8147         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
8148
8149         /* allocation size */
8150         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8151         offset += 8;
8152
8153         /* end of file */
8154         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8155         offset += 8;
8156
8157         /* File Type */
8158         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8159         offset += 2;
8160
8161         /* IPC State */
8162         offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
8163
8164         /* is directory */
8165         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8166         offset += 1;
8167
8168         BYTE_COUNT;
8169
8170         END_OF_SMB
8171
8172         /* call AndXCommand (if there are any) */
8173         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
8174
8175         return offset;
8176 }
8177
8178
8179 static int
8180 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8181 {
8182         guint8 wc;
8183         guint16 bc;
8184
8185         WORD_COUNT;
8186  
8187         BYTE_COUNT;
8188
8189         END_OF_SMB
8190
8191         return offset;
8192 }
8193
8194 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8195    BEGIN Transaction/Transaction2 Primary and secondary requests
8196    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
8197
8198
8199 static const value_string trans2_cmd_vals[] = {
8200         { 0x00,         "OPEN2" },
8201         { 0x01,         "FIND_FIRST2" },
8202         { 0x02,         "FIND_NEXT2" },
8203         { 0x03,         "QUERY_FS_INFORMATION" },
8204         { 0x04,         "QUOTAS" },
8205         { 0x05,         "QUERY_PATH_INFORMATION" },
8206         { 0x06,         "SET_PATH_INFORMATION" },
8207         { 0x07,         "QUERY_FILE_INFORMATION" },
8208         { 0x08,         "SET_FILE_INFORMATION" },
8209         { 0x09,         "FSCTL" },
8210         { 0x0A,         "IOCTL2" },
8211         { 0x0B,         "FIND_NOTIFY_FIRST" },
8212         { 0x0C,         "FIND_NOTIFY_NEXT" },
8213         { 0x0D,         "CREATE_DIRECTORY" },
8214         { 0x0E,         "SESSION_SETUP" },
8215         { 0x10,         "GET_DFS_REFERRAL" },
8216         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
8217         { 0,    NULL }
8218 };
8219
8220 static const true_false_string tfs_tf_dtid = {
8221         "Also DISCONNECT TID",
8222         "Do NOT disconnect TID"
8223 };
8224 static const true_false_string tfs_tf_owt = {
8225         "One Way Transaction (NO RESPONSE)",
8226         "Two way transaction"
8227 };
8228
8229 static const true_false_string tfs_ff2_backup = {
8230         "Find WITH backup intent",
8231         "No backup intent"
8232 };
8233 static const true_false_string tfs_ff2_continue = {
8234         "CONTINUE search from previous position",
8235         "New search, do NOT continue from previous position"
8236 };
8237 static const true_false_string tfs_ff2_resume = {
8238         "Return RESUME keys",
8239         "Do NOT return resume keys"
8240 };
8241 static const true_false_string tfs_ff2_close_eos = {
8242         "CLOSE search if END OF SEARCH is reached",
8243         "Do NOT close search if end of search reached"
8244 };
8245 static const true_false_string tfs_ff2_close = {
8246         "CLOSE search after this request",
8247         "Do NOT close search after this request"
8248 };
8249
8250 /* used by
8251    TRANS2_FIND_FIRST2
8252 */
8253 static const value_string ff2_il_vals[] = {
8254         { 1,            "Info Standard  (4.3.4.1)"},
8255         { 2,            "Info Query EA Size  (4.3.4.2)"},
8256         { 3,            "Info Query EAs From List  (4.3.4.2)"},
8257         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
8258         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
8259         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
8260         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
8261         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
8262         {0, NULL}
8263 };
8264
8265 /* values used by :
8266         TRANS2_QUERY_PATH_INFORMATION
8267         TRANS2_SET_PATH_INFORMATION
8268 */
8269 static const value_string qpi_loi_vals[] = {
8270         { 1,            "Info Standard  (4.2.14.1)"},
8271         { 2,            "Info Query EA Size  (4.2.14.1)"},
8272         { 3,            "Info Query EAs From List  (4.2.14.2)"},
8273         { 4,            "Info Query All EAs  (4.2.14.2)"},
8274         { 6,            "Info Is Name Valid  (4.2.14.3)"},
8275         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
8276         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
8277         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
8278         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
8279         { 0x0107,       "Query File All Info  (4.2.14.8)"},
8280         { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
8281         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
8282         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
8283         { 0x0200,       "Set File Unix Basic"},
8284         { 0x0201,       "Set File Unix Link"},
8285         { 0x0202,       "Set File Unix HardLink"},
8286         {0, NULL}
8287 };
8288
8289 static const value_string qfsi_vals[] = {
8290         { 1,            "Info Allocation"},
8291         { 2,            "Info Volume"},
8292         { 0x0102,       "Query FS Volume Info"},
8293         { 0x0103,       "Query FS Size Info"},
8294         { 0x0104,       "Query FS Device Info"},
8295         { 0x0105,       "Query FS Attribute Info"},
8296         { 1006,         "Query FS Quota Info"},
8297         {0, NULL}
8298 };
8299
8300 static const value_string delete_pending_vals[] = {
8301         {0,     "Normal, no pending delete"},
8302         {1,     "This object has DELETE PENDING"},
8303         {0, NULL}
8304 };
8305
8306 static const value_string alignment_vals[] = {
8307         {0,     "Byte alignment"},
8308         {1,     "Word (16bit) alignment"},
8309         {3,     "Long (32bit) alignment"},
8310         {7,     "8 byte boundary alignment"},
8311         {0x0f,  "16 byte boundary alignment"},
8312         {0x1f,  "32 byte boundary alignment"},
8313         {0x3f,  "64 byte boundary alignment"},
8314         {0x7f,  "128 byte boundary alignment"},
8315         {0xff,  "256 byte boundary alignment"},
8316         {0x1ff, "512 byte boundary alignment"},
8317         {0, NULL}
8318 };
8319
8320
8321 static const true_false_string tfs_get_dfs_server_hold_storage = {
8322         "Referral SERVER HOLDS STORAGE for the file",
8323         "Referral server does NOT hold storage for the file"
8324 };
8325 static const true_false_string tfs_get_dfs_fielding = {
8326         "The server in referral is FIELDING CAPABLE",
8327         "The server in referrals is NOT fielding capable"
8328 };
8329
8330 static const true_false_string tfs_dfs_referral_flags_strip = {
8331         "STRIP off pathconsumed characters before submitting",
8332         "Do NOT strip off any characters"
8333 };
8334
8335 static const value_string dfs_referral_server_type_vals[] = {
8336         {0,     "Don't know"},
8337         {1,     "SMB Server"},
8338         {2,     "Netware Server"},
8339         {3,     "Domain Server"},
8340         {0, NULL}
8341 };
8342
8343
8344 static const true_false_string tfs_device_char_removable = {
8345         "This is a REMOVABLE device",
8346         "This is NOT a removable device"
8347 };
8348 static const true_false_string tfs_device_char_read_only = {
8349         "This is a READ-ONLY device",
8350         "This is NOT a read-only device"
8351 };
8352 static const true_false_string tfs_device_char_floppy = {
8353         "This is a FLOPPY DISK device",
8354         "This is NOT a floppy disk device"
8355 };
8356 static const true_false_string tfs_device_char_write_once = {
8357         "This is a WRITE-ONCE device",
8358         "This is NOT a write-once device"
8359 };
8360 static const true_false_string tfs_device_char_remote = {
8361         "This is a REMOTE device",
8362         "This is NOT a remote device"
8363 };
8364 static const true_false_string tfs_device_char_mounted = {
8365         "This device is MOUNTED",
8366         "This device is NOT mounted"
8367 };
8368 static const true_false_string tfs_device_char_virtual = {
8369         "This is a VIRTUAL device",
8370         "This is NOT a virtual device"
8371 };
8372
8373
8374 static const true_false_string tfs_fs_attr_css = {
8375         "This FS supports CASE SENSITIVE SEARCHes",
8376         "This FS does NOT support case sensitive searches"
8377 };
8378 static const true_false_string tfs_fs_attr_cpn = {
8379         "This FS supports CASE PRESERVED NAMES",
8380         "This FS does NOT support case preserved names"
8381 };
8382 static const true_false_string tfs_fs_attr_pacls = {
8383         "This FS supports PERSISTENT ACLs",
8384         "This FS does NOT support persistent acls"
8385 };
8386 static const true_false_string tfs_fs_attr_fc = {
8387         "This FS supports COMPRESSED FILES",
8388         "This FS does NOT support compressed files"
8389 };
8390 static const true_false_string tfs_fs_attr_vq = {
8391         "This FS supports VOLUME QUOTAS",
8392         "This FS does NOT support volume quotas"
8393 };
8394 static const true_false_string tfs_fs_attr_dim = {
8395         "This FS is on a MOUNTED DEVICE",
8396         "This FS is NOT on a mounted device"
8397 };
8398 static const true_false_string tfs_fs_attr_vic = {
8399         "This FS is on a COMPRESSED VOLUME",
8400         "This FS is NOT on a compressed volume"
8401 };
8402
8403
8404
8405 static int
8406 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8407 {
8408         guint16 mask;
8409         proto_item *item = NULL;
8410         proto_tree *tree = NULL;
8411
8412         mask = tvb_get_letohs(tvb, offset);
8413
8414         if(parent_tree){
8415                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8416                         "Flags: 0x%04x", mask);
8417                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
8418         }
8419
8420         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
8421                 tvb, offset, 2, mask);
8422         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
8423                 tvb, offset, 2, mask);
8424         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
8425                 tvb, offset, 2, mask);
8426         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
8427                 tvb, offset, 2, mask);
8428         proto_tree_add_boolean(tree, hf_smb_ff2_close,
8429                 tvb, offset, 2, mask);
8430
8431         offset += 2;
8432
8433         return offset;
8434 }
8435
8436 static int
8437 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
8438     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
8439 {
8440         proto_item *item = NULL;
8441         proto_tree *tree = NULL;
8442         smb_info_t *si;
8443         smb_transact2_info_t *t2i;
8444         int fn_len;
8445         const char *fn;
8446         int old_offset = offset;
8447
8448         si = (smb_info_t *)pinfo->private_data;
8449         if (si->sip != NULL)
8450                 t2i = si->sip->extra_info;
8451         else
8452                 t2i = NULL;
8453
8454         if(parent_tree){
8455                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8456                                 "%s Parameters",
8457                                 val_to_str(subcmd, trans2_cmd_vals, 
8458                                            "Unknown (0x%02x)"));
8459                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
8460         }
8461
8462         switch(subcmd){
8463         case 0x00:      /*TRANS2_OPEN2*/
8464                 /* open flags */
8465                 CHECK_BYTE_COUNT_TRANS(2);
8466                 offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
8467                 bc -= 2;
8468
8469                 /* desired access */
8470                 CHECK_BYTE_COUNT_TRANS(2);
8471                 offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
8472                 bc -= 2;
8473
8474                 /* 2 reserved bytes */
8475                 CHECK_BYTE_COUNT_TRANS(2);
8476                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8477                 COUNT_BYTES_TRANS(2);
8478
8479                 /* File Attributes */
8480                 CHECK_BYTE_COUNT_TRANS(2);
8481                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
8482                 bc -= 2;
8483
8484                 /* create time */
8485                 CHECK_BYTE_COUNT_TRANS(4);
8486                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8487                         hf_smb_create_time,
8488                         hf_smb_create_dos_date, hf_smb_create_dos_time,
8489                         TRUE);
8490                 bc -= 4;
8491
8492                 /* open function */
8493                 CHECK_BYTE_COUNT_TRANS(2);
8494                 offset = dissect_open_function(tvb, pinfo, tree, offset);
8495                 bc -= 2;
8496
8497                 /* allocation size */
8498                 CHECK_BYTE_COUNT_TRANS(4);
8499                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
8500                 COUNT_BYTES_TRANS(4);
8501
8502                 /* 10 reserved bytes */
8503                 CHECK_BYTE_COUNT_TRANS(10);
8504                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
8505                 COUNT_BYTES_TRANS(10);
8506
8507                 /* file name */
8508                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8509                 CHECK_STRING_TRANS(fn);
8510                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8511                         fn);
8512                 COUNT_BYTES_TRANS(fn_len);
8513
8514                 if (check_col(pinfo->cinfo, COL_INFO)) {
8515                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8516                         fn);
8517                 }
8518
8519                 /* XXX dont know how to decode FEAList */
8520                 break;
8521         case 0x01:      /*TRANS2_FIND_FIRST2*/
8522                 /* Search Attributes */
8523                 CHECK_BYTE_COUNT_TRANS(2);
8524                 offset = dissect_search_attributes(tvb, pinfo, tree, offset);
8525                 bc -= 2;
8526
8527                 /* search count */
8528                 CHECK_BYTE_COUNT_TRANS(2);
8529                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8530                 COUNT_BYTES_TRANS(2);
8531
8532                 /* Find First2 flags */
8533                 CHECK_BYTE_COUNT_TRANS(2);
8534                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8535                 bc -= 2;
8536
8537                 /* Find First2 information level */
8538                 CHECK_BYTE_COUNT_TRANS(2);
8539                 si->info_level = tvb_get_letohs(tvb, offset);
8540                 if (!pinfo->fd->flags.visited)
8541                         t2i->info_level = si->info_level;
8542                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8543                 COUNT_BYTES_TRANS(2);
8544
8545                 /* storage type */
8546                 CHECK_BYTE_COUNT_TRANS(4);
8547                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
8548                 COUNT_BYTES_TRANS(4);
8549
8550                 /* search pattern */
8551                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8552                 CHECK_STRING_TRANS(fn);
8553                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
8554                         fn);
8555                 COUNT_BYTES_TRANS(fn_len);
8556
8557                 if (check_col(pinfo->cinfo, COL_INFO)) {
8558                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
8559                         fn);
8560                 }
8561
8562                 /* XXX dont know how to decode FEAList */
8563
8564                 break;
8565         case 0x02:      /*TRANS2_FIND_NEXT2*/
8566                 /* sid */
8567                 CHECK_BYTE_COUNT_TRANS(2);
8568                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
8569                 COUNT_BYTES_TRANS(2);
8570
8571                 /* search count */
8572                 CHECK_BYTE_COUNT_TRANS(2);
8573                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
8574                 COUNT_BYTES_TRANS(2);
8575
8576                 /* Find First2 information level */
8577                 CHECK_BYTE_COUNT_TRANS(2);
8578                 si->info_level = tvb_get_letohs(tvb, offset);
8579                 if (!pinfo->fd->flags.visited)
8580                         t2i->info_level = si->info_level;
8581                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
8582                 COUNT_BYTES_TRANS(2);
8583
8584                 /* resume key */
8585                 CHECK_BYTE_COUNT_TRANS(4);
8586                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
8587                 COUNT_BYTES_TRANS(4);
8588
8589                 /* Find First2 flags */
8590                 CHECK_BYTE_COUNT_TRANS(2);
8591                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
8592                 bc -= 2;
8593
8594                 /* file name */
8595                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8596                 CHECK_STRING_TRANS(fn);
8597                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8598                         fn);
8599                 COUNT_BYTES_TRANS(fn_len);
8600
8601                 if (check_col(pinfo->cinfo, COL_INFO)) {
8602                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
8603                         fn);
8604                 }
8605
8606                 break;
8607         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
8608                 /* level of interest */
8609                 CHECK_BYTE_COUNT_TRANS(2);
8610                 si->info_level = tvb_get_letohs(tvb, offset);
8611                 if (!pinfo->fd->flags.visited)
8612                         t2i->info_level = si->info_level;
8613                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
8614                 COUNT_BYTES_TRANS(2);
8615
8616                 break;
8617         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
8618                 /* level of interest */
8619                 CHECK_BYTE_COUNT_TRANS(2);
8620                 si->info_level = tvb_get_letohs(tvb, offset);
8621                 if (!pinfo->fd->flags.visited)
8622                         t2i->info_level = si->info_level;
8623                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8624                 COUNT_BYTES_TRANS(2);
8625                 
8626                 /* 4 reserved bytes */
8627                 CHECK_BYTE_COUNT_TRANS(4);
8628                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
8629                 COUNT_BYTES_TRANS(4);
8630
8631                 /* file name */
8632                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8633                 CHECK_STRING_TRANS(fn);
8634                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8635                         fn);
8636                 COUNT_BYTES_TRANS(fn_len);
8637
8638                 if (check_col(pinfo->cinfo, COL_INFO)) {
8639                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8640                         fn);
8641                 }
8642
8643                 break;
8644         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
8645                 /* level of interest */
8646                 CHECK_BYTE_COUNT_TRANS(2);
8647                 si->info_level = tvb_get_letohs(tvb, offset);
8648                 if (!pinfo->fd->flags.visited)
8649                         t2i->info_level = si->info_level;
8650                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8651                 COUNT_BYTES_TRANS(2);
8652                 
8653                 /* 4 reserved bytes */
8654                 CHECK_BYTE_COUNT_TRANS(4);
8655                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
8656                 COUNT_BYTES_TRANS(4);
8657
8658                 /* file name */
8659                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8660                 CHECK_STRING_TRANS(fn);
8661                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8662                         fn);
8663                 COUNT_BYTES_TRANS(fn_len);
8664
8665                 if (check_col(pinfo->cinfo, COL_INFO)) {
8666                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
8667                         fn);
8668                 }
8669
8670                 break;
8671         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
8672                 guint16 fid;
8673
8674                 /* fid */
8675                 CHECK_BYTE_COUNT_TRANS(2);
8676                 fid = tvb_get_letohs(tvb, offset);
8677                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8678                 COUNT_BYTES_TRANS(2);
8679
8680                 /* level of interest */
8681                 CHECK_BYTE_COUNT_TRANS(2);
8682                 si->info_level = tvb_get_letohs(tvb, offset);
8683                 if (!pinfo->fd->flags.visited)
8684                         t2i->info_level = si->info_level;
8685                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8686                 COUNT_BYTES_TRANS(2);
8687                 
8688                 break;
8689         }
8690         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
8691                 guint16 fid;
8692
8693                 /* fid */
8694                 CHECK_BYTE_COUNT_TRANS(2);
8695                 fid = tvb_get_letohs(tvb, offset);
8696                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8697                 COUNT_BYTES_TRANS(2);
8698
8699                 /* level of interest */
8700                 CHECK_BYTE_COUNT_TRANS(2);
8701                 si->info_level = tvb_get_letohs(tvb, offset);
8702                 if (!pinfo->fd->flags.visited)
8703                         t2i->info_level = si->info_level;
8704                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
8705                 COUNT_BYTES_TRANS(2);
8706                 
8707                 /* 2 reserved bytes */
8708                 CHECK_BYTE_COUNT_TRANS(2);
8709                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8710                 COUNT_BYTES_TRANS(2);
8711
8712                 break;
8713         }
8714         case 0x09:      /*TRANS2_FSCTL*/
8715         case 0x0a:      /*TRANS2_IOCTL2*/
8716                 /* these calls have no parameter block in the request */
8717                 break;
8718         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
8719         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
8720                 /* XXX unknown structure*/
8721                 break;
8722         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
8723                 /* 4 reserved bytes */
8724                 CHECK_BYTE_COUNT_TRANS(4);
8725                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
8726                 COUNT_BYTES_TRANS(4);
8727
8728                 /* dir name */
8729                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
8730                         FALSE, FALSE, &bc);
8731                 CHECK_STRING_TRANS(fn);
8732                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
8733                         fn);
8734                 COUNT_BYTES_TRANS(fn_len);
8735
8736                 if (check_col(pinfo->cinfo, COL_INFO)) {
8737                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
8738                         fn);
8739                 }
8740
8741                 /* XXX optional FEAList, unknown what FEAList looks like*/
8742                 break;
8743         case 0x0e:      /*TRANS2_SESSION_SETUP*/
8744                 /* XXX unknown structure*/
8745                 break;
8746         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
8747                 /* referral level */
8748                 CHECK_BYTE_COUNT_TRANS(2);
8749                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
8750                 COUNT_BYTES_TRANS(2);
8751                 
8752                 /* file name */
8753                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8754                 CHECK_STRING_TRANS(fn);
8755                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8756                         fn);
8757                 COUNT_BYTES_TRANS(fn_len);
8758
8759                 if (check_col(pinfo->cinfo, COL_INFO)) {
8760                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
8761                         fn);
8762                 }
8763
8764                 break;
8765         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
8766                 /* file name */
8767                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
8768                 CHECK_STRING_TRANS(fn);
8769                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8770                         fn);
8771                 COUNT_BYTES_TRANS(fn_len);
8772
8773                 if (check_col(pinfo->cinfo, COL_INFO)) {
8774                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
8775                         fn);
8776                 }
8777
8778                 break;
8779         }
8780
8781         /* ooops there were data we didnt know how to process */
8782         if((offset-old_offset) < bc){
8783                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8784                     bc - (offset-old_offset), TRUE);
8785                 offset += bc - (offset-old_offset);
8786         }
8787
8788         return offset;
8789 }
8790
8791 /*
8792  * XXX - just use "dissect_connect_flags()" here?
8793  */
8794 static guint16
8795 dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8796 {
8797         guint16 mask;
8798         proto_item *item = NULL;
8799         proto_tree *tree = NULL;
8800
8801         mask = tvb_get_letohs(tvb, offset);
8802
8803         if(parent_tree){
8804                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8805                         "Flags: 0x%04x", mask);
8806                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
8807         }
8808
8809         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
8810                 tvb, offset, 2, mask);
8811         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
8812                 tvb, offset, 2, mask);
8813
8814         return mask;
8815 }
8816  
8817
8818 static int
8819 dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8820 {
8821         guint16 mask;
8822         proto_item *item = NULL;
8823         proto_tree *tree = NULL;
8824
8825         mask = tvb_get_letohs(tvb, offset);
8826
8827         if(parent_tree){
8828                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8829                         "Flags: 0x%04x", mask);
8830                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
8831         }
8832
8833         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
8834                 tvb, offset, 2, mask);
8835         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
8836                 tvb, offset, 2, mask);
8837
8838         offset += 2;
8839         return offset;
8840 }
8841
8842 static int
8843 dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
8844 {
8845         guint16 mask;
8846         proto_item *item = NULL;
8847         proto_tree *tree = NULL;
8848
8849         mask = tvb_get_letohs(tvb, offset);
8850
8851         if(parent_tree){
8852                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
8853                         "Flags: 0x%04x", mask);
8854                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
8855         }
8856
8857         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
8858                 tvb, offset, 2, mask);
8859
8860         offset += 2;
8861
8862         return offset;
8863 }
8864
8865
8866 /* dfs inconsistency data  (4.4.2)
8867 */
8868 static int
8869 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
8870     proto_tree *tree, int offset, guint16 *bcp)
8871 {
8872         int fn_len;
8873         const char *fn;
8874
8875         /*XXX shouldn this data hold version and size? unclear from doc*/
8876         /* referral version */
8877         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8878         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
8879         COUNT_BYTES_TRANS_SUBR(2);
8880
8881         /* referral size */
8882         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8883         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
8884         COUNT_BYTES_TRANS_SUBR(2);
8885
8886         /* referral server type */
8887         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8888         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
8889         COUNT_BYTES_TRANS_SUBR(2);
8890
8891         /* referral flags */
8892         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8893         offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
8894         *bcp -= 2;
8895
8896         /* node name */
8897         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
8898         CHECK_STRING_TRANS_SUBR(fn);
8899         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
8900                 fn);
8901         COUNT_BYTES_TRANS_SUBR(fn_len);
8902
8903         return offset;
8904 }
8905
8906 /* get dfs referral data  (4.4.1)
8907 */
8908 static int
8909 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
8910     proto_tree *tree, int offset, guint16 *bcp)
8911 {
8912         guint16 numref;
8913         guint16 refsize;
8914         guint16 pathoffset;
8915         guint16 altpathoffset;
8916         guint16 nodeoffset;
8917         int fn_len;
8918         int stroffset;
8919         int offsetoffset;
8920         guint16 save_bc;
8921         const char *fn;
8922         int unklen;
8923         int ucstring_end;
8924         int ucstring_len;
8925
8926         /* path consumed */
8927         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8928         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
8929         COUNT_BYTES_TRANS_SUBR(2);
8930
8931         /* num referrals */
8932         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8933         numref = tvb_get_letohs(tvb, offset);
8934         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
8935         COUNT_BYTES_TRANS_SUBR(2);
8936
8937         /* get dfs flags */
8938         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8939         offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
8940         *bcp -= 2;
8941
8942         /* XXX - in at least one capture there appears to be 2 bytes
8943            of stuff after the Dfs flags, perhaps so that the header
8944            in front of the referral list is a multiple of 4 bytes long. */
8945         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8946         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
8947         COUNT_BYTES_TRANS_SUBR(2);
8948
8949         /* if there are any referrals */
8950         if(numref){
8951                 proto_item *ref_item = NULL;
8952                 proto_tree *ref_tree = NULL;
8953                 int old_offset=offset;
8954
8955                 if(tree){
8956                         ref_item = proto_tree_add_text(tree,
8957                                 tvb, offset, *bcp, "Referrals");
8958                         ref_tree = proto_item_add_subtree(ref_item,
8959                                 ett_smb_dfs_referrals);
8960                 }
8961                 ucstring_end = -1;
8962
8963                 while(numref--){
8964                         proto_item *ri = NULL;
8965                         proto_tree *rt = NULL;
8966                         int old_offset=offset;
8967                         guint16 version;
8968
8969                         if(tree){
8970                                 ri = proto_tree_add_text(ref_tree,
8971                                         tvb, offset, *bcp, "Referral");
8972                                 rt = proto_item_add_subtree(ri,
8973                                         ett_smb_dfs_referral);
8974                         }
8975                 
8976                         /* referral version */
8977                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8978                         version = tvb_get_letohs(tvb, offset);
8979                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
8980                                 tvb, offset, 2, version);
8981                         COUNT_BYTES_TRANS_SUBR(2);
8982
8983                         /* referral size */
8984                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8985                         refsize = tvb_get_letohs(tvb, offset);
8986                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
8987                         COUNT_BYTES_TRANS_SUBR(2);
8988
8989                         /* referral server type */
8990                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8991                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
8992                         COUNT_BYTES_TRANS_SUBR(2);
8993
8994                         /* referral flags */
8995                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8996                         offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
8997                         *bcp -= 2;
8998
8999                         switch(version){
9000
9001                         case 1:
9002                                 /* node name */
9003                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9004                                 CHECK_STRING_TRANS_SUBR(fn);
9005                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
9006                                         fn);
9007                                 COUNT_BYTES_TRANS_SUBR(fn_len);
9008                                 break;
9009
9010                         case 2:
9011                         case 3: /* XXX - like version 2, but not identical;
9012                                    seen in a capture, but the format isn't
9013                                    documented */
9014                                 /* proximity */
9015                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9016                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
9017                                 COUNT_BYTES_TRANS_SUBR(2);
9018
9019                                 /* ttl */
9020                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9021                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
9022                                 COUNT_BYTES_TRANS_SUBR(2);
9023
9024                                 /* path offset */
9025                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9026                                 pathoffset = tvb_get_letohs(tvb, offset);
9027                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
9028                                 COUNT_BYTES_TRANS_SUBR(2);
9029
9030                                 /* alt path offset */
9031                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9032                                 altpathoffset = tvb_get_letohs(tvb, offset);
9033                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
9034                                 COUNT_BYTES_TRANS_SUBR(2);
9035
9036                                 /* node offset */
9037                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
9038                                 nodeoffset = tvb_get_letohs(tvb, offset);
9039                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
9040                                 COUNT_BYTES_TRANS_SUBR(2);
9041
9042                                 /* path */
9043                                 if (pathoffset != 0) {
9044                                         stroffset = old_offset + pathoffset;
9045                                         offsetoffset = stroffset - offset;
9046                                         if (offsetoffset > 0 &&
9047                                             *bcp > offsetoffset) {
9048                                                 save_bc = *bcp;
9049                                                 *bcp -= offsetoffset;
9050                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9051                                                 CHECK_STRING_TRANS_SUBR(fn);
9052                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
9053                                                         fn);
9054                                                 stroffset += fn_len;
9055                                                 if (ucstring_end < stroffset)
9056                                                         ucstring_end = stroffset;
9057                                                 *bcp = save_bc;
9058                                         }
9059                                 }
9060                         
9061                                 /* alt path */
9062                                 if (altpathoffset != 0) {
9063                                         stroffset = old_offset + altpathoffset;
9064                                         offsetoffset = stroffset - offset;
9065                                         if (offsetoffset > 0 &&
9066                                             *bcp > offsetoffset) {
9067                                                 save_bc = *bcp;
9068                                                 *bcp -= offsetoffset;
9069                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9070                                                 CHECK_STRING_TRANS_SUBR(fn);
9071                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
9072                                                         fn);
9073                                                 stroffset += fn_len;
9074                                                 if (ucstring_end < stroffset)
9075                                                         ucstring_end = stroffset;
9076                                                 *bcp = save_bc;
9077                                         }
9078                                 }
9079                         
9080                                 /* node */
9081                                 if (nodeoffset != 0) {
9082                                         stroffset = old_offset + nodeoffset;
9083                                         offsetoffset = stroffset - offset;
9084                                         if (offsetoffset > 0 &&
9085                                             *bcp > offsetoffset) {
9086                                                 save_bc = *bcp;
9087                                                 *bcp -= offsetoffset;
9088                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
9089                                                 CHECK_STRING_TRANS_SUBR(fn);
9090                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
9091                                                         fn);
9092                                                 stroffset += fn_len;
9093                                                 if (ucstring_end < stroffset)
9094                                                         ucstring_end = stroffset;
9095                                                 *bcp = save_bc;
9096                                         }
9097                                 }
9098                                 break;
9099                         }
9100
9101                         /*
9102                          * Show anything beyond the length of the referral
9103                          * as unknown data.
9104                          */
9105                         unklen = (old_offset + refsize) - offset;
9106                         if (unklen < 0) {
9107                                 /*
9108                                  * XXX - the length is bogus.
9109                                  */
9110                                 unklen = 0;
9111                         }
9112                         if (unklen != 0) {
9113                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
9114                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
9115                                     offset, unklen, TRUE);
9116                                 COUNT_BYTES_TRANS_SUBR(unklen);
9117                         }
9118
9119                         proto_item_set_len(ri, offset-old_offset);
9120                 }
9121
9122                 /*
9123                  * Treat the offset past the end of the last Unicode
9124                  * string after the referrals (if any) as the last
9125                  * offset.
9126                  */
9127                 if (ucstring_end > offset) {
9128                         ucstring_len = ucstring_end - offset;
9129                         if (*bcp < ucstring_len)
9130                                 ucstring_len = *bcp;
9131                         offset += ucstring_len;
9132                         *bcp -= ucstring_len;
9133                 }
9134                 proto_item_set_len(ref_item, offset-old_offset);
9135         }
9136
9137         return offset;
9138 }
9139
9140
9141 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
9142    as described in 4.2.14.1
9143 */
9144 static int
9145 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9146     int offset, guint16 *bcp, gboolean *trunc)
9147 {
9148         /* create time */
9149         CHECK_BYTE_COUNT_SUBR(4);
9150         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9151                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
9152                 FALSE);
9153         *bcp -= 4;
9154
9155         /* access time */
9156         CHECK_BYTE_COUNT_SUBR(4);
9157         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9158                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
9159                 FALSE);
9160         *bcp -= 4;
9161
9162         /* last write time */
9163         CHECK_BYTE_COUNT_SUBR(4);
9164         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9165                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
9166                 FALSE);
9167         *bcp -= 4;
9168
9169         /* data size */
9170         CHECK_BYTE_COUNT_SUBR(4);
9171         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
9172         COUNT_BYTES_SUBR(4);
9173
9174         /* allocation size */
9175         CHECK_BYTE_COUNT_SUBR(4);
9176         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9177         COUNT_BYTES_SUBR(4);
9178
9179         /* File Attributes */
9180         CHECK_BYTE_COUNT_SUBR(2);
9181         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9182         *bcp -= 2;
9183
9184         /* ea size */
9185         CHECK_BYTE_COUNT_SUBR(4);
9186         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9187         COUNT_BYTES_SUBR(4);
9188
9189         *trunc = FALSE;
9190         return offset;
9191 }
9192
9193 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
9194    as described in 4.2.14.2
9195 */
9196 static int
9197 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9198     int offset, guint16 *bcp, gboolean *trunc)
9199 {
9200         /* list length */
9201         CHECK_BYTE_COUNT_SUBR(4);
9202         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
9203         COUNT_BYTES_SUBR(4);
9204
9205         *trunc = FALSE;
9206         return offset;
9207 }
9208
9209 /* this dissects the SMB_INFO_IS_NAME_VALID
9210    as described in 4.2.14.3
9211 */
9212 static int
9213 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9214     int offset, guint16 *bcp, gboolean *trunc)
9215 {
9216         int fn_len;
9217         const char *fn;
9218
9219         /* file name */
9220         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9221         CHECK_STRING_SUBR(fn);
9222         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9223                 fn);
9224         COUNT_BYTES_SUBR(fn_len);
9225
9226         *trunc = FALSE;
9227         return offset;
9228 }
9229
9230 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
9231    as described in 4.2.14.4
9232 */
9233 static int
9234 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9235     int offset, guint16 *bcp, gboolean *trunc)
9236 {
9237         /* create time */
9238         CHECK_BYTE_COUNT_SUBR(8);
9239         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9240                 hf_smb_create_time);
9241         *bcp -= 8;
9242         
9243         /* access time */
9244         CHECK_BYTE_COUNT_SUBR(8);
9245         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9246                 hf_smb_access_time);
9247         *bcp -= 8;
9248         
9249         /* last write time */
9250         CHECK_BYTE_COUNT_SUBR(8);
9251         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9252                 hf_smb_last_write_time);
9253         *bcp -= 8;
9254         
9255         /* last change time */
9256         CHECK_BYTE_COUNT_SUBR(8);
9257         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9258                 hf_smb_change_time);
9259         *bcp -= 8;
9260         
9261         /* File Attributes */
9262         CHECK_BYTE_COUNT_SUBR(2);
9263         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9264         *bcp -= 2;
9265
9266         *trunc = FALSE;
9267         return offset;
9268 }
9269
9270 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
9271    as described in 4.2.14.5
9272 */
9273 static int
9274 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9275     int offset, guint16 *bcp, gboolean *trunc)
9276 {
9277         /* allocation size */
9278         CHECK_BYTE_COUNT_SUBR(8);
9279         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9280         COUNT_BYTES_SUBR(8);
9281
9282         /* end of file */
9283         CHECK_BYTE_COUNT_SUBR(8);
9284         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9285         COUNT_BYTES_SUBR(8);
9286
9287         /* number of links */
9288         CHECK_BYTE_COUNT_SUBR(4);
9289         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
9290         COUNT_BYTES_SUBR(4);
9291
9292         /* delete pending */
9293         CHECK_BYTE_COUNT_SUBR(2);
9294         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
9295         COUNT_BYTES_SUBR(2);
9296
9297         /* is directory */
9298         CHECK_BYTE_COUNT_SUBR(1);
9299         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9300         COUNT_BYTES_SUBR(1);
9301
9302         *trunc = FALSE;
9303         return offset;
9304 }
9305
9306 /* this dissects the SMB_QUERY_FILE_EA_INFO
9307    as described in 4.2.14.6
9308 */
9309 static int
9310 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9311     int offset, guint16 *bcp, gboolean *trunc)
9312 {
9313         /* ea size */
9314         CHECK_BYTE_COUNT_SUBR(4);
9315         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9316         COUNT_BYTES_SUBR(4);
9317
9318         *trunc = FALSE;
9319         return offset;
9320 }
9321
9322 /* this dissects the SMB_QUERY_FILE_NAME_INFO
9323    as described in 4.2.14.7
9324    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
9325    as described in 4.2.14.9
9326 */
9327 static int
9328 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9329     int offset, guint16 *bcp, gboolean *trunc)
9330 {
9331         int fn_len;
9332         const char *fn;
9333
9334         /* file name len */
9335         CHECK_BYTE_COUNT_SUBR(4);
9336         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
9337         COUNT_BYTES_SUBR(4);
9338
9339         /* file name */
9340         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
9341         CHECK_STRING_SUBR(fn);
9342         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9343                 fn);
9344         COUNT_BYTES_SUBR(fn_len);
9345
9346         *trunc = FALSE;
9347         return offset;
9348 }
9349
9350 /* this dissects the SMB_QUERY_FILE_ALL_INFO
9351    as described in 4.2.14.8
9352 */
9353 static int
9354 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9355     int offset, guint16 *bcp, gboolean *trunc)
9356 {
9357
9358         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
9359         if (trunc)
9360                 return offset;
9361         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
9362         if (trunc)
9363                 return offset;
9364
9365         /* index number */
9366         CHECK_BYTE_COUNT_SUBR(8);
9367         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9368         COUNT_BYTES_SUBR(8);
9369
9370         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9371         if (trunc)
9372                 return offset;
9373
9374         /* access flags */
9375         CHECK_BYTE_COUNT_SUBR(4);
9376         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
9377         COUNT_BYTES_SUBR(4);
9378
9379         /* index number */
9380         CHECK_BYTE_COUNT_SUBR(8);
9381         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
9382         COUNT_BYTES_SUBR(8);
9383
9384         /* current offset */
9385         CHECK_BYTE_COUNT_SUBR(8);
9386         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
9387         COUNT_BYTES_SUBR(8);
9388
9389         /* mode */
9390         CHECK_BYTE_COUNT_SUBR(4);
9391         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
9392         *bcp -= 4;
9393
9394         /* alignment */
9395         CHECK_BYTE_COUNT_SUBR(4);
9396         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
9397         COUNT_BYTES_SUBR(4);
9398         
9399         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
9400
9401         return offset;
9402 }
9403
9404 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
9405    as described in 4.2.14.10
9406 */
9407 static int
9408 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9409     int offset, guint16 *bcp, gboolean *trunc)
9410 {
9411         proto_item *item;
9412         proto_tree *tree;
9413         int old_offset;
9414         guint32 neo;
9415         int fn_len;
9416         const char *fn;
9417         int padcnt;
9418
9419         for (;;) {
9420                 old_offset = offset;
9421
9422                 /* next entry offset */
9423                 CHECK_BYTE_COUNT_SUBR(4);
9424                 if(parent_tree){
9425                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
9426                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9427                 } else {
9428                         item = NULL;
9429                         tree = NULL;
9430                 }
9431
9432                 neo = tvb_get_letohl(tvb, offset);
9433                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9434                 COUNT_BYTES_SUBR(4);
9435         
9436                 /* stream name len */
9437                 CHECK_BYTE_COUNT_SUBR(4);
9438                 fn_len = tvb_get_letohl(tvb, offset);
9439                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
9440                 COUNT_BYTES_SUBR(4);
9441         
9442                 /* stream size */
9443                 CHECK_BYTE_COUNT_SUBR(8);
9444                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
9445                 COUNT_BYTES_SUBR(8);
9446
9447                 /* allocation size */
9448                 CHECK_BYTE_COUNT_SUBR(8);
9449                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9450                 COUNT_BYTES_SUBR(8);
9451
9452                 /* stream name */
9453                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9454                 CHECK_STRING_SUBR(fn);
9455                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
9456                         fn);
9457                 COUNT_BYTES_SUBR(fn_len);
9458  
9459                 proto_item_append_text(item, ": %s", fn);
9460                 proto_item_set_len(item, offset-old_offset);
9461
9462                 if (neo == 0)
9463                         break;  /* no more structures */
9464
9465                 /* skip to next structure */
9466                 padcnt = (old_offset + neo) - offset;
9467                 if (padcnt < 0) {
9468                         /*
9469                          * XXX - this is bogus; flag it?
9470                          */
9471                         padcnt = 0;
9472                 }
9473                 if (padcnt != 0) {
9474                         CHECK_BYTE_COUNT_SUBR(padcnt);
9475                         COUNT_BYTES_SUBR(padcnt);
9476                 }
9477         }
9478
9479         *trunc = FALSE;
9480         return offset;
9481 }
9482
9483 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
9484    as described in 4.2.14.11
9485 */
9486 static int
9487 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
9488     int offset, guint16 *bcp, gboolean *trunc)
9489 {
9490         /* compressed file size */
9491         CHECK_BYTE_COUNT_SUBR(8);
9492         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
9493         COUNT_BYTES_SUBR(8);
9494
9495         /* compression format */
9496         CHECK_BYTE_COUNT_SUBR(2);
9497         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
9498         COUNT_BYTES_SUBR(2);
9499         
9500         /* compression unit shift */
9501         CHECK_BYTE_COUNT_SUBR(1);
9502         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
9503         COUNT_BYTES_SUBR(1);
9504         
9505         /* compression chunk shift */
9506         CHECK_BYTE_COUNT_SUBR(1);
9507         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
9508         COUNT_BYTES_SUBR(1);
9509         
9510         /* compression cluster shift */
9511         CHECK_BYTE_COUNT_SUBR(1);
9512         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
9513         COUNT_BYTES_SUBR(1);
9514         
9515         /* 3 reserved bytes */
9516         CHECK_BYTE_COUNT_SUBR(3);
9517         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
9518         COUNT_BYTES_SUBR(3);
9519
9520         *trunc = FALSE;
9521         return offset;
9522 }
9523
9524
9525
9526 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
9527 static int
9528 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
9529     int offset, guint16 *bcp)
9530 {
9531         smb_info_t *si;
9532         gboolean trunc;
9533
9534         if(!*bcp){
9535                 return offset;
9536         }
9537         
9538         si = (smb_info_t *)pinfo->private_data;
9539         switch(si->info_level){
9540         case 1:         /*Info Standard*/
9541         case 2:         /*Info Query EA Size*/
9542                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
9543                     &trunc);
9544                 break;
9545         case 3:         /*Info Query EAs From List*/
9546         case 4:         /*Info Query All EAs*/
9547                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
9548                     &trunc);
9549                 break;
9550         case 6:         /*Info Is Name Valid*/
9551                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
9552                     &trunc);
9553                 break;
9554         case 0x0101:    /*Query File Basic Info*/
9555                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
9556                     &trunc);
9557                 break;
9558         case 0x0102:    /*Query File Standard Info*/
9559                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
9560                     &trunc);
9561                 break;
9562         case 0x0103:    /*Query File EA Info*/
9563                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
9564                     &trunc);
9565                 break;
9566         case 0x0104:    /*Query File Name Info*/
9567                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9568                     &trunc);
9569                 break;
9570         case 0x0107:    /*Query File All Info*/
9571                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
9572                     &trunc);
9573                 break;
9574         case 0x0108:    /*Query File Alt File Info*/
9575                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
9576                     &trunc);
9577                 break;
9578         case 0x0109:    /*Query File Stream Info*/
9579                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
9580                     &trunc);
9581                 break;
9582         case 0x010b:    /*Query File Compression Info*/
9583                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
9584                     &trunc);
9585                 break;
9586         case 0x0200:    /*Set File Unix Basic*/
9587                 /* XXX add this from the SNIA doc */
9588                 break;
9589         case 0x0201:    /*Set File Unix Link*/
9590                 /* XXX add this from the SNIA doc */
9591                 break;
9592         case 0x0202:    /*Set File Unix HardLink*/
9593                 /* XXX add this from the SNIA doc */
9594                 break;
9595         }
9596         
9597         return offset;
9598 }
9599
9600
9601 static int
9602 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
9603     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
9604 {
9605         proto_item *item = NULL;
9606         proto_tree *tree = NULL;
9607         smb_info_t *si;
9608
9609         si = (smb_info_t *)pinfo->private_data;
9610
9611         if(parent_tree){
9612                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
9613                                 "%s Data",
9614                                 val_to_str(subcmd, trans2_cmd_vals, 
9615                                                 "Unknown (0x%02x)"));
9616                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
9617         }
9618
9619         switch(subcmd){
9620         case 0x00:      /*TRANS2_OPEN2*/
9621                 /* XXX FAEList here?*/
9622                 break;
9623         case 0x01:      /*TRANS2_FIND_FIRST2*/
9624                 /* XXX FAEList here?*/
9625                 break;
9626         case 0x02:      /*TRANS2_FIND_NEXT2*/
9627                 /* no data field in this request */
9628                 break;
9629         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
9630                 /* no data field in this request */
9631                 break;
9632         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
9633                 /* no data field in this request */
9634                 break;
9635         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
9636                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
9637                 break;
9638         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
9639                 /* no data field in this request */
9640                 break;
9641         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
9642                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
9643                 break;
9644         case 0x09:      /*TRANS2_FSCTL*/
9645                 /*XXX dont know how to decode this yet */
9646                 break;
9647         case 0x0a:      /*TRANS2_IOCTL2*/
9648                 /*XXX dont know how to decode this yet */
9649                 break;
9650         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
9651                 /*XXX dont know how to decode this yet */
9652                 break;
9653         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
9654                 /*XXX dont know how to decode this yet */
9655                 break;
9656         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
9657                 /* no data block for this one */
9658                 break;
9659         case 0x0e:      /*TRANS2_SESSION_SETUP*/
9660                 /*XXX dont know how to decode this yet */
9661                 break;
9662         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
9663                 /* no data field in this request */
9664                 break;
9665         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
9666                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
9667                 break;
9668         }
9669
9670         /* ooops there were data we didnt know how to process */
9671         if(dc != 0){
9672                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
9673                 offset += dc;
9674         }
9675
9676         return offset;
9677 }
9678
9679
9680 static void
9681 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
9682     packet_info *pinfo, proto_tree *tree)
9683 {
9684         int i;
9685         int offset;
9686         guint length;
9687
9688         /*
9689          * Show the setup words.
9690          */
9691         if (s_tvb != NULL) {
9692                 length = tvb_reported_length(s_tvb);
9693                 for (i = 0, offset = 0; length >= 2;
9694                     i++, offset += 2, length -= 2) {
9695                         /*
9696                          * XXX - add a setup word filterable field?
9697                          */
9698                         proto_tree_add_text(tree, s_tvb, offset, 2,
9699                             "Setup Word %d: 0x%04x", i,
9700                             tvb_get_letohs(s_tvb, offset));
9701                 }
9702         }
9703
9704         /*
9705          * Show the parameters, if any.
9706          */
9707         if (p_tvb != NULL) {
9708                 length = tvb_reported_length(p_tvb);
9709                 if (length != 0) {
9710                         proto_tree_add_text(tree, p_tvb, 0, length,
9711                             "Parameters: %s",
9712                             tvb_bytes_to_str(p_tvb, 0, length));
9713                 }
9714         }
9715
9716         /*
9717          * Show the data, if any.
9718          */
9719         if (d_tvb != NULL) {
9720                 length = tvb_reported_length(d_tvb);
9721                 if (length != 0) {
9722                         proto_tree_add_text(tree, d_tvb, 0, length,
9723                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
9724                 }
9725         }
9726 }
9727
9728 /* This routine handles the following 4 calls
9729    Transaction  0x25
9730    Transaction Secondary 0x26
9731    Transaction2 0x32
9732    Transaction2 Secondary 0x33
9733 */
9734 static int
9735 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9736 {
9737         guint8 wc, sc=0;
9738         int so=offset;
9739         int sl=0;
9740         int spo=offset;
9741         int spc=0;
9742         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
9743         int subcmd = -1;
9744         guint32 to;
9745         int an_len;
9746         const char *an = NULL;
9747         smb_info_t *si;
9748         smb_transact2_info_t *t2i;
9749         smb_transact_info_t *tri;
9750         guint16 bc;
9751         int padcnt;
9752         gboolean dissected_trans;
9753
9754         si = (smb_info_t *)pinfo->private_data;
9755
9756         WORD_COUNT;
9757
9758         if(wc==8){
9759                 /*secondary client request*/
9760
9761                 /* total param count, only a 16bit integer here*/
9762                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
9763                 offset += 2;
9764         
9765                 /* total data count , only 16bit integer here*/
9766                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
9767                 offset += 2;
9768
9769                 /* param count */
9770                 pc = tvb_get_letohs(tvb, offset);
9771                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
9772                 offset += 2;
9773
9774                 /* param offset */
9775                 po = tvb_get_letohs(tvb, offset);
9776                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
9777                 offset += 2;
9778
9779                 /* param disp */
9780                 pd = tvb_get_letohs(tvb, offset);
9781                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
9782                 offset += 2;
9783         
9784                 /* data count */
9785                 dc = tvb_get_letohs(tvb, offset);
9786                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
9787                 offset += 2;
9788
9789                 /* data offset */
9790                 od = tvb_get_letohs(tvb, offset);
9791                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
9792                 offset += 2;
9793         
9794                 /* data disp */
9795                 dd = tvb_get_letohs(tvb, offset);
9796                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
9797                 offset += 2;
9798
9799                 if(si->cmd==SMB_COM_TRANSACTION2){
9800                         guint16 fid;
9801
9802                         /* fid */
9803                         fid = tvb_get_letohs(tvb, offset);
9804                         add_fid(tvb, pinfo, tree, offset, 2, fid);
9805
9806                         offset += 2;
9807                 }
9808
9809                 /* There are no setup words. */
9810                 so = offset;
9811                 sc = 0;
9812                 sl = 0;
9813         } else {
9814                 /* it is not a secondary request */
9815
9816                 /* total param count , only a 16 bit integer here*/
9817                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
9818                 offset += 2;
9819
9820                 /* total data count , only 16bit integer here*/
9821                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
9822                 offset += 2;
9823
9824                 /* max param count , only 16bit integer here*/
9825                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
9826                 offset += 2;
9827
9828                 /* max data count, only 16bit integer here*/
9829                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
9830                 offset += 2;
9831
9832                 /* max setup count, only 16bit integer here*/
9833                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
9834                 offset += 1;
9835
9836                 /* reserved byte */
9837                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9838                 offset += 1;
9839
9840                 /* transaction flags */
9841                 tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
9842                 offset += 2;
9843
9844                 /* timeout */
9845                 to = tvb_get_letohl(tvb, offset);
9846                 if (to == 0)
9847                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
9848                 else if (to == 0xffffffff)
9849                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
9850                 else
9851                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
9852                 offset += 4;
9853
9854                 /* 2 reserved bytes */
9855                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
9856                 offset += 2;
9857
9858                 /* param count */
9859                 pc = tvb_get_letohs(tvb, offset);
9860                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
9861                 offset += 2;
9862         
9863                 /* param offset */
9864                 po = tvb_get_letohs(tvb, offset);
9865                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
9866                 offset += 2;
9867
9868                 /* param displacement is zero here */
9869                 pd = 0;
9870
9871                 /* data count */
9872                 dc = tvb_get_letohs(tvb, offset);
9873                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
9874                 offset += 2;
9875
9876                 /* data offset */
9877                 od = tvb_get_letohs(tvb, offset);
9878                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
9879                 offset += 2;
9880
9881                 /* data displacement is zero here */
9882                 dd = 0;
9883
9884                 /* setup count */
9885                 sc = tvb_get_guint8(tvb, offset);
9886                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9887                 offset += 1;
9888
9889                 /* reserved byte */
9890                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9891                 offset += 1;
9892                 
9893                 /* this is where the setup bytes, if any start */       
9894                 so = offset;
9895                 sl = sc*2;
9896
9897                 /* if there were any setup bytes, decode them */
9898                 if(sc){
9899                         switch(si->cmd){
9900
9901                         case SMB_COM_TRANSACTION2:
9902                                 /* TRANSACTION2 only has one setup word and
9903                                    that is the subcommand code. */
9904                                 subcmd = tvb_get_letohs(tvb, offset);
9905                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
9906                                     tvb, offset, 2, subcmd);
9907                                 if (check_col(pinfo->cinfo, COL_INFO)) {
9908                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
9909                                             val_to_str(subcmd, trans2_cmd_vals, 
9910                                                 "Unknown (0x%02x)"));
9911                                 }
9912                                 if (!si->unidir) {
9913                                         if(!pinfo->fd->flags.visited){
9914                                                 /* 
9915                                                  * Allocate a new
9916                                                  * smb_transact2_info_t
9917                                                  * structure.
9918                                                  */
9919                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
9920                                                 t2i->subcmd = subcmd;
9921                                                 t2i->info_level = -1;
9922                                                 si->sip->extra_info = t2i;
9923                                         }
9924                                 }     
9925                                 break;
9926
9927                         case SMB_COM_TRANSACTION:
9928                                 /* TRANSACTION setup words processed below */
9929                                 break;
9930                         }
9931
9932                         offset += sl;
9933                 }
9934         }
9935
9936         BYTE_COUNT;
9937         
9938         if(wc!=8){
9939                 /* primary request */
9940                 /* name is NULL if transaction2 */
9941                 if(si->cmd == SMB_COM_TRANSACTION){
9942                         /* Transaction Name */
9943                         an = get_unicode_or_ascii_string(tvb, &offset,
9944                                 pinfo, &an_len, FALSE, FALSE, &bc);
9945                         if (an == NULL)
9946                                 goto endofcommand;
9947                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
9948                                 offset, an_len, an);
9949                         COUNT_BYTES(an_len);
9950                 }
9951         }
9952
9953         /*
9954          * The pipe or mailslot arguments for Transaction start with
9955          * the first setup word (or where the first setup word would
9956          * be if there were any setup words), and run to the current
9957          * offset (which could mean that there aren't any).
9958          */
9959         spo = so;
9960         spc = offset - spo;
9961
9962         /* parameters */
9963         if(po>offset){
9964                 /* We have some initial padding bytes.
9965                 */
9966                 padcnt = po-offset;
9967                 if (padcnt > bc)
9968                         padcnt = bc;
9969                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9970                 COUNT_BYTES(padcnt);
9971         }
9972         if(pc){
9973                 CHECK_BYTE_COUNT(pc);
9974                 switch(si->cmd) {
9975
9976                 case SMB_COM_TRANSACTION2:
9977                         /* TRANSACTION2 parameters*/
9978                         offset = dissect_transaction2_request_parameters(tvb,
9979                             pinfo, tree, offset, subcmd, pc);
9980                         bc -= pc;
9981                         break;
9982
9983                 case SMB_COM_TRANSACTION:
9984                         /* TRANSACTION parameters processed below */
9985                         COUNT_BYTES(pc);
9986                         break;
9987                 }
9988         }
9989
9990         /* data */
9991         if(od>offset){
9992                 /* We have some initial padding bytes.
9993                 */
9994                 padcnt = od-offset;
9995                 if (padcnt > bc)
9996                         padcnt = bc;
9997                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9998                 COUNT_BYTES(padcnt);
9999         }
10000         if(dc){
10001                 CHECK_BYTE_COUNT(dc);
10002                 switch(si->cmd){
10003
10004                 case SMB_COM_TRANSACTION2:
10005                         /* TRANSACTION2 data*/
10006                         offset = dissect_transaction2_request_data(tvb, pinfo,
10007                             tree, offset, subcmd, dc);
10008                         bc -= dc;
10009                         break;
10010
10011                 case SMB_COM_TRANSACTION:
10012                         /* TRANSACTION data processed below */
10013                         COUNT_BYTES(dc);
10014                         break;
10015                 }
10016         }
10017
10018         /*TRANSACTION request parameters */
10019         if(si->cmd==SMB_COM_TRANSACTION){
10020                 /*XXX replace this block with a function and use that one 
10021                      for both requests/responses*/
10022                 if(dd==0){
10023                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
10024                         tvbuff_t *sp_tvb, *pd_tvb;
10025
10026                         if(pc>0){
10027                                 if(pc>tvb_length_remaining(tvb, po)){
10028                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
10029                                 } else {
10030                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
10031                                 }
10032                         } else {
10033                                 p_tvb = NULL;
10034                         }
10035                         if(dc>0){
10036                                 if(dc>tvb_length_remaining(tvb, od)){
10037                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
10038                                 } else {
10039                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
10040                                 }
10041                         } else {
10042                                 d_tvb = NULL;
10043                         }
10044                         if(sl){
10045                                 if(sl>tvb_length_remaining(tvb, so)){
10046                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
10047                                 } else {
10048                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
10049                                 }
10050                         } else {
10051                                 s_tvb = NULL;
10052                         }
10053
10054                         if (!si->unidir) {
10055                                 if(!pinfo->fd->flags.visited){
10056                                         /* 
10057                                          * Allocate a new smb_transact_info_t
10058                                          * structure.
10059                                          */
10060                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
10061                                         tri->subcmd = -1;
10062                                         tri->trans_subcmd = -1;
10063                                         tri->function = -1;
10064                                         tri->fid = -1;
10065                                         tri->lanman_cmd = 0;
10066                                         tri->param_descrip = NULL;
10067                                         tri->data_descrip = NULL;
10068                                         tri->aux_data_descrip = NULL;
10069                                         tri->info_level = -1;
10070                                         si->sip->extra_info = tri;
10071                                 } else {
10072                                         /*
10073                                          * We already filled the structure
10074                                          * in; don't bother doing so again.
10075                                          */
10076                                         tri = NULL;
10077                                 }
10078                         } else {
10079                                 /*
10080                                  * This is a unidirectional message, for
10081                                  * which there will be no reply; don't
10082                                  * bother allocating an "smb_transact_info_t"
10083                                  * structure for it.
10084                                  */
10085                                 tri = NULL;
10086                         }
10087                         dissected_trans = FALSE;
10088                         if(strncmp("\\PIPE\\", an, 6) == 0){
10089                                 if (tri != NULL)
10090                                         tri->subcmd=TRANSACTION_PIPE;
10091
10092                                 /*
10093                                  * A tvbuff containing the setup words and
10094                                  * the pipe path.
10095                                  */
10096                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10097
10098                                 /*
10099                                  * A tvbuff containing the parameters and the
10100                                  * data.
10101                                  */
10102                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
10103
10104                                 dissected_trans = dissect_pipe_smb(sp_tvb,
10105                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
10106                                     top_tree);
10107                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
10108                                 if (tri != NULL)
10109                                         tri->subcmd=TRANSACTION_MAILSLOT;
10110
10111                                 /*
10112                                  * A tvbuff containing the setup words and
10113                                  * the mailslot path.
10114                                  */
10115                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
10116                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
10117                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
10118                         }
10119                         if (!dissected_trans) {
10120                                 dissect_trans_data(s_tvb, p_tvb, d_tvb,
10121                                     pinfo, tree);
10122                         }
10123                 } else {
10124                         if(check_col(pinfo->cinfo, COL_INFO)){
10125                                 col_append_str(pinfo->cinfo, COL_INFO,
10126                                         "[transact continuation]");
10127                         }
10128                 }
10129         }
10130
10131         END_OF_SMB
10132
10133         return offset;
10134 }
10135
10136  
10137
10138 static int
10139 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10140     int offset, guint16 *bcp, gboolean *trunc)
10141 {
10142         int fn_len;
10143         const char *fn;
10144         int old_offset = offset;
10145         proto_item *item = NULL;
10146         proto_tree *tree = NULL;
10147         smb_info_t *si;
10148
10149         si = (smb_info_t *)pinfo->private_data;
10150
10151         if(parent_tree){
10152                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10153                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10154                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10155         }
10156
10157         /* create time */
10158         CHECK_BYTE_COUNT_SUBR(4);
10159         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10160                 hf_smb_create_time,
10161                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10162         *bcp -= 4;
10163
10164         /* access time */
10165         CHECK_BYTE_COUNT_SUBR(4);
10166         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10167                 hf_smb_access_time,
10168                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10169         *bcp -= 4;
10170
10171         /* last write time */
10172         CHECK_BYTE_COUNT_SUBR(4);
10173         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10174                 hf_smb_last_write_time,
10175                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10176         *bcp -= 4;
10177
10178         /* data size */
10179         CHECK_BYTE_COUNT_SUBR(4);
10180         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10181         COUNT_BYTES_SUBR(4);
10182
10183         /* allocation size */
10184         CHECK_BYTE_COUNT_SUBR(4);
10185         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10186         COUNT_BYTES_SUBR(4);
10187
10188         /* File Attributes */
10189         CHECK_BYTE_COUNT_SUBR(2);
10190         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10191         *bcp -= 2;
10192
10193         /* file name len */
10194         CHECK_BYTE_COUNT_SUBR(1);
10195         fn_len = tvb_get_guint8(tvb, offset);
10196         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10197         COUNT_BYTES_SUBR(1);
10198
10199         /* file name */
10200         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10201         CHECK_STRING_SUBR(fn);
10202         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10203                 fn);
10204         COUNT_BYTES_SUBR(fn_len);
10205
10206         if (check_col(pinfo->cinfo, COL_INFO)) {
10207                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10208                 fn);
10209         }
10210  
10211         proto_item_append_text(item, " File: %s", fn);
10212         proto_item_set_len(item, offset-old_offset);
10213
10214         *trunc = FALSE;
10215         return offset;
10216 }
10217
10218 static int
10219 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10220     int offset, guint16 *bcp, gboolean *trunc)
10221 {
10222         int fn_len;
10223         const char *fn;
10224         int old_offset = offset;
10225         proto_item *item = NULL;
10226         proto_tree *tree = NULL;
10227         smb_info_t *si;
10228
10229         si = (smb_info_t *)pinfo->private_data;
10230
10231         if(parent_tree){
10232                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10233                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10234                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10235         }
10236  
10237         /* create time */
10238         CHECK_BYTE_COUNT_SUBR(4);
10239         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10240                 hf_smb_create_time,
10241                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
10242         *bcp -= 4;
10243
10244         /* access time */
10245         CHECK_BYTE_COUNT_SUBR(4);
10246         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10247                 hf_smb_access_time,
10248                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
10249         *bcp -= 4;
10250
10251         /* last write time */
10252         CHECK_BYTE_COUNT_SUBR(4);
10253         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10254                 hf_smb_last_write_time,
10255                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
10256         *bcp -= 4;
10257
10258         /* data size */
10259         CHECK_BYTE_COUNT_SUBR(4);
10260         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10261         COUNT_BYTES_SUBR(4);
10262
10263         /* allocation size */
10264         CHECK_BYTE_COUNT_SUBR(4);
10265         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10266         COUNT_BYTES_SUBR(4);
10267
10268         /* File Attributes */
10269         CHECK_BYTE_COUNT_SUBR(2);
10270         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10271         *bcp -= 2;
10272
10273         /* ea size */
10274         CHECK_BYTE_COUNT_SUBR(4);
10275         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10276         COUNT_BYTES_SUBR(4);
10277
10278         /* file name len */
10279         CHECK_BYTE_COUNT_SUBR(1);
10280         fn_len = tvb_get_guint8(tvb, offset);
10281         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
10282         COUNT_BYTES_SUBR(1);
10283
10284         /* file name */
10285         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10286         CHECK_STRING_SUBR(fn);
10287         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10288                 fn);
10289         COUNT_BYTES_SUBR(fn_len);
10290
10291         if (check_col(pinfo->cinfo, COL_INFO)) {
10292                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10293                 fn);
10294         }
10295
10296         proto_item_append_text(item, " File: %s", fn);
10297         proto_item_set_len(item, offset-old_offset);
10298
10299         *trunc = FALSE;
10300         return offset;
10301 }
10302
10303 static int
10304 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10305     int offset, guint16 *bcp, gboolean *trunc)
10306 {
10307         int fn_len;
10308         const char *fn;
10309         int old_offset = offset;
10310         proto_item *item = NULL;
10311         proto_tree *tree = NULL;
10312         smb_info_t *si;
10313         guint32 neo;
10314         int padcnt;
10315
10316         si = (smb_info_t *)pinfo->private_data;
10317
10318         if(parent_tree){
10319                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10320                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10321                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10322         }
10323
10324         /* next entry offset */
10325         CHECK_BYTE_COUNT_SUBR(4);
10326         neo = tvb_get_letohl(tvb, offset);
10327         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10328         COUNT_BYTES_SUBR(4);
10329         
10330         /* file index */
10331         CHECK_BYTE_COUNT_SUBR(4);
10332         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10333         COUNT_BYTES_SUBR(4);
10334
10335         /* create time */
10336         CHECK_BYTE_COUNT_SUBR(8);
10337         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10338                 hf_smb_create_time);
10339         *bcp -= 8;
10340         
10341         /* access time */
10342         CHECK_BYTE_COUNT_SUBR(8);
10343         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10344                 hf_smb_access_time);
10345         *bcp -= 8;
10346         
10347         /* last write time */
10348         CHECK_BYTE_COUNT_SUBR(8);
10349         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10350                 hf_smb_last_write_time);
10351         *bcp -= 8;
10352         
10353         /* last change time */
10354         CHECK_BYTE_COUNT_SUBR(8);
10355         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10356                 hf_smb_change_time);
10357         *bcp -= 8;
10358         
10359         /* end of file */
10360         CHECK_BYTE_COUNT_SUBR(8);
10361         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10362         COUNT_BYTES_SUBR(8);
10363
10364         /* allocation size */
10365         CHECK_BYTE_COUNT_SUBR(8);
10366         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10367         COUNT_BYTES_SUBR(8);
10368
10369         /* Extended File Attributes */
10370         CHECK_BYTE_COUNT_SUBR(4);
10371         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10372         *bcp -= 4;
10373
10374         /* file name len */
10375         CHECK_BYTE_COUNT_SUBR(4);
10376         fn_len = tvb_get_letohl(tvb, offset);
10377         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10378         COUNT_BYTES_SUBR(4);
10379
10380         /* file name */
10381         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10382         CHECK_STRING_SUBR(fn);
10383         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10384                 fn);
10385         COUNT_BYTES_SUBR(fn_len);
10386
10387         if (check_col(pinfo->cinfo, COL_INFO)) {
10388                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10389                 fn);
10390         }
10391
10392         /* skip to next structure */
10393         if(neo){
10394                 padcnt = (old_offset + neo) - offset;
10395                 if (padcnt < 0) {
10396                         /*
10397                          * XXX - this is bogus; flag it?
10398                          */
10399                         padcnt = 0;
10400                 }
10401                 if (padcnt != 0) {
10402                         CHECK_BYTE_COUNT_SUBR(padcnt);
10403                         COUNT_BYTES_SUBR(padcnt);
10404                 }
10405         }
10406
10407         proto_item_append_text(item, " File: %s", fn);
10408         proto_item_set_len(item, offset-old_offset);
10409
10410         *trunc = FALSE;
10411         return offset;
10412 }
10413
10414 static int
10415 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10416     int offset, guint16 *bcp, gboolean *trunc)
10417 {
10418         int fn_len;
10419         const char *fn;
10420         int old_offset = offset;
10421         proto_item *item = NULL;
10422         proto_tree *tree = NULL;
10423         smb_info_t *si;
10424         guint32 neo;
10425         int padcnt;
10426
10427         si = (smb_info_t *)pinfo->private_data;
10428
10429         if(parent_tree){
10430                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10431                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10432                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10433         }
10434
10435         /* next entry offset */
10436         CHECK_BYTE_COUNT_SUBR(4);
10437         neo = tvb_get_letohl(tvb, offset);
10438         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10439         COUNT_BYTES_SUBR(4);
10440         
10441         /* file index */
10442         CHECK_BYTE_COUNT_SUBR(4);
10443         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10444         COUNT_BYTES_SUBR(4);
10445
10446         /* create time */
10447         CHECK_BYTE_COUNT_SUBR(8);
10448         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10449                 hf_smb_create_time);
10450         *bcp -= 8;
10451         
10452         /* access time */
10453         CHECK_BYTE_COUNT_SUBR(8);
10454         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10455                 hf_smb_access_time);
10456         *bcp -= 8;
10457         
10458         /* last write time */
10459         CHECK_BYTE_COUNT_SUBR(8);
10460         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10461                 hf_smb_last_write_time);
10462         *bcp -= 8;
10463         
10464         /* last change time */
10465         CHECK_BYTE_COUNT_SUBR(8);
10466         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10467                 hf_smb_change_time);
10468         *bcp -= 8;
10469         
10470         /* end of file */
10471         CHECK_BYTE_COUNT_SUBR(8);
10472         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10473         COUNT_BYTES_SUBR(8);
10474
10475         /* allocation size */
10476         CHECK_BYTE_COUNT_SUBR(8);
10477         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10478         COUNT_BYTES_SUBR(8);
10479
10480         /* Extended File Attributes */
10481         CHECK_BYTE_COUNT_SUBR(4);
10482         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10483         *bcp -= 4;
10484
10485         /* file name len */
10486         CHECK_BYTE_COUNT_SUBR(4);
10487         fn_len = tvb_get_letohl(tvb, offset);
10488         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10489         COUNT_BYTES_SUBR(4);
10490
10491         /* ea size */
10492         CHECK_BYTE_COUNT_SUBR(4);
10493         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10494         COUNT_BYTES_SUBR(4);
10495
10496         /* file name */
10497         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10498         CHECK_STRING_SUBR(fn);
10499         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10500                 fn);
10501         COUNT_BYTES_SUBR(fn_len);
10502
10503         if (check_col(pinfo->cinfo, COL_INFO)) {
10504                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10505                 fn);
10506         }
10507
10508         /* skip to next structure */
10509         if(neo){
10510                 padcnt = (old_offset + neo) - offset;
10511                 if (padcnt < 0) {
10512                         /*
10513                          * XXX - this is bogus; flag it?
10514                          */
10515                         padcnt = 0;
10516                 }
10517                 if (padcnt != 0) {
10518                         CHECK_BYTE_COUNT_SUBR(padcnt);
10519                         COUNT_BYTES_SUBR(padcnt);
10520                 }
10521         }
10522
10523         proto_item_append_text(item, " File: %s", fn);
10524         proto_item_set_len(item, offset-old_offset);
10525
10526         *trunc = FALSE;
10527         return offset;
10528 }
10529
10530 static int
10531 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10532     int offset, guint16 *bcp, gboolean *trunc)
10533 {
10534         int fn_len, sfn_len;
10535         const char *fn, *sfn;
10536         int old_offset = offset;
10537         proto_item *item = NULL;
10538         proto_tree *tree = NULL;
10539         smb_info_t *si;
10540         guint32 neo;
10541         int padcnt;
10542
10543         si = (smb_info_t *)pinfo->private_data;
10544
10545         if(parent_tree){
10546                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10547                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10548                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10549         }
10550
10551         /* next entry offset */
10552         CHECK_BYTE_COUNT_SUBR(4);
10553         neo = tvb_get_letohl(tvb, offset);
10554         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10555         COUNT_BYTES_SUBR(4);
10556         
10557         /* file index */
10558         CHECK_BYTE_COUNT_SUBR(4);
10559         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10560         COUNT_BYTES_SUBR(4);
10561
10562         /* create time */
10563         CHECK_BYTE_COUNT_SUBR(8);
10564         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10565                 hf_smb_create_time);
10566         *bcp -= 8;
10567         
10568         /* access time */
10569         CHECK_BYTE_COUNT_SUBR(8);
10570         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10571                 hf_smb_access_time);
10572         *bcp -= 8;
10573         
10574         /* last write time */
10575         CHECK_BYTE_COUNT_SUBR(8);
10576         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10577                 hf_smb_last_write_time);
10578         *bcp -= 8;
10579         
10580         /* last change time */
10581         CHECK_BYTE_COUNT_SUBR(8);
10582         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10583                 hf_smb_change_time);
10584         *bcp -= 8;
10585         
10586         /* end of file */
10587         CHECK_BYTE_COUNT_SUBR(8);
10588         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
10589         COUNT_BYTES_SUBR(8);
10590
10591         /* allocation size */
10592         CHECK_BYTE_COUNT_SUBR(8);
10593         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10594         COUNT_BYTES_SUBR(8);
10595
10596         /* Extended File Attributes */
10597         CHECK_BYTE_COUNT_SUBR(4);
10598         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
10599         *bcp -= 4;
10600
10601         /* file name len */
10602         CHECK_BYTE_COUNT_SUBR(4);
10603         fn_len = tvb_get_letohl(tvb, offset);
10604         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10605         COUNT_BYTES_SUBR(4);
10606
10607         /* ea size */
10608         CHECK_BYTE_COUNT_SUBR(4);
10609         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
10610         COUNT_BYTES_SUBR(4);
10611
10612         /* short file name len */
10613         CHECK_BYTE_COUNT_SUBR(1);
10614         sfn_len = tvb_get_guint8(tvb, offset);
10615         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
10616         COUNT_BYTES_SUBR(1);
10617
10618         /* reserved byte */
10619         CHECK_BYTE_COUNT_SUBR(1);
10620         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10621         COUNT_BYTES_SUBR(1);
10622  
10623         /* short file name */
10624         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
10625         CHECK_STRING_SUBR(sfn);
10626         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
10627                 sfn);
10628         COUNT_BYTES_SUBR(24);
10629
10630         /* file name */
10631         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10632         CHECK_STRING_SUBR(fn);
10633         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10634                 fn);
10635         COUNT_BYTES_SUBR(fn_len);
10636
10637         if (check_col(pinfo->cinfo, COL_INFO)) {
10638                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10639                 fn);
10640         }
10641
10642         /* skip to next structure */
10643         if(neo){
10644                 padcnt = (old_offset + neo) - offset;
10645                 if (padcnt < 0) {
10646                         /*
10647                          * XXX - this is bogus; flag it?
10648                          */
10649                         padcnt = 0;
10650                 }
10651                 if (padcnt != 0) {
10652                         CHECK_BYTE_COUNT_SUBR(padcnt);
10653                         COUNT_BYTES_SUBR(padcnt);
10654                 }
10655         }
10656
10657         proto_item_append_text(item, " File: %s", fn);
10658         proto_item_set_len(item, offset-old_offset);
10659
10660         *trunc = FALSE;
10661         return offset;
10662 }
10663
10664 static int
10665 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10666     int offset, guint16 *bcp, gboolean *trunc)
10667 {
10668         int fn_len;
10669         const char *fn;
10670         int old_offset = offset;
10671         proto_item *item = NULL;
10672         proto_tree *tree = NULL;
10673         smb_info_t *si;
10674         guint32 neo;
10675         int padcnt;
10676
10677         si = (smb_info_t *)pinfo->private_data;
10678
10679         if(parent_tree){
10680                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
10681                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
10682                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
10683         }
10684  
10685         /* next entry offset */
10686         CHECK_BYTE_COUNT_SUBR(4);
10687         neo = tvb_get_letohl(tvb, offset);
10688         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
10689         COUNT_BYTES_SUBR(4);
10690         
10691         /* file index */
10692         CHECK_BYTE_COUNT_SUBR(4);
10693         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
10694         COUNT_BYTES_SUBR(4);
10695
10696         /* file name len */
10697         CHECK_BYTE_COUNT_SUBR(4);
10698         fn_len = tvb_get_letohl(tvb, offset);
10699         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
10700         COUNT_BYTES_SUBR(4);
10701
10702         /* file name */
10703         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10704         CHECK_STRING_SUBR(fn);
10705         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10706                 fn);
10707         COUNT_BYTES_SUBR(fn_len);
10708
10709         if (check_col(pinfo->cinfo, COL_INFO)) {
10710                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
10711                 fn);
10712         }
10713
10714         /* skip to next structure */
10715         if(neo){
10716                 padcnt = (old_offset + neo) - offset;
10717                 if (padcnt < 0) {
10718                         /*
10719                          * XXX - this is bogus; flag it?
10720                          */
10721                         padcnt = 0;
10722                 }
10723                 if (padcnt != 0) {
10724                         CHECK_BYTE_COUNT_SUBR(padcnt);
10725                         COUNT_BYTES_SUBR(padcnt);
10726                 }
10727         }
10728
10729         proto_item_append_text(item, " File: %s", fn);
10730         proto_item_set_len(item, offset-old_offset);
10731
10732         *trunc = FALSE;
10733         return offset;
10734 }
10735  
10736 static int
10737 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
10738     int offset, guint16 *bcp, gboolean *trunc)
10739 {
10740 /*XXX im lazy. i havnt implemented this */
10741         offset += *bcp;
10742         *bcp = 0;
10743         *trunc = FALSE;
10744         return offset;
10745 }
10746
10747 /*dissect the data block for TRANS2_FIND_FIRST2*/
10748 static int
10749 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
10750     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
10751 {
10752         smb_info_t *si;
10753
10754         if(!*bcp){
10755                 return offset;
10756         }
10757         
10758         si = (smb_info_t *)pinfo->private_data;
10759         switch(si->info_level){
10760         case 1:         /*Info Standard*/
10761                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
10762                     trunc);
10763                 break;
10764         case 2:         /*Info Query EA Size*/
10765                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
10766                     trunc);
10767                 break;
10768         case 3:         /*Info Query EAs From List same as 
10769                                 InfoQueryEASize*/
10770                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
10771                     trunc);
10772                 break;
10773         case 0x0101:    /*Find File Directory Info*/
10774                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
10775                     trunc);
10776                 break;
10777         case 0x0102:    /*Find File Full Directory Info*/
10778                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
10779                     trunc);
10780                 break;
10781         case 0x0103:    /*Find File Names Info*/
10782                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
10783                     trunc);
10784                 break;
10785         case 0x0104:    /*Find File Both Directory Info*/
10786                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
10787                     trunc);
10788                 break;
10789         case 0x0202:    /*Find File UNIX*/
10790                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
10791                     trunc);
10792                 break;
10793         default:        /* unknown info level */
10794                 *trunc = FALSE;
10795                 break;
10796         }
10797         return offset;
10798 }
10799
10800
10801 static int
10802 dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10803 {
10804         guint32 mask;
10805         proto_item *item = NULL;
10806         proto_tree *tree = NULL;
10807
10808         mask = tvb_get_letohl(tvb, offset);
10809
10810         if(parent_tree){
10811                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
10812                         "FS Attributes: 0x%08x", mask);
10813                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
10814         }
10815
10816         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
10817                 tvb, offset, 4, mask);
10818         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
10819                 tvb, offset, 4, mask);
10820         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
10821                 tvb, offset, 4, mask);
10822         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
10823                 tvb, offset, 4, mask);
10824         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
10825                 tvb, offset, 4, mask);
10826         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
10827                 tvb, offset, 4, mask);
10828         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
10829                 tvb, offset, 4, mask);
10830
10831         offset += 4;
10832         return offset;
10833 }
10834  
10835
10836 static int
10837 dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10838 {
10839         guint32 mask;
10840         proto_item *item = NULL;
10841         proto_tree *tree = NULL;
10842
10843         mask = tvb_get_letohl(tvb, offset);
10844
10845         if(parent_tree){
10846                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
10847                         "Device Characteristics: 0x%08x", mask);
10848                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
10849         }
10850
10851         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
10852                 tvb, offset, 4, mask);
10853         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
10854                 tvb, offset, 4, mask);
10855         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
10856                 tvb, offset, 4, mask);
10857         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
10858                 tvb, offset, 4, mask);
10859         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
10860                 tvb, offset, 4, mask);
10861         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
10862                 tvb, offset, 4, mask);
10863         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
10864                 tvb, offset, 4, mask);
10865
10866         offset += 4;
10867         return offset;
10868 }
10869
10870 /* dissect 4 bytes specifying the number of 256 byte blocks for a quota limit */
10871 static void
10872 dissect_quota_32bit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
10873                 char *str)
10874
10875         guint32 quota;
10876         int i;
10877         char *prefix = "KMGTPE";
10878
10879         quota = tvb_get_letohl(tvb, offset);
10880
10881         /* divide by four to get number of KB*/
10882         quota >>= 2;
10883
10884         /* divide by 1024 until the result is less than 1024 */
10885         i=0;
10886         while( quota>1023 ){
10887                 i++;
10888                 quota >>= 10;
10889         }
10890
10891         proto_tree_add_text(tree, tvb, offset, 4,
10892                         "%s is %d%cB",str, quota, prefix[i]);
10893 }
10894
10895
10896 static const true_false_string tfs_quota_flags_deny_disk = {
10897         "DENY DISK SPACE for users exceeding quota limit",
10898         "Do NOT deny disk space for users exceeding quota limit"
10899 };
10900 static const true_false_string tfs_quota_flags_log_limit = {
10901         "LOG EVENT when a user exceeds their QUOTA LIMIT",
10902         "Do NOT log event when a user exceeds their quota limit"
10903 };
10904 static const true_false_string tfs_quota_flags_log_warning = {
10905         "LOG EVENT when a user exceeds their WARNING LEVEL",
10906         "Do NOT log event when a user exceeds their warning level"
10907 };
10908 static void
10909 dissect_quota_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10910 {
10911         guint8 mask;
10912         proto_item *item = NULL;
10913         proto_tree *tree = NULL;
10914
10915         mask = tvb_get_guint8(tvb, offset);
10916
10917         if(parent_tree){
10918                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
10919                         "Quota Flags: 0x%02x", mask);
10920                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
10921         }
10922
10923         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
10924                 tvb, offset, 1, mask);
10925         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
10926                 tvb, offset, 1, mask);
10927         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
10928                 tvb, offset, 1, mask);
10929 }
10930
10931 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
10932 static int
10933 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10934     int offset, guint16 *bcp)
10935 {
10936         smb_info_t *si;
10937         int fn_len, vll, fnl;
10938         const char *fn;
10939
10940         if(!*bcp){
10941                 return offset;
10942         }
10943         
10944         si = (smb_info_t *)pinfo->private_data;
10945         switch(si->info_level){
10946         case 1:         /* SMB_INFO_ALLOCATION */
10947                 /* filesystem id */
10948                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10949                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
10950                 COUNT_BYTES_TRANS_SUBR(4);
10951
10952                 /* sectors per unit */
10953                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10954                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
10955                 COUNT_BYTES_TRANS_SUBR(4);
10956
10957                 /* units */
10958                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10959                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
10960                 COUNT_BYTES_TRANS_SUBR(4);
10961
10962                 /* avail units */
10963                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10964                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
10965                 COUNT_BYTES_TRANS_SUBR(4);
10966
10967                 /* bytes per sector, only 16bit integer here */
10968                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10969                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10970                 COUNT_BYTES_TRANS_SUBR(2);
10971
10972                 break;
10973         case 2:         /* SMB_INFO_VOLUME */
10974                 /* volume serial number */
10975                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10976                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
10977                 COUNT_BYTES_TRANS_SUBR(4);
10978
10979                 /* volume label length, only one byte here */
10980                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
10981                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10982                 COUNT_BYTES_TRANS_SUBR(1);
10983
10984                 /* label */
10985                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
10986                 CHECK_STRING_TRANS_SUBR(fn);
10987                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
10988                         fn);
10989                 COUNT_BYTES_TRANS_SUBR(fn_len);
10990
10991                 break;
10992         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
10993                 /* create time */
10994                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
10995                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10996                         hf_smb_create_time);
10997                 *bcp -= 8;
10998         
10999                 /* volume serial number */
11000                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11001                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
11002                 COUNT_BYTES_TRANS_SUBR(4);
11003
11004                 /* volume label length */
11005                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11006                 vll = tvb_get_letohl(tvb, offset);
11007                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
11008                 COUNT_BYTES_TRANS_SUBR(4);
11009
11010                 /* 2 reserved bytes */
11011                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
11012                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11013                 COUNT_BYTES_TRANS_SUBR(2);
11014
11015                 /* label */
11016                 fn_len = vll;
11017                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11018                 CHECK_STRING_TRANS_SUBR(fn);
11019                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
11020                         fn);
11021                 COUNT_BYTES_TRANS_SUBR(fn_len);
11022
11023                 break;
11024         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
11025                 /* allocation size */
11026                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11027                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11028                 COUNT_BYTES_TRANS_SUBR(8);
11029
11030                 /* free allocation units */
11031                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
11032                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
11033                 COUNT_BYTES_TRANS_SUBR(8);
11034
11035                 /* sectors per unit */
11036                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11037                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
11038                 COUNT_BYTES_TRANS_SUBR(4);
11039
11040                 /* bytes per sector */
11041                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11042                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
11043                 COUNT_BYTES_TRANS_SUBR(4);
11044
11045                 break;
11046         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
11047                 /* device type */
11048                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11049                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
11050                 COUNT_BYTES_TRANS_SUBR(4);
11051  
11052                 /* device characteristics */
11053                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11054                 offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
11055                 *bcp -= 4;
11056         
11057                 break;
11058         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
11059                 /* FS attributes */
11060                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11061                 offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
11062                 *bcp -= 4;
11063         
11064                 /* max name len */
11065                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11066                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
11067                 COUNT_BYTES_TRANS_SUBR(4);
11068
11069                 /* fs name length */
11070                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11071                 fnl = tvb_get_letohl(tvb, offset);
11072                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
11073                 COUNT_BYTES_TRANS_SUBR(4);
11074
11075                 /* label */
11076                 fn_len = fnl;
11077                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
11078                 CHECK_STRING_TRANS_SUBR(fn);
11079                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
11080                         fn);
11081                 COUNT_BYTES_TRANS_SUBR(fn_len);
11082
11083                 break;
11084         case 1006:      /* QUERY_FS_QUOTA_INFO */
11085                 /* first 25 bytes are unknown */
11086                 CHECK_BYTE_COUNT_TRANS_SUBR(25);
11087                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
11088                             offset, 25, TRUE);
11089                 COUNT_BYTES_TRANS_SUBR(25);
11090
11091                 /* This really calls for a separate routing, but this will do for testing */
11092                 /* number of 256byte blocks for WARNING LEVEL, 32bit integer */
11093                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11094                 dissect_quota_32bit(tvb, pinfo, tree, offset, "Default (Soft) Quota Warning Level");
11095                 COUNT_BYTES_TRANS_SUBR(4);
11096
11097                 /* these 4 bytes are unknown */
11098                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11099                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
11100                             offset, 4, TRUE);
11101                 COUNT_BYTES_TRANS_SUBR(4);
11102
11103                 /* number of 256byte blocks for QUOTA LIMIT, 64bit integer */
11104                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
11105                 dissect_quota_32bit(tvb, pinfo, tree, offset, "Default (Hard) Quota Limit");
11106                 COUNT_BYTES_TRANS_SUBR(4);
11107
11108                 /* these 3 bytes are unknown */
11109                 CHECK_BYTE_COUNT_TRANS_SUBR(3);
11110                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
11111                             offset, 3, TRUE);
11112                 COUNT_BYTES_TRANS_SUBR(3);
11113
11114                 /* one byte of quota flags */
11115                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
11116                 dissect_quota_flags(tvb, pinfo, tree, offset);
11117                 COUNT_BYTES_TRANS_SUBR(1);
11118
11119                 /* these 7 bytes are unknown */
11120                 CHECK_BYTE_COUNT_TRANS_SUBR(7);
11121                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
11122                             offset, 7, TRUE);
11123                 COUNT_BYTES_TRANS_SUBR(7);
11124         }
11125  
11126         return offset;
11127 }
11128  
11129 static int
11130 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
11131     proto_tree *parent_tree)
11132 {
11133         proto_item *item = NULL;
11134         proto_tree *tree = NULL;
11135         smb_info_t *si;
11136         smb_transact2_info_t *t2i;
11137         int count;
11138         gboolean trunc;
11139         int offset = 0;
11140         guint16 dc;
11141
11142         dc = tvb_reported_length(tvb);
11143
11144         si = (smb_info_t *)pinfo->private_data;
11145         if (si->sip != NULL)
11146                 t2i = si->sip->extra_info;
11147         else
11148                 t2i = NULL;
11149
11150         if(parent_tree){
11151                 if (t2i != NULL && t2i->subcmd != -1) {
11152                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11153                                 "%s Data",
11154                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11155                                         "Unknown (0x%02x)"));
11156                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11157                 } else {
11158                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11159                                 "Unknown Transaction2 Data");
11160                 }
11161         }
11162
11163         if (t2i == NULL) {
11164                 offset += dc;
11165                 return offset;
11166         }
11167         switch(t2i->subcmd){
11168         case 0x00:      /*TRANS2_OPEN2*/
11169                 /* XXX not implemented yet. See SNIA doc */
11170                 break;
11171         case 0x01:      /*TRANS2_FIND_FIRST2*/
11172                 /* returned data */
11173                 count = si->info_count;
11174
11175                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11176                         col_append_fstr(pinfo->cinfo, COL_INFO,
11177                         ", Files:");
11178                 }
11179
11180                 while(count--){
11181                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11182                                 offset, &dc, &trunc);
11183                         if (trunc)
11184                                 break;
11185                 }
11186                 break;
11187         case 0x02:      /*TRANS2_FIND_NEXT2*/
11188                 /* returned data */
11189                 count = si->info_count;
11190
11191                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
11192                         col_append_fstr(pinfo->cinfo, COL_INFO,
11193                         ", Files:");
11194                 }
11195
11196                 while(count--){
11197                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
11198                                 offset, &dc, &trunc);
11199                         if (trunc)
11200                                 break;
11201                 }
11202                 break;
11203         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11204                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
11205                 break;
11206         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11207                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11208                 break;
11209         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11210                 /* no data in this response */
11211                 break;
11212         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11213                 /* identical to QUERY_PATH_INFO */
11214                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
11215                 break;
11216         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11217                 /* no data in this response */
11218                 break;
11219         case 0x09:      /*TRANS2_FSCTL*/
11220                 /* XXX dont know how to dissect this one (yet)*/
11221                 break;
11222         case 0x0a:      /*TRANS2_IOCTL2*/
11223                 /* XXX dont know how to dissect this one (yet)*/
11224                 break;
11225         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11226                 /* XXX dont know how to dissect this one (yet)*/
11227                 break;
11228         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11229                 /* XXX dont know how to dissect this one (yet)*/
11230                 break;
11231         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11232                 /* no data in this response */
11233                 break;
11234         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11235                 /* XXX dont know how to dissect this one (yet)*/
11236                 break;
11237         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11238                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
11239                 break;
11240         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11241                 /* the SNIA spec appears to say the response has no data */
11242                 break;
11243         case -1:
11244                 /*
11245                  * We don't know what the matching request was; don't
11246                  * bother putting anything else into the tree for the data.
11247                  */
11248                 offset += dc;
11249                 dc = 0;
11250                 break;
11251         }
11252
11253         /* ooops there were data we didnt know how to process */
11254         if(dc != 0){
11255                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11256                 offset += dc;
11257         }
11258
11259         return offset;
11260 }
11261
11262
11263 static void
11264 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
11265 {
11266         proto_item *item = NULL;
11267         proto_tree *tree = NULL;
11268         smb_info_t *si;
11269         smb_transact2_info_t *t2i;
11270         guint16 fid;
11271         int lno;
11272         int offset = 0;
11273         int pc;
11274
11275         pc = tvb_reported_length(tvb);
11276
11277         si = (smb_info_t *)pinfo->private_data;
11278         if (si->sip != NULL)
11279                 t2i = si->sip->extra_info;
11280         else
11281                 t2i = NULL;
11282
11283         if(parent_tree){
11284                 if (t2i != NULL && t2i->subcmd != -1) {
11285                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11286                                 "%s Parameters",
11287                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
11288                                                 "Unknown (0x%02x)"));
11289                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
11290                 } else {
11291                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
11292                                 "Unknown Transaction2 Parameters");
11293                 }
11294         }
11295
11296         if (t2i == NULL) {
11297                 offset += pc;
11298                 return;
11299         }
11300         switch(t2i->subcmd){
11301         case 0x00:      /*TRANS2_OPEN2*/
11302                 /* fid */
11303                 fid = tvb_get_letohs(tvb, offset);
11304                 add_fid(tvb, pinfo, tree, offset, 2, fid);
11305                 offset += 2;
11306
11307                 /* File Attributes */
11308                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
11309
11310                 /* create time */
11311                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
11312                         hf_smb_create_time, 
11313                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
11314
11315                 /* data size */
11316                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
11317                 offset += 4;
11318
11319                 /* granted access */
11320                 offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
11321
11322                 /* File Type */
11323                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
11324                 offset += 2;
11325
11326                 /* IPC State */
11327                 offset = dissect_ipc_state(tvb, pinfo, tree, offset, FALSE);
11328
11329                 /* open_action */
11330                 offset = dissect_open_action(tvb, pinfo, tree, offset);
11331
11332                 /* 4 reserved bytes */
11333                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
11334                 offset += 4;
11335
11336                 /* ea error offset, only a 16 bit integer here */
11337                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11338                 offset += 2;
11339
11340                 /* ea length */
11341                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
11342                 offset += 4;
11343
11344                 break;
11345         case 0x01:      /*TRANS2_FIND_FIRST2*/
11346                 /* Find First2 information level */
11347                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
11348
11349                 /* sid */
11350                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
11351                 offset += 2;
11352
11353                 /* search count */
11354                 si->info_count = tvb_get_letohs(tvb, offset);
11355                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11356                 offset += 2;
11357
11358                 /* end of search */
11359                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11360                 offset += 2;
11361
11362                 /* ea error offset, only a 16 bit integer here */
11363                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11364                 offset += 2;
11365
11366                 /* last name offset */
11367                 lno = tvb_get_letohs(tvb, offset);
11368                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11369                 offset += 2;
11370
11371                 break;
11372         case 0x02:      /*TRANS2_FIND_NEXT2*/
11373                 /* search count */
11374                 si->info_count = tvb_get_letohs(tvb, offset);
11375                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
11376                 offset += 2;
11377
11378                 /* end of search */
11379                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
11380                 offset += 2;
11381
11382                 /* ea error offset , only a 16 bit integer here*/
11383                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11384                 offset += 2;
11385
11386                 /* last name offset */
11387                 lno = tvb_get_letohs(tvb, offset);
11388                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
11389                 offset += 2;
11390
11391                 break;
11392         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11393                 /* no parameter block here */
11394                 break;
11395         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11396                 /* no parameter block here */
11397                 break;
11398         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11399                 /* no parameter block here */
11400                 break;
11401         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11402                 /* no parameter block here */
11403                 break;
11404         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11405                 /* no parameter block here */
11406                 break;
11407         case 0x09:      /*TRANS2_FSCTL*/
11408                 /* XXX dont know how to dissect this one (yet)*/
11409                 break;
11410         case 0x0a:      /*TRANS2_IOCTL2*/
11411                 /* XXX dont know how to dissect this one (yet)*/
11412                 break;
11413         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11414                 /* XXX dont know how to dissect this one (yet)*/
11415                 break;
11416         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11417                 /* XXX dont know how to dissect this one (yet)*/
11418                 break;
11419         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11420                 /* ea error offset, only a 16 bit integer here */
11421                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11422                 offset += 2;
11423
11424                 break;
11425         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11426                 /* XXX dont know how to dissect this one (yet)*/
11427                 break;
11428         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11429                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11430                 break;
11431         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11432                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
11433                 break;
11434         case -1:
11435                 /*
11436                  * We don't know what the matching request was; don't
11437                  * bother putting anything else into the tree for the data.
11438                  */
11439                 offset += pc;
11440                 break;
11441         }
11442
11443         /* ooops there were data we didnt know how to process */
11444         if(offset<pc){
11445                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
11446                 offset += pc-offset;
11447         }
11448 }
11449
11450
11451 static int
11452 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
11453 {
11454         guint8 sc, wc;
11455         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
11456         gboolean reassembled = FALSE;
11457         smb_info_t *si;
11458         smb_transact2_info_t *t2i = NULL;
11459         guint16 bc;
11460         int padcnt;
11461         gboolean dissected_trans;
11462         fragment_data *r_fd = NULL;
11463         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
11464         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
11465         gboolean save_fragmented;
11466
11467         si = (smb_info_t *)pinfo->private_data;
11468
11469         switch(si->cmd){
11470         case SMB_COM_TRANSACTION2:
11471                 /* transaction2 */
11472                 if (si->sip != NULL) {
11473                         t2i = si->sip->extra_info;
11474                 } else
11475                         t2i = NULL;
11476                 if (t2i == NULL) {
11477                         /*
11478                          * We didn't see the matching request, so we don't
11479                          * know what type of transaction this is.
11480                          */
11481                         proto_tree_add_text(tree, tvb, 0, 0,
11482                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
11483                         if (check_col(pinfo->cinfo, COL_INFO)) {
11484                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11485                         }
11486                 } else {
11487                         si->info_level = t2i->info_level;
11488                         if (t2i->subcmd == -1) {
11489                                 /*
11490                                  * We didn't manage to extract the subcommand
11491                                  * from the matching request (perhaps because
11492                                  * the frame was short), so we don't know what
11493                                  * type of transaction this is.
11494                                  */
11495                                 proto_tree_add_text(tree, tvb, 0, 0,
11496                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
11497                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11498                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
11499                                 }
11500                         } else {
11501                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
11502                                 if (check_col(pinfo->cinfo, COL_INFO)) {
11503                                         col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
11504                                                 val_to_str(t2i->subcmd,
11505                                                         trans2_cmd_vals, 
11506                                                         "<unknown (0x%02x)>"));
11507                                 }
11508                         }
11509                 }
11510                 break;
11511         }
11512
11513         WORD_COUNT;
11514
11515         /* total param count, only a 16bit integer here */
11516         tp = tvb_get_letohs(tvb, offset);
11517         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
11518         offset += 2;
11519
11520         /* total data count, only a 16 bit integer here */
11521         td = tvb_get_letohs(tvb, offset);
11522         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
11523         offset += 2;
11524
11525         /* 2 reserved bytes */
11526         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
11527         offset += 2;
11528
11529         /* param count */
11530         pc = tvb_get_letohs(tvb, offset);
11531         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11532         offset += 2;
11533
11534         /* param offset */
11535         po = tvb_get_letohs(tvb, offset);
11536         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11537         offset += 2;
11538
11539         /* param disp */
11540         pd = tvb_get_letohs(tvb, offset);
11541         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11542         offset += 2;
11543
11544         /* data count */
11545         dc = tvb_get_letohs(tvb, offset);
11546         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11547         offset += 2;
11548
11549         /* data offset */
11550         od = tvb_get_letohs(tvb, offset);
11551         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11552         offset += 2;
11553
11554         /* data disp */
11555         dd = tvb_get_letohs(tvb, offset);
11556         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11557         offset += 2;
11558
11559         /* setup count */
11560         sc = tvb_get_guint8(tvb, offset);
11561         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
11562         offset += 1;
11563
11564         /* reserved byte */
11565         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
11566         offset += 1;
11567
11568
11569         /* if there were any setup bytes, put them in a tvb for later */
11570         if(sc){
11571                 if((2*sc)>tvb_length_remaining(tvb, offset)){
11572                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
11573                 } else {
11574                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
11575                 }
11576                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
11577         } else {
11578                 s_tvb = NULL;
11579                 sp_tvb=NULL;
11580         }
11581         offset += 2*sc;
11582
11583
11584         BYTE_COUNT;
11585
11586
11587         /* reassembly of SMB Transaction data payload.
11588            In this section we do reassembly of both the data and parameters
11589            blocks of the SMB transaction command.
11590         */
11591         save_fragmented = pinfo->fragmented;
11592         /* do we need reassembly? */
11593         if( (td!=dc) || (tp!=pc) ){
11594                 /* oh yeah, either data or parameter section needs 
11595                    reassembly
11596                 */
11597                 pinfo->fragmented = TRUE;
11598                 if(smb_trans_reassembly){
11599                         /* ...and we were told to do reassembly */
11600                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
11601                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
11602                                                              po, pc, pd, td+tp);
11603                                 
11604                         }
11605                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
11606                                 r_fd = smb_trans_defragment(tree, pinfo, tvb, 
11607                                                              od, dc, dd+tp, td+tp);
11608                         }
11609                 }
11610         }
11611
11612         /* if we got a reassembled fd structure from the reassembly routine we must
11613            create pd_tvb from it 
11614         */
11615         if(r_fd){
11616                 proto_tree *tr;
11617                 proto_item *it;
11618                 fragment_data *fd;
11619                 
11620                 it = proto_tree_add_text(tree, tvb, 0, 0, "Fragments");
11621                 tr = proto_item_add_subtree(it, ett_smb_segments);
11622                 for(fd=r_fd->next;fd;fd=fd->next){
11623                         proto_tree_add_text(tr, tvb, 0, 0, "Frame:%u Data:%u-%u",
11624                                             fd->frame, fd->offset, fd->offset+fd->len-1);
11625                 }
11626                 
11627                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
11628                                              r_fd->datalen);
11629                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
11630                 add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
11631                 pinfo->fragmented = FALSE;
11632         }
11633
11634
11635         if(pd_tvb){
11636                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
11637                 if(tp){
11638                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
11639                 }
11640                 if(td){
11641                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
11642                 }
11643         } else {
11644                 /* It was not reassembled. Do as best as we can.
11645                  * in this case we always try to dissect the stuff if 
11646                  * data and param displacement is 0. i.e. for the first
11647                  * (and maybe only) packet.
11648                  */
11649                 if( (pd==0) && (dd==0) ){
11650                         int min;
11651                         int reported_min;
11652                         min = MIN(pc,tvb_length_remaining(tvb,po));
11653                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
11654                         if(min && reported_min) {
11655                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
11656                         }
11657                         min = MIN(dc,tvb_length_remaining(tvb,od));
11658                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
11659                         if(min && reported_min) {
11660                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
11661                         }
11662                         /*
11663                          * A tvbuff containing the parameters
11664                          * and the data.
11665                          * XXX - check pc and dc as well?
11666                          */
11667                         if (tvb_length_remaining(tvb, po)){
11668                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
11669                         }
11670                 }
11671         }
11672
11673
11674
11675         /* parameters */
11676         if(po>offset){
11677                 /* We have some padding bytes.
11678                 */
11679                 padcnt = po-offset;
11680                 if (padcnt > bc)
11681                         padcnt = bc;
11682                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11683                 COUNT_BYTES(padcnt);
11684         }
11685         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
11686                 /* TRANSACTION2 parameters*/
11687                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
11688         }
11689         COUNT_BYTES(pc);
11690
11691
11692         /* data */
11693         if(od>offset){
11694                 /* We have some initial padding bytes.
11695                 */
11696                 padcnt = od-offset;
11697                 if (padcnt > bc)
11698                         padcnt = bc;
11699                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
11700                 COUNT_BYTES(padcnt);
11701         }
11702         /*
11703          * If the data count is bigger than the count of bytes
11704          * remaining, clamp it so that the count of bytes remaining
11705          * doesn't go negative.
11706          */
11707         if (dc > bc)
11708                 dc = bc;
11709         COUNT_BYTES(dc);
11710
11711
11712
11713         /* from now on, everything is in separate tvbuffs so we dont count
11714            the bytes with COUNT_BYTES any more.
11715            neither do we reference offset any more (which by now points to the
11716            first byte AFTER this PDU */
11717
11718
11719         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
11720                 /* TRANSACTION2 parameters*/
11721                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
11722         }
11723
11724
11725         if(si->cmd==SMB_COM_TRANSACTION){
11726                 smb_transact_info_t *tri;
11727
11728                 dissected_trans = FALSE;
11729                 if (si->sip != NULL)
11730                         tri = si->sip->extra_info;
11731                 else
11732                         tri = NULL;
11733                 if (tri != NULL) {
11734                         switch(tri->subcmd){
11735
11736                         case TRANSACTION_PIPE:
11737                                 /* This function is safe to call for 
11738                                    s_tvb==sp_tvb==NULL, i.e. if we don't
11739                                    know them at this point.
11740                                    It's also safe to call if "p_tvb"
11741                                    or "d_tvb" are null.
11742                                 */
11743                                 if( pd_tvb) {
11744                                         dissected_trans = dissect_pipe_smb(
11745                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
11746                                                 d_tvb, NULL, pinfo, top_tree);
11747                                 }
11748                                 break;
11749                                 
11750                         case TRANSACTION_MAILSLOT:
11751                                 /* This one should be safe to call
11752                                    even if s_tvb and sp_tvb is NULL
11753                                 */
11754                                 if(d_tvb){
11755                                         dissected_trans = dissect_mailslot_smb(
11756                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
11757                                                 top_tree);
11758                                 }
11759                                 break;
11760                         }
11761                 }
11762                 if (!dissected_trans) {
11763                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
11764                         dissect_trans_data(s_tvb, p_tvb, d_tvb,
11765                                            pinfo, tree);
11766                 }
11767         }
11768
11769
11770         if( (p_tvb==0) && (d_tvb==0) ){
11771                 if(check_col(pinfo->cinfo, COL_INFO)){
11772                         col_append_str(pinfo->cinfo, COL_INFO,
11773                                        "[transact continuation]");
11774                 }
11775         }
11776
11777         pinfo->fragmented = save_fragmented;
11778         END_OF_SMB
11779
11780         return offset;
11781 }
11782
11783
11784 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11785    END Transaction/Transaction2 Primary and secondary requests
11786    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
11787
11788
11789 static int
11790 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
11791 {
11792         guint8 wc;
11793         guint16 bc;
11794
11795         WORD_COUNT;
11796  
11797         if (wc != 0)
11798                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
11799
11800         BYTE_COUNT;
11801
11802         if (bc != 0)
11803                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
11804
11805         END_OF_SMB
11806
11807         return offset;
11808 }
11809
11810 typedef struct _smb_function {
11811        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
11812        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
11813 } smb_function;
11814
11815 smb_function smb_dissector[256] = {
11816   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
11817   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
11818   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
11819   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
11820   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
11821   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
11822   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
11823   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
11824   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
11825   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
11826   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
11827   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
11828   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
11829   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
11830   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
11831   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
11832
11833   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
11834   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
11835   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
11836   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
11837   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
11838   /* 0x15 */  {dissect_unknown, dissect_unknown},
11839   /* 0x16 */  {dissect_unknown, dissect_unknown},
11840   /* 0x17 */  {dissect_unknown, dissect_unknown},
11841   /* 0x18 */  {dissect_unknown, dissect_unknown},
11842   /* 0x19 */  {dissect_unknown, dissect_unknown},
11843   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
11844   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
11845   /* 0x1c */  {dissect_unknown, dissect_unknown},
11846   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
11847   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
11848   /* 0x1f */  {dissect_unknown, dissect_unknown},
11849
11850   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
11851   /* 0x21 */  {dissect_unknown, dissect_unknown},
11852   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
11853   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
11854   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
11855   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
11856   /* 0x26 Transaction Secondary */  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
11857   /* 0x27 */  {dissect_unknown, dissect_unknown},
11858   /* 0x28 */  {dissect_unknown, dissect_unknown},
11859   /* 0x29 */  {dissect_unknown, dissect_unknown},
11860   /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
11861   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
11862   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
11863   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
11864   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
11865   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
11866
11867   /* 0x30 */  {dissect_unknown, dissect_unknown},
11868   /* 0x31 */  {dissect_unknown, dissect_unknown},
11869   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
11870   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
11871   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
11872   /* 0x35 */  {dissect_unknown, dissect_unknown},
11873   /* 0x36 */  {dissect_unknown, dissect_unknown},
11874   /* 0x37 */  {dissect_unknown, dissect_unknown},
11875   /* 0x38 */  {dissect_unknown, dissect_unknown},
11876   /* 0x39 */  {dissect_unknown, dissect_unknown},
11877   /* 0x3a */  {dissect_unknown, dissect_unknown},
11878   /* 0x3b */  {dissect_unknown, dissect_unknown},
11879   /* 0x3c */  {dissect_unknown, dissect_unknown},
11880   /* 0x3d */  {dissect_unknown, dissect_unknown},
11881   /* 0x3e */  {dissect_unknown, dissect_unknown},
11882   /* 0x3f */  {dissect_unknown, dissect_unknown},
11883
11884   /* 0x40 */  {dissect_unknown, dissect_unknown},
11885   /* 0x41 */  {dissect_unknown, dissect_unknown},
11886   /* 0x42 */  {dissect_unknown, dissect_unknown},
11887   /* 0x43 */  {dissect_unknown, dissect_unknown},
11888   /* 0x44 */  {dissect_unknown, dissect_unknown},
11889   /* 0x45 */  {dissect_unknown, dissect_unknown},
11890   /* 0x46 */  {dissect_unknown, dissect_unknown},
11891   /* 0x47 */  {dissect_unknown, dissect_unknown},
11892   /* 0x48 */  {dissect_unknown, dissect_unknown},
11893   /* 0x49 */  {dissect_unknown, dissect_unknown},
11894   /* 0x4a */  {dissect_unknown, dissect_unknown},
11895   /* 0x4b */  {dissect_unknown, dissect_unknown},
11896   /* 0x4c */  {dissect_unknown, dissect_unknown},
11897   /* 0x4d */  {dissect_unknown, dissect_unknown},
11898   /* 0x4e */  {dissect_unknown, dissect_unknown},
11899   /* 0x4f */  {dissect_unknown, dissect_unknown},
11900
11901   /* 0x50 */  {dissect_unknown, dissect_unknown},
11902   /* 0x51 */  {dissect_unknown, dissect_unknown},
11903   /* 0x52 */  {dissect_unknown, dissect_unknown},
11904   /* 0x53 */  {dissect_unknown, dissect_unknown},
11905   /* 0x54 */  {dissect_unknown, dissect_unknown},
11906   /* 0x55 */  {dissect_unknown, dissect_unknown},
11907   /* 0x56 */  {dissect_unknown, dissect_unknown},
11908   /* 0x57 */  {dissect_unknown, dissect_unknown},
11909   /* 0x58 */  {dissect_unknown, dissect_unknown},
11910   /* 0x59 */  {dissect_unknown, dissect_unknown},
11911   /* 0x5a */  {dissect_unknown, dissect_unknown},
11912   /* 0x5b */  {dissect_unknown, dissect_unknown},
11913   /* 0x5c */  {dissect_unknown, dissect_unknown},
11914   /* 0x5d */  {dissect_unknown, dissect_unknown},
11915   /* 0x5e */  {dissect_unknown, dissect_unknown},
11916   /* 0x5f */  {dissect_unknown, dissect_unknown},
11917
11918   /* 0x60 */  {dissect_unknown, dissect_unknown},
11919   /* 0x61 */  {dissect_unknown, dissect_unknown},
11920   /* 0x62 */  {dissect_unknown, dissect_unknown},
11921   /* 0x63 */  {dissect_unknown, dissect_unknown},
11922   /* 0x64 */  {dissect_unknown, dissect_unknown},
11923   /* 0x65 */  {dissect_unknown, dissect_unknown},
11924   /* 0x66 */  {dissect_unknown, dissect_unknown},
11925   /* 0x67 */  {dissect_unknown, dissect_unknown},
11926   /* 0x68 */  {dissect_unknown, dissect_unknown},
11927   /* 0x69 */  {dissect_unknown, dissect_unknown},
11928   /* 0x6a */  {dissect_unknown, dissect_unknown},
11929   /* 0x6b */  {dissect_unknown, dissect_unknown},
11930   /* 0x6c */  {dissect_unknown, dissect_unknown},
11931   /* 0x6d */  {dissect_unknown, dissect_unknown},
11932   /* 0x6e */  {dissect_unknown, dissect_unknown},
11933   /* 0x6f */  {dissect_unknown, dissect_unknown},
11934
11935   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
11936   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
11937   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
11938   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
11939   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
11940   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
11941   /* 0x76 */  {dissect_unknown, dissect_unknown},
11942   /* 0x77 */  {dissect_unknown, dissect_unknown},
11943   /* 0x78 */  {dissect_unknown, dissect_unknown},
11944   /* 0x79 */  {dissect_unknown, dissect_unknown},
11945   /* 0x7a */  {dissect_unknown, dissect_unknown},
11946   /* 0x7b */  {dissect_unknown, dissect_unknown},
11947   /* 0x7c */  {dissect_unknown, dissect_unknown},
11948   /* 0x7d */  {dissect_unknown, dissect_unknown},
11949   /* 0x7e */  {dissect_unknown, dissect_unknown},
11950   /* 0x7f */  {dissect_unknown, dissect_unknown},
11951
11952   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
11953   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
11954   /* 0x82 */  {dissect_unknown, dissect_unknown},
11955   /* 0x83 */  {dissect_unknown, dissect_unknown},
11956   /* 0x84 */  {dissect_unknown, dissect_unknown},
11957   /* 0x85 */  {dissect_unknown, dissect_unknown},
11958   /* 0x86 */  {dissect_unknown, dissect_unknown},
11959   /* 0x87 */  {dissect_unknown, dissect_unknown},
11960   /* 0x88 */  {dissect_unknown, dissect_unknown},
11961   /* 0x89 */  {dissect_unknown, dissect_unknown},
11962   /* 0x8a */  {dissect_unknown, dissect_unknown},
11963   /* 0x8b */  {dissect_unknown, dissect_unknown},
11964   /* 0x8c */  {dissect_unknown, dissect_unknown},
11965   /* 0x8d */  {dissect_unknown, dissect_unknown},
11966   /* 0x8e */  {dissect_unknown, dissect_unknown},
11967   /* 0x8f */  {dissect_unknown, dissect_unknown},
11968
11969   /* 0x90 */  {dissect_unknown, dissect_unknown},
11970   /* 0x91 */  {dissect_unknown, dissect_unknown},
11971   /* 0x92 */  {dissect_unknown, dissect_unknown},
11972   /* 0x93 */  {dissect_unknown, dissect_unknown},
11973   /* 0x94 */  {dissect_unknown, dissect_unknown},
11974   /* 0x95 */  {dissect_unknown, dissect_unknown},
11975   /* 0x96 */  {dissect_unknown, dissect_unknown},
11976   /* 0x97 */  {dissect_unknown, dissect_unknown},
11977   /* 0x98 */  {dissect_unknown, dissect_unknown},
11978   /* 0x99 */  {dissect_unknown, dissect_unknown},
11979   /* 0x9a */  {dissect_unknown, dissect_unknown},
11980   /* 0x9b */  {dissect_unknown, dissect_unknown},
11981   /* 0x9c */  {dissect_unknown, dissect_unknown},
11982   /* 0x9d */  {dissect_unknown, dissect_unknown},
11983   /* 0x9e */  {dissect_unknown, dissect_unknown},
11984   /* 0x9f */  {dissect_unknown, dissect_unknown},
11985   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
11986   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
11987   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
11988   /* 0xa3 */  {dissect_unknown, dissect_unknown},
11989   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
11990   /* 0xa5 */  {dissect_unknown, dissect_unknown},
11991   /* 0xa6 */  {dissect_unknown, dissect_unknown},
11992   /* 0xa7 */  {dissect_unknown, dissect_unknown},
11993   /* 0xa8 */  {dissect_unknown, dissect_unknown},
11994   /* 0xa9 */  {dissect_unknown, dissect_unknown},
11995   /* 0xaa */  {dissect_unknown, dissect_unknown},
11996   /* 0xab */  {dissect_unknown, dissect_unknown},
11997   /* 0xac */  {dissect_unknown, dissect_unknown},
11998   /* 0xad */  {dissect_unknown, dissect_unknown},
11999   /* 0xae */  {dissect_unknown, dissect_unknown},
12000   /* 0xaf */  {dissect_unknown, dissect_unknown},
12001
12002   /* 0xb0 */  {dissect_unknown, dissect_unknown},
12003   /* 0xb1 */  {dissect_unknown, dissect_unknown},
12004   /* 0xb2 */  {dissect_unknown, dissect_unknown},
12005   /* 0xb3 */  {dissect_unknown, dissect_unknown},
12006   /* 0xb4 */  {dissect_unknown, dissect_unknown},
12007   /* 0xb5 */  {dissect_unknown, dissect_unknown},
12008   /* 0xb6 */  {dissect_unknown, dissect_unknown},
12009   /* 0xb7 */  {dissect_unknown, dissect_unknown},
12010   /* 0xb8 */  {dissect_unknown, dissect_unknown},
12011   /* 0xb9 */  {dissect_unknown, dissect_unknown},
12012   /* 0xba */  {dissect_unknown, dissect_unknown},
12013   /* 0xbb */  {dissect_unknown, dissect_unknown},
12014   /* 0xbc */  {dissect_unknown, dissect_unknown},
12015   /* 0xbd */  {dissect_unknown, dissect_unknown},
12016   /* 0xbe */  {dissect_unknown, dissect_unknown},
12017   /* 0xbf */  {dissect_unknown, dissect_unknown},
12018   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
12019   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
12020   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
12021   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
12022   /* 0xc4 */  {dissect_unknown, dissect_unknown},
12023   /* 0xc5 */  {dissect_unknown, dissect_unknown},
12024   /* 0xc6 */  {dissect_unknown, dissect_unknown},
12025   /* 0xc7 */  {dissect_unknown, dissect_unknown},
12026   /* 0xc8 */  {dissect_unknown, dissect_unknown},
12027   /* 0xc9 */  {dissect_unknown, dissect_unknown},
12028   /* 0xca */  {dissect_unknown, dissect_unknown},
12029   /* 0xcb */  {dissect_unknown, dissect_unknown},
12030   /* 0xcc */  {dissect_unknown, dissect_unknown},
12031   /* 0xcd */  {dissect_unknown, dissect_unknown},
12032   /* 0xce */  {dissect_unknown, dissect_unknown},
12033   /* 0xcf */  {dissect_unknown, dissect_unknown},
12034
12035   /* 0xd0 */  {dissect_unknown, dissect_unknown},
12036   /* 0xd1 */  {dissect_unknown, dissect_unknown},
12037   /* 0xd2 */  {dissect_unknown, dissect_unknown},
12038   /* 0xd3 */  {dissect_unknown, dissect_unknown},
12039   /* 0xd4 */  {dissect_unknown, dissect_unknown},
12040   /* 0xd5 */  {dissect_unknown, dissect_unknown},
12041   /* 0xd6 */  {dissect_unknown, dissect_unknown},
12042   /* 0xd7 */  {dissect_unknown, dissect_unknown},
12043   /* 0xd8 */  {dissect_unknown, dissect_unknown},
12044   /* 0xd9 */  {dissect_unknown, dissect_unknown},
12045   /* 0xda */  {dissect_unknown, dissect_unknown},
12046   /* 0xdb */  {dissect_unknown, dissect_unknown},
12047   /* 0xdc */  {dissect_unknown, dissect_unknown},
12048   /* 0xdd */  {dissect_unknown, dissect_unknown},
12049   /* 0xde */  {dissect_unknown, dissect_unknown},
12050   /* 0xdf */  {dissect_unknown, dissect_unknown},
12051
12052   /* 0xe0 */  {dissect_unknown, dissect_unknown},
12053   /* 0xe1 */  {dissect_unknown, dissect_unknown},
12054   /* 0xe2 */  {dissect_unknown, dissect_unknown},
12055   /* 0xe3 */  {dissect_unknown, dissect_unknown},
12056   /* 0xe4 */  {dissect_unknown, dissect_unknown},
12057   /* 0xe5 */  {dissect_unknown, dissect_unknown},
12058   /* 0xe6 */  {dissect_unknown, dissect_unknown},
12059   /* 0xe7 */  {dissect_unknown, dissect_unknown},
12060   /* 0xe8 */  {dissect_unknown, dissect_unknown},
12061   /* 0xe9 */  {dissect_unknown, dissect_unknown},
12062   /* 0xea */  {dissect_unknown, dissect_unknown},
12063   /* 0xeb */  {dissect_unknown, dissect_unknown},
12064   /* 0xec */  {dissect_unknown, dissect_unknown},
12065   /* 0xed */  {dissect_unknown, dissect_unknown},
12066   /* 0xee */  {dissect_unknown, dissect_unknown},
12067   /* 0xef */  {dissect_unknown, dissect_unknown},
12068
12069   /* 0xf0 */  {dissect_unknown, dissect_unknown},
12070   /* 0xf1 */  {dissect_unknown, dissect_unknown},
12071   /* 0xf2 */  {dissect_unknown, dissect_unknown},
12072   /* 0xf3 */  {dissect_unknown, dissect_unknown},
12073   /* 0xf4 */  {dissect_unknown, dissect_unknown},
12074   /* 0xf5 */  {dissect_unknown, dissect_unknown},
12075   /* 0xf6 */  {dissect_unknown, dissect_unknown},
12076   /* 0xf7 */  {dissect_unknown, dissect_unknown},
12077   /* 0xf8 */  {dissect_unknown, dissect_unknown},
12078   /* 0xf9 */  {dissect_unknown, dissect_unknown},
12079   /* 0xfa */  {dissect_unknown, dissect_unknown},
12080   /* 0xfb */  {dissect_unknown, dissect_unknown},
12081   /* 0xfc */  {dissect_unknown, dissect_unknown},
12082   /* 0xfd */  {dissect_unknown, dissect_unknown},
12083   /* 0xfe */  {dissect_unknown, dissect_unknown},
12084   /* 0xff */  {dissect_unknown, dissect_unknown},
12085 };
12086
12087 static int
12088 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
12089 {
12090         int old_offset = offset;
12091         smb_info_t *si;
12092  
12093         si = pinfo->private_data;
12094         if(cmd!=0xff){
12095                 proto_item *cmd_item;
12096                 proto_tree *cmd_tree;
12097                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
12098
12099                 if (check_col(pinfo->cinfo, COL_INFO)) {
12100                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
12101                                 decode_smb_name(cmd),
12102                                 (si->request)? "Request" : "Response");
12103                 }
12104
12105                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
12106                         "%s %s (0x%02x)",
12107                         decode_smb_name(cmd), 
12108                         (si->request)?"Request":"Response",
12109                         cmd);
12110
12111                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
12112
12113                 dissector = (si->request)?
12114                         smb_dissector[cmd].request:smb_dissector[cmd].response;
12115
12116                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
12117                 proto_item_set_len(cmd_item, offset-old_offset);
12118         }
12119         return offset;
12120 }
12121
12122
12123 /* NOTE: this value_string array will also be used to access data directly by
12124  * index instead of val_to_str() since 
12125  * 1, the array will always span every value from 0x00 to 0xff and
12126  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
12127  * This means that this value_string array MUST always
12128  * 1, contain all entries 0x00 to 0xff
12129  * 2, all entries must be in order.
12130  */
12131 static const value_string smb_cmd_vals[] = {
12132   { 0x00, "Create Directory" },
12133   { 0x01, "Delete Directory" },
12134   { 0x02, "Open" },
12135   { 0x03, "Create" },
12136   { 0x04, "Close" },
12137   { 0x05, "Flush" },
12138   { 0x06, "Delete" },
12139   { 0x07, "Rename" },
12140   { 0x08, "Query Information" },
12141   { 0x09, "Set Information" },
12142   { 0x0A, "Read" },
12143   { 0x0B, "Write" },
12144   { 0x0C, "Lock Byte Range" },
12145   { 0x0D, "Unlock Byte Range" },
12146   { 0x0E, "Create Temp" },
12147   { 0x0F, "Create New" },
12148   { 0x10, "Check Directory" },
12149   { 0x11, "Process Exit" },
12150   { 0x12, "Seek" },
12151   { 0x13, "Lock And Read" },
12152   { 0x14, "Write And Unlock" },
12153   { 0x15, "unknown-0x15" },
12154   { 0x16, "unknown-0x16" },
12155   { 0x17, "unknown-0x17" },
12156   { 0x18, "unknown-0x18" },
12157   { 0x19, "unknown-0x19" },
12158   { 0x1A, "Read Raw" },
12159   { 0x1B, "Read MPX" },
12160   { 0x1C, "Read MPX Secondary" },
12161   { 0x1D, "Write Raw" },
12162   { 0x1E, "Write MPX" },
12163   { 0x1F, "SMBwriteBs" },
12164   { 0x20, "Write Complete" },
12165   { 0x21, "unknown-0x21" },
12166   { 0x22, "Set Information2" },
12167   { 0x23, "Query Information2" },
12168   { 0x24, "Locking AndX" },
12169   { 0x25, "Transaction" },
12170   { 0x26, "Transaction Secondary" },
12171   { 0x27, "IOCTL" },
12172   { 0x28, "IOCTL Secondary" },
12173   { 0x29, "Copy" },
12174   { 0x2A, "Move" },
12175   { 0x2B, "Echo" },
12176   { 0x2C, "Write And Close" },
12177   { 0x2D, "Open AndX" },
12178   { 0x2E, "Read AndX" },
12179   { 0x2F, "Write AndX" },
12180   { 0x30, "unknown-0x30" },
12181   { 0x31, "Close And Tree Discover" },
12182   { 0x32, "Transaction2" },
12183   { 0x33, "Transaction2 Secondary" },
12184   { 0x34, "Find Close2" },
12185   { 0x35, "Find Notify Close" },
12186   { 0x36, "unknown-0x36" },
12187   { 0x37, "unknown-0x37" },
12188   { 0x38, "unknown-0x38" },
12189   { 0x39, "unknown-0x39" },
12190   { 0x3A, "unknown-0x3A" },
12191   { 0x3B, "unknown-0x3B" },
12192   { 0x3C, "unknown-0x3C" },
12193   { 0x3D, "unknown-0x3D" },
12194   { 0x3E, "unknown-0x3E" },
12195   { 0x3F, "unknown-0x3F" },
12196   { 0x40, "unknown-0x40" },
12197   { 0x41, "unknown-0x41" },
12198   { 0x42, "unknown-0x42" },
12199   { 0x43, "unknown-0x43" },
12200   { 0x44, "unknown-0x44" },
12201   { 0x45, "unknown-0x45" },
12202   { 0x46, "unknown-0x46" },
12203   { 0x47, "unknown-0x47" },
12204   { 0x48, "unknown-0x48" },
12205   { 0x49, "unknown-0x49" },
12206   { 0x4A, "unknown-0x4A" },
12207   { 0x4B, "unknown-0x4B" },
12208   { 0x4C, "unknown-0x4C" },
12209   { 0x4D, "unknown-0x4D" },
12210   { 0x4E, "unknown-0x4E" },
12211   { 0x4F, "unknown-0x4F" },
12212   { 0x50, "unknown-0x50" },
12213   { 0x51, "unknown-0x51" },
12214   { 0x52, "unknown-0x52" },
12215   { 0x53, "unknown-0x53" },
12216   { 0x54, "unknown-0x54" },
12217   { 0x55, "unknown-0x55" },
12218   { 0x56, "unknown-0x56" },
12219   { 0x57, "unknown-0x57" },
12220   { 0x58, "unknown-0x58" },
12221   { 0x59, "unknown-0x59" },
12222   { 0x5A, "unknown-0x5A" },
12223   { 0x5B, "unknown-0x5B" },
12224   { 0x5C, "unknown-0x5C" },
12225   { 0x5D, "unknown-0x5D" },
12226   { 0x5E, "unknown-0x5E" },
12227   { 0x5F, "unknown-0x5F" },
12228   { 0x60, "unknown-0x60" },
12229   { 0x61, "unknown-0x61" },
12230   { 0x62, "unknown-0x62" },
12231   { 0x63, "unknown-0x63" },
12232   { 0x64, "unknown-0x64" },
12233   { 0x65, "unknown-0x65" },
12234   { 0x66, "unknown-0x66" },
12235   { 0x67, "unknown-0x67" },
12236   { 0x68, "unknown-0x68" },
12237   { 0x69, "unknown-0x69" },
12238   { 0x6A, "unknown-0x6A" },
12239   { 0x6B, "unknown-0x6B" },
12240   { 0x6C, "unknown-0x6C" },
12241   { 0x6D, "unknown-0x6D" },
12242   { 0x6E, "unknown-0x6E" },
12243   { 0x6F, "unknown-0x6F" },
12244   { 0x70, "Tree Connect" },
12245   { 0x71, "Tree Disconnect" },
12246   { 0x72, "Negotiate Protocol" },
12247   { 0x73, "Session Setup AndX" },
12248   { 0x74, "Logoff AndX" },
12249   { 0x75, "Tree Connect AndX" },
12250   { 0x76, "unknown-0x76" },
12251   { 0x77, "unknown-0x77" },
12252   { 0x78, "unknown-0x78" },
12253   { 0x79, "unknown-0x79" },
12254   { 0x7A, "unknown-0x7A" },
12255   { 0x7B, "unknown-0x7B" },
12256   { 0x7C, "unknown-0x7C" },
12257   { 0x7D, "unknown-0x7D" },
12258   { 0x7E, "unknown-0x7E" },
12259   { 0x7F, "unknown-0x7F" },
12260   { 0x80, "Query Information Disk" },
12261   { 0x81, "Search" },
12262   { 0x82, "Find" },
12263   { 0x83, "Find Unique" },
12264   { 0x84, "SMBfclose" },
12265   { 0x85, "unknown-0x85" },
12266   { 0x86, "unknown-0x86" },
12267   { 0x87, "unknown-0x87" },
12268   { 0x88, "unknown-0x88" },
12269   { 0x89, "unknown-0x89" },
12270   { 0x8A, "unknown-0x8A" },
12271   { 0x8B, "unknown-0x8B" },
12272   { 0x8C, "unknown-0x8C" },
12273   { 0x8D, "unknown-0x8D" },
12274   { 0x8E, "unknown-0x8E" },
12275   { 0x8F, "unknown-0x8F" },
12276   { 0x90, "unknown-0x90" },
12277   { 0x91, "unknown-0x91" },
12278   { 0x92, "unknown-0x92" },
12279   { 0x93, "unknown-0x93" },
12280   { 0x94, "unknown-0x94" },
12281   { 0x95, "unknown-0x95" },
12282   { 0x96, "unknown-0x96" },
12283   { 0x97, "unknown-0x97" },
12284   { 0x98, "unknown-0x98" },
12285   { 0x99, "unknown-0x99" },
12286   { 0x9A, "unknown-0x9A" },
12287   { 0x9B, "unknown-0x9B" },
12288   { 0x9C, "unknown-0x9C" },
12289   { 0x9D, "unknown-0x9D" },
12290   { 0x9E, "unknown-0x9E" },
12291   { 0x9F, "unknown-0x9F" },
12292   { 0xA0, "NT Transact" },
12293   { 0xA1, "NT Transact Secondary" },
12294   { 0xA2, "NT Create AndX" },
12295   { 0xA3, "unknown-0xA3" },
12296   { 0xA4, "NT Cancel" },
12297   { 0xA5, "unknown-0xA5" },
12298   { 0xA6, "unknown-0xA6" },
12299   { 0xA7, "unknown-0xA7" },
12300   { 0xA8, "unknown-0xA8" },
12301   { 0xA9, "unknown-0xA9" },
12302   { 0xAA, "unknown-0xAA" },
12303   { 0xAB, "unknown-0xAB" },
12304   { 0xAC, "unknown-0xAC" },
12305   { 0xAD, "unknown-0xAD" },
12306   { 0xAE, "unknown-0xAE" },
12307   { 0xAF, "unknown-0xAF" },
12308   { 0xB0, "unknown-0xB0" },
12309   { 0xB1, "unknown-0xB1" },
12310   { 0xB2, "unknown-0xB2" },
12311   { 0xB3, "unknown-0xB3" },
12312   { 0xB4, "unknown-0xB4" },
12313   { 0xB5, "unknown-0xB5" },
12314   { 0xB6, "unknown-0xB6" },
12315   { 0xB7, "unknown-0xB7" },
12316   { 0xB8, "unknown-0xB8" },
12317   { 0xB9, "unknown-0xB9" },
12318   { 0xBA, "unknown-0xBA" },
12319   { 0xBB, "unknown-0xBB" },
12320   { 0xBC, "unknown-0xBC" },
12321   { 0xBD, "unknown-0xBD" },
12322   { 0xBE, "unknown-0xBE" },
12323   { 0xBF, "unknown-0xBF" },
12324   { 0xC0, "Open Print File" },
12325   { 0xC1, "Write Print File" },
12326   { 0xC2, "Close Print File" },
12327   { 0xC3, "Get Print Queue" },
12328   { 0xC4, "unknown-0xC4" },
12329   { 0xC5, "unknown-0xC5" },
12330   { 0xC6, "unknown-0xC6" },
12331   { 0xC7, "unknown-0xC7" },
12332   { 0xC8, "unknown-0xC8" },
12333   { 0xC9, "unknown-0xC9" },
12334   { 0xCA, "unknown-0xCA" },
12335   { 0xCB, "unknown-0xCB" },
12336   { 0xCC, "unknown-0xCC" },
12337   { 0xCD, "unknown-0xCD" },
12338   { 0xCE, "unknown-0xCE" },
12339   { 0xCF, "unknown-0xCF" },
12340   { 0xD0, "SMBsends" },
12341   { 0xD1, "SMBsendb" },
12342   { 0xD2, "SMBfwdname" },
12343   { 0xD3, "SMBcancelf" },
12344   { 0xD4, "SMBgetmac" },
12345   { 0xD5, "SMBsendstrt" },
12346   { 0xD6, "SMBsendend" },
12347   { 0xD7, "SMBsendtxt" },
12348   { 0xD8, "SMBreadbulk" },
12349   { 0xD9, "SMBwritebulk" },
12350   { 0xDA, "SMBwritebulkdata" },
12351   { 0xDB, "unknown-0xDB" },
12352   { 0xDC, "unknown-0xDC" },
12353   { 0xDD, "unknown-0xDD" },
12354   { 0xDE, "unknown-0xDE" },
12355   { 0xDF, "unknown-0xDF" },
12356   { 0xE0, "unknown-0xE0" },
12357   { 0xE1, "unknown-0xE1" },
12358   { 0xE2, "unknown-0xE2" },
12359   { 0xE3, "unknown-0xE3" },
12360   { 0xE4, "unknown-0xE4" },
12361   { 0xE5, "unknown-0xE5" },
12362   { 0xE6, "unknown-0xE6" },
12363   { 0xE7, "unknown-0xE7" },
12364   { 0xE8, "unknown-0xE8" },
12365   { 0xE9, "unknown-0xE9" },
12366   { 0xEA, "unknown-0xEA" },
12367   { 0xEB, "unknown-0xEB" },
12368   { 0xEC, "unknown-0xEC" },
12369   { 0xED, "unknown-0xED" },
12370   { 0xEE, "unknown-0xEE" },
12371   { 0xEF, "unknown-0xEF" },
12372   { 0xF0, "unknown-0xF0" },
12373   { 0xF1, "unknown-0xF1" },
12374   { 0xF2, "unknown-0xF2" },
12375   { 0xF3, "unknown-0xF3" },
12376   { 0xF4, "unknown-0xF4" },
12377   { 0xF5, "unknown-0xF5" },
12378   { 0xF6, "unknown-0xF6" },
12379   { 0xF7, "unknown-0xF7" },
12380   { 0xF8, "unknown-0xF8" },
12381   { 0xF9, "unknown-0xF9" },
12382   { 0xFA, "unknown-0xFA" },
12383   { 0xFB, "unknown-0xFB" },
12384   { 0xFC, "unknown-0xFC" },
12385   { 0xFD, "unknown-0xFD" },
12386   { 0xFE, "SMBinvalid" },
12387   { 0xFF, "unknown-0xFF" },
12388   { 0x00, NULL },
12389 };
12390
12391 static char *decode_smb_name(unsigned char cmd)
12392 {
12393   return(smb_cmd_vals[cmd].strptr);
12394 }
12395  
12396
12397
12398 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12399  * Everything TVBUFFIFIED above this line
12400  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
12401
12402
12403 static void
12404 free_hash_tables(gpointer ctarg, gpointer user_data)
12405 {
12406         conv_tables_t *ct = ctarg;
12407
12408         if (ct->unmatched)
12409                 g_hash_table_destroy(ct->unmatched);
12410         if (ct->matched)
12411                 g_hash_table_destroy(ct->matched);
12412         if (ct->dcerpc_fid_to_frame)
12413                 g_hash_table_destroy(ct->dcerpc_fid_to_frame);
12414 }
12415
12416 static void
12417 smb_init_protocol(void)
12418 {
12419         if (smb_saved_info_key_chunk)
12420                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
12421         if (smb_saved_info_chunk)
12422                 g_mem_chunk_destroy(smb_saved_info_chunk);
12423         if (smb_nt_transact_info_chunk)
12424                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
12425         if (smb_transact2_info_chunk)
12426                 g_mem_chunk_destroy(smb_transact2_info_chunk);
12427         if (smb_transact_info_chunk)
12428                 g_mem_chunk_destroy(smb_transact_info_chunk);
12429
12430         /*
12431          * Free the hash tables attached to the conversation table
12432          * structures, and then free the list of conversation table
12433          * data structures (which doesn't free the data structures
12434          * themselves; that's done by destroying the chunk from
12435          * which they were allocated).
12436          */
12437         if (conv_tables) {
12438                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
12439                 g_slist_free(conv_tables);
12440                 conv_tables = NULL;
12441         }
12442
12443         /*
12444          * Now destroy the chunk from which the conversation table
12445          * structures were allocated.
12446          */
12447         if (conv_tables_chunk)
12448                 g_mem_chunk_destroy(conv_tables_chunk);
12449
12450         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
12451             sizeof(smb_saved_info_t),
12452             smb_saved_info_init_count * sizeof(smb_saved_info_t),
12453             G_ALLOC_ONLY);
12454         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
12455             sizeof(smb_saved_info_key_t),
12456             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
12457             G_ALLOC_ONLY);
12458         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
12459             sizeof(smb_nt_transact_info_t),
12460             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
12461             G_ALLOC_ONLY);
12462         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
12463             sizeof(smb_transact2_info_t),
12464             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
12465             G_ALLOC_ONLY);
12466         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
12467             sizeof(smb_transact_info_t),
12468             smb_transact_info_init_count * sizeof(smb_transact_info_t),
12469             G_ALLOC_ONLY);
12470         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
12471             sizeof(conv_tables_t),
12472             conv_tables_count * sizeof(conv_tables_t),
12473             G_ALLOC_ONLY);
12474 }
12475
12476 /* Max string length for displaying Unicode strings.  */
12477 #define MAX_UNICODE_STR_LEN     256
12478
12479
12480 /* Turn a little-endian Unicode '\0'-terminated string into a string we
12481    can display.
12482    XXX - for now, we just handle the ISO 8859-1 characters.
12483    If exactlen==TRUE then us_lenp contains the exact len of the string in
12484    bytes. It might not be null terminated !
12485    bc specifies the number of bytes in the byte parameters; Windows 2000,
12486    at least, appears, in some cases, to put only 1 byte of 0 at the end
12487    of a Unicode string if the byte count
12488 */
12489 static gchar *
12490 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
12491                    guint16 bc)
12492 {
12493   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12494   static gchar *cur;
12495   gchar        *p;
12496   guint16       uchar;
12497   int           len;
12498   int           us_len;
12499   int           overflow = 0;
12500
12501   if (cur == &str[0][0]) {
12502     cur = &str[1][0];
12503   } else if (cur == &str[1][0]) {  
12504     cur = &str[2][0];
12505   } else {  
12506     cur = &str[0][0];
12507   }
12508   p = cur;
12509   len = MAX_UNICODE_STR_LEN;
12510   us_len = 0;
12511   for (;;) {
12512     if (bc == 0)
12513       break;
12514     if (bc == 1) {
12515       /* XXX - explain this */
12516       if (!exactlen)
12517         us_len += 1;    /* this is a one-byte null terminator */
12518       break;
12519     }
12520     uchar = tvb_get_letohs(tvb, offset);
12521     if (uchar == 0) {
12522       us_len += 2;      /* this is a two-byte null terminator */
12523       break;
12524     }
12525     if (len > 0) {
12526       if ((uchar & 0xFF00) == 0)
12527         *p++ = uchar;   /* ISO 8859-1 */
12528       else
12529         *p++ = '?';     /* not 8859-1 */
12530       len--;
12531     } else
12532       overflow = 1;
12533     offset += 2;
12534     bc -= 2;
12535     us_len += 2;
12536     if(exactlen){
12537       if(us_len>= *us_lenp){
12538         break;
12539       }
12540     }
12541   }
12542   if (overflow) {
12543     /* Note that we're not showing the full string.  */
12544     *p++ = '.';
12545     *p++ = '.';
12546     *p++ = '.';
12547   }
12548   *p = '\0';
12549   *us_lenp = us_len;
12550   return cur;
12551 }
12552  
12553
12554 /* nopad == TRUE : Do not add any padding before this string
12555  * exactlen == TRUE : len contains the exact len of the string in bytes.
12556  * bc: pointer to variable with amount of data left in the byte parameters
12557  *   region
12558  */
12559 static const gchar *
12560 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
12561     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
12562     guint16 *bcp)
12563 {
12564   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
12565   static gchar *cur;
12566   const gchar *string;
12567   int string_len;
12568   smb_info_t *si;
12569   int copylen;
12570
12571   if (*bcp == 0) {
12572     /* Not enough data in buffer */
12573     return NULL;
12574   }
12575   si = pinfo->private_data;
12576   if (si->unicode) {
12577     if ((!nopad) && (*offsetp % 2)) {
12578       /*
12579        * XXX - this should be an offset relative to the beginning of the SMB,
12580        * not an offset relative to the beginning of the frame; if the stuff
12581        * before the SMB has an odd number of bytes, an offset relative to
12582        * the beginning of the frame will give the wrong answer.
12583        */
12584       (*offsetp)++;   /* Looks like a pad byte there sometimes */
12585       (*bcp)--;
12586       if (*bcp == 0) {
12587         /* Not enough data in buffer */
12588         return NULL;
12589       }
12590     }
12591     if(exactlen){
12592       string_len = *len;
12593       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
12594     } else {
12595       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
12596     }
12597   } else {
12598     if(exactlen){
12599       /*
12600        * The string we return must be null-terminated.
12601        */
12602       if (cur == &str[0][0]) {
12603         cur = &str[1][0];
12604       } else if (cur == &str[1][0]) {  
12605         cur = &str[2][0];
12606       } else {  
12607         cur = &str[0][0];
12608       }
12609       copylen = *len;
12610       if (copylen > MAX_UNICODE_STR_LEN)
12611         copylen = MAX_UNICODE_STR_LEN;
12612       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
12613       cur[copylen] = '\0';
12614       if (copylen > MAX_UNICODE_STR_LEN)
12615         strcat(cur, "...");
12616       string_len = *len;
12617       string = cur;
12618     } else {
12619       string_len = tvb_strsize(tvb, *offsetp);
12620       string = tvb_get_ptr(tvb, *offsetp, string_len);
12621     }
12622   }
12623   *len = string_len;
12624   return string;
12625 }
12626
12627
12628
12629 static const value_string errcls_types[] = {
12630   { SMB_SUCCESS, "Success"},
12631   { SMB_ERRDOS, "DOS Error"},
12632   { SMB_ERRSRV, "Server Error"},
12633   { SMB_ERRHRD, "Hardware Error"},
12634   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
12635   { 0, NULL }
12636 };
12637
12638 const value_string DOS_errors[] = {
12639   {0, "Success"},
12640   {SMBE_insufficientbuffer, "Insufficient buffer"},
12641   {SMBE_badfunc, "Invalid function (or system call)"},
12642   {SMBE_badfile, "File not found (pathname error)"},
12643   {SMBE_badpath, "Directory not found"},
12644   {SMBE_nofids, "Too many open files"},
12645   {SMBE_noaccess, "Access denied"},
12646   {SMBE_badfid, "Invalid fid"},
12647   {SMBE_nomem,  "Out of memory"},
12648   {SMBE_badmem, "Invalid memory block address"},
12649   {SMBE_badenv, "Invalid environment"},
12650   {SMBE_badaccess, "Invalid open mode"},
12651   {SMBE_baddata, "Invalid data (only from ioctl call)"},
12652   {SMBE_res, "Reserved error code?"}, 
12653   {SMBE_baddrive, "Invalid drive"},
12654   {SMBE_remcd, "Attempt to delete current directory"},
12655   {SMBE_diffdevice, "Rename/move across different filesystems"},
12656   {SMBE_nofiles, "No more files found in file search"},
12657   {SMBE_badshare, "Share mode on file conflict with open mode"},
12658   {SMBE_lock, "Lock request conflicts with existing lock"},
12659   {SMBE_unsup, "Request unsupported, returned by Win 95"},
12660   {SMBE_nosuchshare, "Requested share does not exist"},
12661   {SMBE_filexists, "File in operation already exists"},
12662   {SMBE_cannotopen, "Cannot open the file specified"},
12663   {SMBE_unknownlevel, "Unknown info level"},
12664   {SMBE_badpipe, "Named pipe invalid"},
12665   {SMBE_pipebusy, "All instances of pipe are busy"},
12666   {SMBE_pipeclosing, "Named pipe close in progress"},
12667   {SMBE_notconnected, "No process on other end of named pipe"},
12668   {SMBE_moredata, "More data to be returned"},
12669   {SMBE_baddirectory,  "Invalid directory name in a path."},
12670   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
12671   {SMBE_eas_nsup, "Extended attributes not supported"},
12672   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
12673   {SMBE_unknownipc, "Unknown IPC Operation"},
12674   {SMBE_noipc, "Don't support ipc"},
12675   {SMBE_alreadyexists, "File already exists"},
12676   {SMBE_unknownprinterdriver, "Unknown printer driver"},
12677   {SMBE_invalidprintername, "Invalid printer name"},
12678   {SMBE_printeralreadyexists, "Printer already exists"},
12679   {SMBE_invaliddatatype, "Invalid data type"},
12680   {SMBE_invalidenvironment, "Invalid environment"},
12681   {SMBE_printerdriverinuse, "Printer driver in use"},
12682   {SMBE_invalidparam, "Invalid parameter"},
12683   {0, NULL}
12684   };
12685
12686 /* Error codes for the ERRSRV class */
12687
12688 static const value_string SRV_errors[] = {
12689   {SMBE_error, "Non specific error code"},
12690   {SMBE_badpw, "Bad password"},
12691   {SMBE_badtype, "Reserved"},
12692   {SMBE_access, "No permissions to perform the requested operation"},
12693   {SMBE_invnid, "TID invalid"},
12694   {SMBE_invnetname, "Invalid network name. Service not found"},
12695   {SMBE_invdevice, "Invalid device"},
12696   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
12697   {SMBE_qfull, "Print queue full"},
12698   {SMBE_qtoobig, "Queued item too big"},
12699   {SMBE_qeof, "EOF on print queue dump"},
12700   {SMBE_invpfid, "Invalid print file in smb_fid"},
12701   {SMBE_smbcmd, "Unrecognised command"},
12702   {SMBE_srverror, "SMB server internal error"},
12703   {SMBE_filespecs, "Fid and pathname invalid combination"},
12704   {SMBE_badlink, "Bad link in request ???"},
12705   {SMBE_badpermits, "Access specified for a file is not valid"},
12706   {SMBE_badpid, "Bad process id in request"},
12707   {SMBE_setattrmode, "Attribute mode invalid"},
12708   {SMBE_paused, "Message server paused"},
12709   {SMBE_msgoff, "Not receiving messages"},
12710   {SMBE_noroom, "No room for message"},
12711   {SMBE_rmuns, "Too many remote usernames"},
12712   {SMBE_timeout, "Operation timed out"},
12713   {SMBE_noresource, "No resources currently available for request."},
12714   {SMBE_toomanyuids, "Too many userids"},
12715   {SMBE_baduid, "Bad userid"},
12716   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
12717   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
12718   {SMBE_contMPX, "Resume MPX mode"},
12719   {SMBE_badPW, "Bad Password???"},
12720   {SMBE_nosupport, "Operation not supported"},
12721   { 0, NULL}
12722 };
12723
12724 /* Error codes for the ERRHRD class */
12725
12726 static const value_string HRD_errors[] = {
12727   {SMBE_nowrite, "Read only media"},
12728   {SMBE_badunit, "Unknown device"},
12729   {SMBE_notready, "Drive not ready"},
12730   {SMBE_badcmd, "Unknown command"},
12731   {SMBE_data, "Data (CRC) error"},
12732   {SMBE_badreq, "Bad request structure length"},
12733   {SMBE_seek, "Seek error???"},
12734   {SMBE_badmedia, "Bad media???"},
12735   {SMBE_badsector, "Bad sector???"},
12736   {SMBE_nopaper, "No paper in printer???"},
12737   {SMBE_write, "Write error???"},
12738   {SMBE_read, "Read error???"},
12739   {SMBE_general, "General error???"},
12740   {SMBE_badshare, "A open conflicts with an existing open"},
12741   {SMBE_lock, "Lock/unlock error"},
12742   {SMBE_wrongdisk,  "Wrong disk???"},
12743   {SMBE_FCBunavail, "FCB unavailable???"},
12744   {SMBE_sharebufexc, "Share buffer excluded???"},
12745   {SMBE_diskfull, "Disk full???"},
12746   {0, NULL}
12747 };
12748
12749 static char *decode_smb_error(guint8 errcls, guint16 errcode)
12750 {
12751
12752   switch (errcls) {
12753
12754   case SMB_SUCCESS:
12755
12756     return("No Error");   /* No error ??? */
12757     break;
12758
12759   case SMB_ERRDOS:
12760
12761     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
12762     break;
12763
12764   case SMB_ERRSRV:
12765
12766     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
12767     break;
12768
12769   case SMB_ERRHRD:
12770
12771     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
12772     break;
12773
12774   default:
12775
12776     return("Unknown error class!");
12777
12778   }
12779
12780 }
12781
12782 /*
12783  * NT error codes.
12784  *
12785  * From
12786  *
12787  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
12788  */
12789 const value_string NT_errors[] = {
12790   { 0x00000000, "STATUS_SUCCESS" },
12791   { 0x00000000, "STATUS_WAIT_0" },
12792   { 0x00000001, "STATUS_WAIT_1" },
12793   { 0x00000002, "STATUS_WAIT_2" },
12794   { 0x00000003, "STATUS_WAIT_3" },
12795   { 0x0000003F, "STATUS_WAIT_63" },
12796   { 0x00000080, "STATUS_ABANDONED" },
12797   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
12798   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
12799   { 0x000000C0, "STATUS_USER_APC" },
12800   { 0x00000100, "STATUS_KERNEL_APC" },
12801   { 0x00000101, "STATUS_ALERTED" },
12802   { 0x00000102, "STATUS_TIMEOUT" },
12803   { 0x00000103, "STATUS_PENDING" },
12804   { 0x00000104, "STATUS_REPARSE" },
12805   { 0x00000105, "STATUS_MORE_ENTRIES" },
12806   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
12807   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
12808   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
12809   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
12810   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
12811   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
12812   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
12813   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
12814   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
12815   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
12816   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
12817   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
12818   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
12819   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
12820   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
12821   { 0x00000116, "STATUS_CRASH_DUMP" },
12822   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
12823   { 0x00000118, "STATUS_REPARSE_OBJECT" },
12824   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
12825   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
12826   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
12827   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
12828   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
12829   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
12830   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
12831   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
12832   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
12833   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
12834   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
12835   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
12836   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
12837   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
12838   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
12839   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
12840   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
12841   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
12842   { 0x40000012, "STATUS_EVENT_DONE" },
12843   { 0x40000013, "STATUS_EVENT_PENDING" },
12844   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
12845   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
12846   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
12847   { 0x40000017, "STATUS_WAS_UNLOCKED" },
12848   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
12849   { 0x40000019, "STATUS_WAS_LOCKED" },
12850   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
12851   { 0x4000001B, "STATUS_ALREADY_WIN32" },
12852   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
12853   { 0x4000001D, "STATUS_WX86_CONTINUE" },
12854   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
12855   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
12856   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
12857   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
12858   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
12859   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
12860   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
12861   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
12862   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
12863   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
12864   { 0x80000003, "STATUS_BREAKPOINT" },
12865   { 0x80000004, "STATUS_SINGLE_STEP" },
12866   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
12867   { 0x80000006, "STATUS_NO_MORE_FILES" },
12868   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
12869   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
12870   { 0x8000000B, "STATUS_NO_INHERITANCE" },
12871   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
12872   { 0x8000000D, "STATUS_PARTIAL_COPY" },
12873   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
12874   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
12875   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
12876   { 0x80000011, "STATUS_DEVICE_BUSY" },
12877   { 0x80000012, "STATUS_NO_MORE_EAS" },
12878   { 0x80000013, "STATUS_INVALID_EA_NAME" },
12879   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
12880   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
12881   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
12882   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
12883   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
12884   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
12885   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
12886   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
12887   { 0x8000001D, "STATUS_BUS_RESET" },
12888   { 0x8000001E, "STATUS_END_OF_MEDIA" },
12889   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
12890   { 0x80000020, "STATUS_MEDIA_CHECK" },
12891   { 0x80000021, "STATUS_SETMARK_DETECTED" },
12892   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
12893   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
12894   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
12895   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
12896   { 0x80000026, "STATUS_LONGJUMP" },
12897   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
12898   { 0x80090301, "SEC_E_INVALID_HANDLE" },
12899   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
12900   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
12901   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
12902   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
12903   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
12904   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
12905   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
12906   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
12907   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
12908   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
12909   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
12910   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
12911   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
12912   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
12913   { 0xC0000008, "STATUS_INVALID_HANDLE" },
12914   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
12915   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
12916   { 0xC000000B, "STATUS_INVALID_CID" },
12917   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
12918   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
12919   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
12920   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
12921   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
12922   { 0xC0000011, "STATUS_END_OF_FILE" },
12923   { 0xC0000012, "STATUS_WRONG_VOLUME" },
12924   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
12925   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
12926   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
12927   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
12928   { 0xC0000017, "STATUS_NO_MEMORY" },
12929   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
12930   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
12931   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
12932   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
12933   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
12934   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
12935   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
12936   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
12937   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
12938   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
12939   { 0xC0000022, "STATUS_ACCESS_DENIED" },
12940   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
12941   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
12942   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
12943   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
12944   { 0xC0000027, "STATUS_UNWIND" },
12945   { 0xC0000028, "STATUS_BAD_STACK" },
12946   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
12947   { 0xC000002A, "STATUS_NOT_LOCKED" },
12948   { 0xC000002B, "STATUS_PARITY_ERROR" },
12949   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
12950   { 0xC000002D, "STATUS_NOT_COMMITTED" },
12951   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
12952   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
12953   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
12954   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
12955   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
12956   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
12957   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
12958   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
12959   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
12960   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
12961   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
12962   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
12963   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
12964   { 0xC000003C, "STATUS_DATA_OVERRUN" },
12965   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
12966   { 0xC000003E, "STATUS_DATA_ERROR" },
12967   { 0xC000003F, "STATUS_CRC_ERROR" },
12968   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
12969   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
12970   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
12971   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
12972   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
12973   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
12974   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
12975   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
12976   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
12977   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
12978   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
12979   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
12980   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
12981   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
12982   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
12983   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
12984   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
12985   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
12986   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
12987   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
12988   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
12989   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
12990   { 0xC0000056, "STATUS_DELETE_PENDING" },
12991   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
12992   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
12993   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
12994   { 0xC000005A, "STATUS_INVALID_OWNER" },
12995   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
12996   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
12997   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
12998   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
12999   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
13000   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
13001   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
13002   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
13003   { 0xC0000063, "STATUS_USER_EXISTS" },
13004   { 0xC0000064, "STATUS_NO_SUCH_USER" },
13005   { 0xC0000065, "STATUS_GROUP_EXISTS" },
13006   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
13007   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
13008   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
13009   { 0xC0000069, "STATUS_LAST_ADMIN" },
13010   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
13011   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
13012   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
13013   { 0xC000006D, "STATUS_LOGON_FAILURE" },
13014   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
13015   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
13016   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
13017   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
13018   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
13019   { 0xC0000073, "STATUS_NONE_MAPPED" },
13020   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
13021   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
13022   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
13023   { 0xC0000077, "STATUS_INVALID_ACL" },
13024   { 0xC0000078, "STATUS_INVALID_SID" },
13025   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
13026   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
13027   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
13028   { 0xC000007C, "STATUS_NO_TOKEN" },
13029   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
13030   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
13031   { 0xC000007F, "STATUS_DISK_FULL" },
13032   { 0xC0000080, "STATUS_SERVER_DISABLED" },
13033   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
13034   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
13035   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
13036   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
13037   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
13038   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
13039   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
13040   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
13041   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
13042   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
13043   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
13044   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
13045   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
13046   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
13047   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
13048   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
13049   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
13050   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
13051   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
13052   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
13053   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
13054   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
13055   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
13056   { 0xC0000098, "STATUS_FILE_INVALID" },
13057   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
13058   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
13059   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
13060   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
13061   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
13062   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
13063   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
13064   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
13065   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
13066   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
13067   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
13068   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
13069   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
13070   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
13071   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
13072   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
13073   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
13074   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
13075   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
13076   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
13077   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
13078   { 0xC00000AE, "STATUS_PIPE_BUSY" },
13079   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
13080   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
13081   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
13082   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
13083   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
13084   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
13085   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
13086   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
13087   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
13088   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
13089   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
13090   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
13091   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
13092   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
13093   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
13094   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
13095   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
13096   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
13097   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
13098   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
13099   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
13100   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
13101   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
13102   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
13103   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
13104   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
13105   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
13106   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
13107   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
13108   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
13109   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
13110   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
13111   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
13112   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
13113   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
13114   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
13115   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
13116   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
13117   { 0xC00000D5, "STATUS_FILE_RENAMED" },
13118   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
13119   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
13120   { 0xC00000D8, "STATUS_CANT_WAIT" },
13121   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
13122   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
13123   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
13124   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
13125   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
13126   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
13127   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
13128   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
13129   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
13130   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
13131   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
13132   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
13133   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
13134   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
13135   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
13136   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
13137   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
13138   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
13139   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
13140   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
13141   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
13142   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
13143   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
13144   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
13145   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
13146   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
13147   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
13148   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
13149   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
13150   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
13151   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
13152   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
13153   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
13154   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
13155   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
13156   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
13157   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
13158   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
13159   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
13160   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
13161   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
13162   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
13163   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
13164   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
13165   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
13166   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
13167   { 0xC0000107, "STATUS_FILES_OPEN" },
13168   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
13169   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
13170   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
13171   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
13172   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
13173   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
13174   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
13175   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
13176   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
13177   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
13178   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
13179   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
13180   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
13181   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
13182   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
13183   { 0xC0000117, "STATUS_NO_LDT" },
13184   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
13185   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
13186   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
13187   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
13188   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
13189   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
13190   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
13191   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
13192   { 0xC0000120, "STATUS_CANCELLED" },
13193   { 0xC0000121, "STATUS_CANNOT_DELETE" },
13194   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
13195   { 0xC0000123, "STATUS_FILE_DELETED" },
13196   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
13197   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
13198   { 0xC0000126, "STATUS_SPECIAL_USER" },
13199   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
13200   { 0xC0000128, "STATUS_FILE_CLOSED" },
13201   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
13202   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
13203   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
13204   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
13205   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
13206   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
13207   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
13208   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
13209   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
13210   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
13211   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
13212   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
13213   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
13214   { 0xC0000136, "STATUS_OPEN_FAILED" },
13215   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
13216   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
13217   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
13218   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
13219   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
13220   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
13221   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
13222   { 0xC000013E, "STATUS_LINK_FAILED" },
13223   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
13224   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
13225   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
13226   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
13227   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
13228   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
13229   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
13230   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
13231   { 0xC0000147, "STATUS_NO_PAGEFILE" },
13232   { 0xC0000148, "STATUS_INVALID_LEVEL" },
13233   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
13234   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
13235   { 0xC000014B, "STATUS_PIPE_BROKEN" },
13236   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
13237   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
13238   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
13239   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
13240   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
13241   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
13242   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
13243   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
13244   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
13245   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
13246   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
13247   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
13248   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
13249   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
13250   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
13251   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
13252   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
13253   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
13254   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
13255   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
13256   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
13257   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
13258   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
13259   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
13260   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
13261   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
13262   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
13263   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
13264   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
13265   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
13266   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
13267   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
13268   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
13269   { 0xC000016D, "STATUS_FT_ORPHANING" },
13270   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
13271   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
13272   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
13273   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
13274   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
13275   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
13276   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
13277   { 0xC0000178, "STATUS_NO_MEDIA" },
13278   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
13279   { 0xC000017B, "STATUS_INVALID_MEMBER" },
13280   { 0xC000017C, "STATUS_KEY_DELETED" },
13281   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
13282   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
13283   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
13284   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
13285   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
13286   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
13287   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
13288   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
13289   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
13290   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
13291   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
13292   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
13293   { 0xC0000189, "STATUS_TOO_LATE" },
13294   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
13295   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
13296   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
13297   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
13298   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
13299   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
13300   { 0xC0000190, "STATUS_TRUST_FAILURE" },
13301   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
13302   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
13303   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
13304   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
13305   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
13306   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
13307   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
13308   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
13309   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
13310   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
13311   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
13312   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
13313   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
13314   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
13315   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
13316   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
13317   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
13318   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
13319   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
13320   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
13321   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
13322   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
13323   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
13324   { 0xC000020D, "STATUS_CONNECTION_RESET" },
13325   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
13326   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
13327   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
13328   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
13329   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
13330   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
13331   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
13332   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
13333   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
13334   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
13335   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
13336   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
13337   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
13338   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
13339   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
13340   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
13341   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
13342   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
13343   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
13344   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
13345   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
13346   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
13347   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
13348   { 0xC0000225, "STATUS_NOT_FOUND" },
13349   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
13350   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
13351   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
13352   { 0xC0000229, "STATUS_FAIL_CHECK" },
13353   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
13354   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
13355   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
13356   { 0xC000022D, "STATUS_RETRY" },
13357   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
13358   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
13359   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
13360   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
13361   { 0xC0000232, "STATUS_INVALID_VARIANT" },
13362   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
13363   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
13364   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
13365   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
13366   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
13367   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
13368   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
13369   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
13370   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
13371   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
13372   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
13373   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
13374   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
13375   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
13376   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
13377   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
13378   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
13379   { 0xC0000244, "STATUS_AUDIT_FAILED" },
13380   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
13381   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
13382   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
13383   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
13384   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
13385   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
13386   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
13387   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
13388   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
13389   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
13390   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
13391   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
13392   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
13393   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
13394   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
13395   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
13396   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
13397   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
13398   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
13399   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
13400   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
13401   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
13402   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
13403   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
13404   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
13405   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
13406   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
13407   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
13408   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
13409   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
13410   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
13411   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
13412   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
13413   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
13414   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
13415   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
13416   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
13417   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
13418   { 0xC0000272, "STATUS_NO_MATCH" },
13419   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
13420   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
13421   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
13422   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
13423   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
13424   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
13425   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
13426   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
13427   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
13428   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
13429   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
13430   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
13431   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
13432   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
13433   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
13434   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
13435   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
13436   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
13437   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
13438   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
13439   { 0xC000028E, "STATUS_NO_EFS" },
13440   { 0xC000028F, "STATUS_WRONG_EFS" },
13441   { 0xC0000290, "STATUS_NO_USER_KEYS" },
13442   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
13443   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
13444   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
13445   { 0x40000294, "STATUS_WAKE_SYSTEM" },
13446   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
13447   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
13448   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
13449   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
13450   { 0xC0000299, "STATUS_SHARED_POLICY" },
13451   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
13452   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
13453   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
13454   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
13455   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
13456   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
13457   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
13458   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
13459   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
13460   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
13461   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
13462   { 0xC00002A5, "STATUS_DS_BUSY" },
13463   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
13464   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
13465   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
13466   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
13467   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
13468   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
13469   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
13470   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
13471   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
13472   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
13473   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
13474   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
13475   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
13476   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
13477   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
13478   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
13479   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
13480   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
13481   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
13482   { 0xC00002B9, "STATUS_NOINTERFACE" },
13483   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
13484   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
13485   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
13486   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
13487   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
13488   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
13489   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
13490   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
13491   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
13492   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
13493   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
13494   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
13495   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
13496   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
13497   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
13498   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
13499   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
13500   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
13501   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
13502   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
13503   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
13504   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
13505   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
13506   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
13507   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
13508   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
13509   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
13510   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
13511   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
13512   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
13513   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
13514   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
13515   { 0xC00002E1, "STATUS_DS_CANT_START" },
13516   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
13517   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
13518   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
13519   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
13520   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
13521   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
13522   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
13523   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
13524   { 0xC0009898, "STATUS_WOW_ASSERTION" },
13525   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
13526   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
13527   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
13528   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
13529   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
13530   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
13531   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
13532   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
13533   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
13534   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
13535   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
13536   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
13537   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
13538   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
13539   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
13540   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
13541   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
13542   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
13543   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
13544   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
13545   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
13546   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
13547   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
13548   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
13549   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
13550   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
13551   { 0xC002001B, "RPC_NT_CALL_FAILED" },
13552   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
13553   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
13554   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
13555   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
13556   { 0xC0020022, "RPC_NT_INVALID_TAG" },
13557   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
13558   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
13559   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
13560   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
13561   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
13562   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
13563   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
13564   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
13565   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
13566   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
13567   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
13568   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
13569   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
13570   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
13571   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
13572   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
13573   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
13574   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
13575   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
13576   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
13577   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
13578   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
13579   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
13580   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
13581   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
13582   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
13583   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
13584   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
13585   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
13586   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
13587   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
13588   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
13589   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
13590   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
13591   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
13592   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
13593   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
13594   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
13595   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
13596   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
13597   { 0xC002100A, "RPC_P_SEND_FAILED" },
13598   { 0xC002100B, "RPC_P_TIMEOUT" },
13599   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
13600   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
13601   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
13602   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
13603   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
13604   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
13605   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
13606   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
13607   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
13608   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
13609   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
13610   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
13611   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
13612   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
13613   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
13614   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
13615   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
13616   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
13617   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
13618   { 0xC002004C, "EPT_NT_CANT_CREATE" },
13619   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
13620   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
13621   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
13622   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
13623   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
13624   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
13625   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
13626   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
13627   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
13628   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
13629   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
13630   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
13631   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
13632   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
13633   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
13634   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
13635   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
13636   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
13637   { 0,          NULL }
13638 };
13639
13640
13641
13642 static const true_false_string tfs_smb_flags_lock = {
13643         "Lock&Read, Write&Unlock are supported",
13644         "Lock&Read, Write&Unlock are not supported"
13645 };
13646 static const true_false_string tfs_smb_flags_receive_buffer = {
13647         "Receive buffer has been posted",
13648         "Receive buffer has not been posted"
13649 };
13650 static const true_false_string tfs_smb_flags_caseless = {
13651         "Path names are caseless",
13652         "Path names are case sensitive"
13653 };
13654 static const true_false_string tfs_smb_flags_canon = {
13655         "Pathnames are canonicalized",
13656         "Pathnames are not canonicalized"
13657 };
13658 static const true_false_string tfs_smb_flags_oplock = {
13659         "OpLock requested/granted",
13660         "OpLock not requested/granted"
13661 };
13662 static const true_false_string tfs_smb_flags_notify = {
13663         "Notify client on all modifications",
13664         "Notify client only on open"
13665 };
13666 static const true_false_string tfs_smb_flags_response = {
13667         "Message is a response to the client/redirector",
13668         "Message is a request to the server"
13669 };
13670
13671 static int
13672 dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
13673 {
13674         guint8 mask;
13675         proto_item *item = NULL;
13676         proto_tree *tree = NULL;
13677
13678         mask = tvb_get_guint8(tvb, offset);
13679
13680         if(parent_tree){
13681                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
13682                         "Flags: 0x%02x", mask);
13683                 tree = proto_item_add_subtree(item, ett_smb_flags);
13684         }
13685         proto_tree_add_boolean(tree, hf_smb_flags_response,
13686                 tvb, offset, 1, mask);
13687         proto_tree_add_boolean(tree, hf_smb_flags_notify,
13688                 tvb, offset, 1, mask);
13689         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
13690                 tvb, offset, 1, mask);
13691         proto_tree_add_boolean(tree, hf_smb_flags_canon,
13692                 tvb, offset, 1, mask);
13693         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
13694                 tvb, offset, 1, mask);
13695         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
13696                 tvb, offset, 1, mask);
13697         proto_tree_add_boolean(tree, hf_smb_flags_lock,
13698                 tvb, offset, 1, mask);
13699         offset += 1;
13700         return offset;
13701 }
13702
13703
13704  
13705 static const true_false_string tfs_smb_flags2_long_names_allowed = {
13706         "Long file names are allowed in the response",
13707         "Long file names are not allowed in the response"
13708 };
13709 static const true_false_string tfs_smb_flags2_ea = {
13710         "Extended attributes are supported",
13711         "Extended attributes are not supported"
13712 };
13713 static const true_false_string tfs_smb_flags2_sec_sig = {
13714         "Security signatures are supported",
13715         "Security signatures are not supported"
13716 };
13717 static const true_false_string tfs_smb_flags2_long_names_used = {
13718         "Path names in request are long file names",
13719         "Path names in request are not long file names"
13720 };
13721 static const true_false_string tfs_smb_flags2_esn = {
13722         "Extended security negotiation is supported",
13723         "Extended security negotiation is not supported"
13724 };
13725 static const true_false_string tfs_smb_flags2_dfs = {
13726         "Resolve pathnames with Dfs",
13727         "Don't resolve pathnames with Dfs"
13728 };
13729 static const true_false_string tfs_smb_flags2_roe = {
13730         "Permit reads if execute-only",
13731         "Don't permit reads if execute-only"
13732 };
13733 static const true_false_string tfs_smb_flags2_nt_error = {
13734         "Error codes are NT error codes",
13735         "Error codes are DOS error codes"
13736 };
13737 static const true_false_string tfs_smb_flags2_string = {
13738         "Strings are Unicode",
13739         "Strings are ASCII"
13740 };
13741 static int
13742 dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
13743 {
13744         guint16 mask;
13745         proto_item *item = NULL;
13746         proto_tree *tree = NULL;
13747
13748         mask = tvb_get_letohs(tvb, offset);
13749
13750         if(parent_tree){
13751                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
13752                         "Flags2: 0x%04x", mask);
13753                 tree = proto_item_add_subtree(item, ett_smb_flags2);
13754         }
13755
13756         proto_tree_add_boolean(tree, hf_smb_flags2_string,
13757                 tvb, offset, 2, mask);
13758         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
13759                 tvb, offset, 2, mask);
13760         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
13761                 tvb, offset, 2, mask);
13762         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
13763                 tvb, offset, 2, mask);
13764         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
13765                 tvb, offset, 2, mask);
13766         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
13767                 tvb, offset, 2, mask);
13768         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
13769                 tvb, offset, 2, mask);
13770         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
13771                 tvb, offset, 2, mask);
13772         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
13773                 tvb, offset, 2, mask);
13774
13775         offset += 2;
13776         return offset;
13777 }
13778
13779
13780
13781 #define SMB_FLAGS_DIRN 0x80
13782
13783
13784 static gboolean
13785 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13786 {
13787         int offset = 0;
13788         proto_item *item = NULL, *hitem = NULL;
13789         proto_tree *tree = NULL, *htree = NULL;
13790         guint8          flags;
13791         guint16         flags2;
13792         smb_info_t      si;
13793         smb_saved_info_t *sip = NULL;
13794         smb_saved_info_key_t key;
13795         smb_saved_info_key_t *new_key;
13796         guint32 nt_status = 0;
13797         guint8 errclass = 0;
13798         guint16 errcode = 0;
13799         guint16 uid, pid, tid, mid;
13800         guint32 pid_mid;
13801         conversation_t *conversation;
13802
13803         top_tree=parent_tree;
13804
13805         /* must check that this really is a smb packet */
13806         if (!tvb_bytes_exist(tvb, 0, 4))
13807                 return FALSE;
13808
13809         if( (tvb_get_guint8(tvb, 0) != 0xff)
13810             || (tvb_get_guint8(tvb, 1) != 'S')
13811             || (tvb_get_guint8(tvb, 2) != 'M')
13812             || (tvb_get_guint8(tvb, 3) != 'B') ){
13813                 return FALSE;
13814         }
13815          
13816         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
13817                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
13818         }
13819         if (check_col(pinfo->cinfo, COL_INFO)){
13820                 col_clear(pinfo->cinfo, COL_INFO);
13821         }
13822
13823         /* start off using the local variable, we will allocate a new one if we
13824            need to*/
13825         si.cmd = tvb_get_guint8(tvb, offset+4);
13826         flags = tvb_get_guint8(tvb, offset+9);
13827         si.request = !(flags&SMB_FLAGS_DIRN);
13828         flags2 = tvb_get_letohs(tvb, offset+10);
13829         if(flags2 & 0x8000){
13830                 si.unicode = TRUE; /* Mark them as Unicode */
13831         } else {
13832                 si.unicode = FALSE;
13833         }
13834         tid = tvb_get_letohs(tvb, offset+24);
13835         pid = tvb_get_letohs(tvb, offset+26);
13836         uid = tvb_get_letohs(tvb, offset+28);
13837         mid = tvb_get_letohs(tvb, offset+30);
13838         pid_mid = (pid << 16) | mid;
13839         si.info_level = -1;
13840         si.info_count = -1;
13841
13842         if (parent_tree) {
13843                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
13844                         -1, FALSE);
13845                 tree = proto_item_add_subtree(item, ett_smb);
13846
13847                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
13848                         "SMB Header");
13849
13850                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
13851         }
13852
13853         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
13854         offset += 4;  /* Skip the marker */
13855
13856         /* find which conversation we are part of and get the tables for that 
13857            conversation*/
13858         conversation = find_conversation(&pinfo->src, &pinfo->dst,
13859                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
13860         if(conversation){
13861                 si.ct=conversation_get_proto_data(conversation, proto_smb);
13862         } else {
13863                 /* OK this is a new conversation, we must create it
13864                    and attach appropriate data (matched and unmatched 
13865                    table for this conversation)
13866                 */
13867                 conversation = conversation_new(&pinfo->src, &pinfo->dst, 
13868                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
13869                 si.ct = g_mem_chunk_alloc(conv_tables_chunk);
13870                 conv_tables = g_slist_prepend(conv_tables, si.ct);
13871                 si.ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
13872                         smb_saved_info_equal_matched);
13873                 si.ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched, 
13874                         smb_saved_info_equal_unmatched);
13875                 si.ct->dcerpc_fid_to_frame=g_hash_table_new(
13876                         smb_saved_info_hash_unmatched, 
13877                         smb_saved_info_equal_unmatched);
13878                 conversation_add_proto_data(conversation, proto_smb, si.ct);
13879         }
13880
13881         if( (si.request)
13882             &&  (mid==0)
13883             &&  (uid==0)
13884             &&  (pid==0)
13885             &&  (tid==0) ){
13886                 /* this is a broadcast SMB packet, there will not be a reply.
13887                    We dont need to do anything 
13888                 */
13889                 si.unidir = TRUE;
13890         } else if( (si.cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
13891                    ||(si.cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
13892                    ||(si.cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
13893                    ||(si.cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
13894                 /* Ok, we got a special request type. This request is either
13895                    an NT Cancel or a continuation relative to a real request
13896                    in an earlier packet.  In either case, we don't expect any
13897                    responses to this packet.  For continuations, any later
13898                    responses we see really just belong to the original request.
13899                    Anyway, we want to remember this packet somehow and
13900                    remember which original request it is associated with so
13901                    we can say nice things such as "This is a Cancellation to
13902                    the request in frame x", but we don't want the
13903                    request/response matching to get messed up.
13904
13905                    The only thing we do in this case is trying to find which original
13906                    request we match with and insert an entry for this "special" 
13907                    request for later reference. We continue to reference the original
13908                    requests smb_saved_info_t but we dont touch it or change anything
13909                    in it.
13910                 */
13911
13912                 si.unidir = TRUE;  /*we dont expect an answer to this one*/
13913
13914                 if(!pinfo->fd->flags.visited){
13915                         /* try to find which original call we match and if we 
13916                            find it add us to the matched table. Dont touch
13917                            anything else since we dont want this one to mess
13918                            up the request/response matching. We still consider
13919                            the initial call the real request and this is only
13920                            some sort of continuation.
13921                         */
13922                         /* we only check the unmatched table and assume that the
13923                            last seen MID matching ours is the right one.
13924                            This can fail but is better than nothing
13925                         */
13926                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
13927                         if(sip!=NULL){
13928                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
13929                                 new_key->frame = pinfo->fd->num;
13930                                 new_key->pid_mid = pid_mid;
13931                                 g_hash_table_insert(si.ct->matched, new_key,
13932                                     sip);
13933                         }
13934                 } else {
13935                         /* we have seen this packet before; check the
13936                            matching table
13937                         */
13938                         key.frame = pinfo->fd->num;
13939                         key.pid_mid = pid_mid;
13940                         sip=g_hash_table_lookup(si.ct->matched, &key);
13941                         if(sip==NULL){
13942                         /*
13943                           We didn't find it.
13944                           Too bad, unfortunately there is not really much we can
13945                           do now since this means that we never saw the initial
13946                           request.
13947                          */
13948                         }
13949                 }
13950
13951
13952                 if(sip && sip->frame_req){
13953                         switch(si.cmd){
13954                         case SMB_COM_NT_CANCEL:
13955                                 proto_tree_add_uint(htree, hf_smb_cancel_to, 
13956                                                     tvb, 0, 0, sip->frame_req);
13957                                 break;
13958                         case SMB_COM_TRANSACTION_SECONDARY:
13959                         case SMB_COM_TRANSACTION2_SECONDARY:
13960                         case SMB_COM_NT_TRANSACT_SECONDARY:
13961                                 proto_tree_add_uint(htree, hf_smb_continuation_to, 
13962                                                     tvb, 0, 0, sip->frame_req);
13963                                 break;
13964                         }
13965                 } else {
13966                         switch(si.cmd){
13967                         case SMB_COM_NT_CANCEL:
13968                                 proto_tree_add_text(htree, tvb, 0, 0,
13969                                                     "Cancellation to: <unknown frame>");
13970                                 break;
13971                         case SMB_COM_TRANSACTION_SECONDARY:
13972                         case SMB_COM_TRANSACTION2_SECONDARY:
13973                         case SMB_COM_NT_TRANSACT_SECONDARY:
13974                                 proto_tree_add_text(htree, tvb, 0, 0,
13975                                                     "Continuation to: <unknown frame>");
13976                                 break;
13977                         }
13978                 }
13979         } else { /* normal bidirectional request or response */
13980                 si.unidir = FALSE;
13981
13982                 if(!pinfo->fd->flags.visited){
13983                         /* first see if we find an unmatched smb "equal" to 
13984                            the current one 
13985                         */
13986                         sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
13987                         if(sip!=NULL){
13988                                 gboolean cmd_match=FALSE;
13989
13990                                 /*
13991                                  * Make sure the SMB we found was the
13992                                  * same command, or a different command
13993                                  * that's another valid type of reply
13994                                  * to that command.
13995                                  */
13996                                 if(si.cmd==sip->cmd){
13997                                         cmd_match=TRUE;
13998                                 }
13999                                 else if(si.cmd==SMB_COM_NT_CANCEL){
14000                                         cmd_match=TRUE;
14001                                 }
14002                                 else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
14003                                      && (sip->cmd==SMB_COM_TRANSACTION)){
14004                                         cmd_match=TRUE;
14005                                 }
14006                                 else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
14007                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
14008                                         cmd_match=TRUE;
14009                                 }
14010                                 else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
14011                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
14012                                         cmd_match=TRUE;
14013                                 }
14014
14015                                 if( (si.request) || (!cmd_match) ) {
14016                                         /* If we are processing an SMB request but there was already
14017                                            another "identical" smb resuest we had not matched yet.
14018                                            This must mean that either we have a retransmission or that the
14019                                            response to the previous one was lost and the client has reused
14020                                            the MID for this conversation. In either case it's not much more
14021                                            we can do than forget the old request and concentrate on the 
14022                                            present one instead.
14023
14024                                            We also do this cleanup if we see that the cmd in the original
14025                                            request in sip->cmd is not compatible with the current cmd.
14026                                            This is to prevent matching errors such as if there were two
14027                                            SMBs of different cmds but with identical MID and PID values and
14028                                            if ethereal lost the first reply and the second request.
14029                                         */
14030                                         g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
14031                                         sip=NULL; /* XXX should free it as well */
14032                                 } else {
14033                                         /* we have found a response to some request we have seen earlier.
14034                                            What we do now depends on whether this is the first response
14035                                            to that request we see (id frame_res==0) or not. 
14036                                         */
14037                                         if(sip->frame_res==0){
14038                                                 /* ok it is the first response we have seen to this packet */
14039                                                 sip->frame_res = pinfo->fd->num;
14040                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14041                                                 new_key->frame = sip->frame_req;
14042                                                 new_key->pid_mid = pid_mid;
14043                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14044                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14045                                                 new_key->frame = sip->frame_res;
14046                                                 new_key->pid_mid = pid_mid;
14047                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14048                                         } else {
14049                                                 /* we have already seen another response to this one, but
14050                                                    register it anyway so we see which request it matches 
14051                                                 */
14052                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
14053                                                 new_key->frame = pinfo->fd->num;
14054                                                 new_key->pid_mid = pid_mid;
14055                                                 g_hash_table_insert(si.ct->matched, new_key, sip);
14056                                         }
14057                                 }
14058                         }
14059                         if(si.request){
14060                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
14061                                 sip->frame_req = pinfo->fd->num;
14062                                 sip->frame_res = 0;
14063                                 sip->cmd = si.cmd;
14064                                 sip->extra_info = NULL;
14065                                 g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
14066                         }
14067                 } else {
14068                         /* we have seen this packet before; check the
14069                            matching table.
14070                            If we haven't yet seen the reply, we won't
14071                            find the info for it; we don't need it, as
14072                            we only use it to save information, and, as
14073                            we've seen this packet before, we've already
14074                            saved the information.
14075                         */
14076                         key.frame = pinfo->fd->num;
14077                         key.pid_mid = pid_mid;
14078                         sip=g_hash_table_lookup(si.ct->matched, &key);
14079                 }
14080         }
14081
14082         /*
14083          * Pass the "sip" on to subdissectors through "si".
14084          */
14085         si.sip = sip;
14086
14087         if (sip != NULL) {
14088                 /*
14089                  * Put in fields for the frame number of the frame to which
14090                  * this is a response or the frame with the response to this
14091                  * frame - if we know the frame number (i.e., it's not 0).
14092                  */
14093                 if(si.request){
14094                         if (sip->frame_res != 0)
14095                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
14096                 } else {
14097                         if (sip->frame_req != 0)
14098                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
14099                 }
14100         }
14101
14102         /* smb command */
14103         proto_tree_add_uint_format(htree, hf_smb_cmd, tvb, offset, 1, si.cmd, "SMB Command: %s (0x%02x)", decode_smb_name(si.cmd), si.cmd);
14104         offset += 1;
14105
14106         if(flags2 & 0x4000){
14107                 /* handle NT 32 bit error code */
14108
14109                 nt_status = tvb_get_letohl(tvb, offset);
14110
14111                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
14112                         TRUE);
14113                 offset += 4;
14114
14115         } else {
14116                 /* handle DOS error code & class */
14117                 errclass = tvb_get_guint8(tvb, offset);
14118                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
14119                         errclass);
14120                 offset += 1;
14121
14122                 /* reserved byte */
14123                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
14124                 offset += 1;
14125
14126                 /* error code */
14127                 /* XXX - the type of this field depends on the value of
14128                  * "errcls", so there is isn't a single value_string array
14129                  * fo it, so there can't be a single field for it.
14130                  */
14131                 errcode = tvb_get_letohs(tvb, offset);
14132                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
14133                         offset, 2, errcode, "Error Code: %s",
14134                         decode_smb_error(errclass, errcode));
14135                 offset += 2;
14136         }
14137
14138         /* flags */
14139         offset = dissect_smb_flags(tvb, pinfo, htree, offset);
14140
14141         /* flags2 */
14142         offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
14143
14144         /*
14145          * The document at
14146          *
14147          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
14148          *
14149          * (a text version of "Microsoft Networks SMB FILE SHARING
14150          * PROTOCOL, Document Version 6.0p") says that:
14151          *
14152          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
14153          *      the "High Part of PID";
14154          *
14155          *      the next four bytes are reserved;
14156          *
14157          *      the next four bytes are, for SMB-over-IPX (with no
14158          *      NetBIOS involved) two bytes of Session ID and two bytes
14159          *      of SequenceNumber.
14160          *
14161          * If we ever implement SMB-over-IPX (which I suspect goes over
14162          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
14163          * document in question), we'd probably want to have some way
14164          * to determine whether this is SMB-over-IPX or not (which could
14165          * be done by adding a PT_IPXSOCKET port type, having the
14166          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
14167          * and having the SMB dissector check for a port type of
14168          * PT_IPXSOCKET and for "pinfo->match_port" being either
14169          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
14170          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
14171          */
14172
14173         /* 12 reserved bytes */
14174         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
14175         offset += 12;
14176
14177         /* TID */
14178         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
14179         offset += 2;
14180
14181         /* PID */
14182         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
14183         offset += 2;
14184
14185         /* UID */
14186         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
14187         offset += 2;
14188
14189         /* MID */
14190         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, mid);
14191         offset += 2;
14192
14193         pinfo->private_data = &si;
14194         dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
14195
14196         /* Append error info from this packet to info string. */
14197         if (!si.request && check_col(pinfo->cinfo, COL_INFO)) {
14198                 if (flags2 & 0x4000) {
14199                         /*
14200                          * The status is an NT status code; was there
14201                          * an error?
14202                          */
14203                         if (nt_status != 0) {
14204                                 /*
14205                                  * Yes.
14206                                  */
14207                                 col_append_fstr(
14208                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14209                                         val_to_str(nt_status, NT_errors,
14210                                             "Unknown (0x%08X)"));
14211                         }
14212                 } else {
14213                         /*
14214                          * The status is a DOS error class and code; was
14215                          * there an error?
14216                          */
14217                         if (errclass != SMB_SUCCESS) {
14218                                 /*
14219                                  * Yes.
14220                                  */
14221                                 col_append_fstr(
14222                                         pinfo->cinfo, COL_INFO, ", Error: %s",
14223                                         decode_smb_error(errclass, errcode));
14224                         }
14225                 }
14226         }
14227
14228         return TRUE;
14229 }
14230
14231 void
14232 proto_register_smb(void)
14233 {
14234         static hf_register_info hf[] = {
14235         { &hf_smb_cmd,
14236                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
14237                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
14238
14239         { &hf_smb_word_count,
14240                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
14241                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
14242
14243         { &hf_smb_byte_count,
14244                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
14245                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
14246
14247         { &hf_smb_response_to,
14248                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
14249                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
14250
14251         { &hf_smb_response_in,
14252                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
14253                 NULL, 0, "The response to this packet is in this packet", HFILL }},
14254
14255         { &hf_smb_continuation_to,
14256                 { "Continuation to", "smb.continuation_to", FT_UINT32, BASE_DEC,
14257                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
14258
14259         { &hf_smb_nt_status,
14260                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
14261                 VALS(NT_errors), 0, "NT Status code", HFILL }},
14262
14263         { &hf_smb_error_class,
14264                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
14265                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
14266
14267         { &hf_smb_error_code,
14268                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
14269                 NULL, 0, "DOS Error Code", HFILL }},
14270
14271         { &hf_smb_reserved,
14272                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
14273                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
14274
14275         { &hf_smb_pid,
14276                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
14277                 NULL, 0, "Process ID", HFILL }},
14278
14279         { &hf_smb_tid,
14280                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
14281                 NULL, 0, "Tree ID", HFILL }},
14282
14283         { &hf_smb_uid,
14284                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
14285                 NULL, 0, "User ID", HFILL }},
14286
14287         { &hf_smb_mid,
14288                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
14289                 NULL, 0, "Multiplex ID", HFILL }},
14290
14291         { &hf_smb_flags_lock,
14292                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
14293                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
14294
14295         { &hf_smb_flags_receive_buffer,
14296                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
14297                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
14298
14299         { &hf_smb_flags_caseless,
14300                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
14301                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
14302
14303         { &hf_smb_flags_canon,
14304                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
14305                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
14306
14307         { &hf_smb_flags_oplock,
14308                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
14309                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
14310
14311         { &hf_smb_flags_notify,
14312                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
14313                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
14314
14315         { &hf_smb_flags_response,
14316                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
14317                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
14318
14319         { &hf_smb_flags2_long_names_allowed,
14320                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
14321                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
14322
14323         { &hf_smb_flags2_ea,
14324                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
14325                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
14326
14327         { &hf_smb_flags2_sec_sig,
14328                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
14329                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
14330
14331         { &hf_smb_flags2_long_names_used,
14332                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
14333                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
14334
14335         { &hf_smb_flags2_esn,
14336                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
14337                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
14338
14339         { &hf_smb_flags2_dfs,
14340                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
14341                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
14342
14343         { &hf_smb_flags2_roe,
14344                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
14345                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
14346
14347         { &hf_smb_flags2_nt_error,
14348                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
14349                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
14350
14351         { &hf_smb_flags2_string,
14352                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
14353                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
14354
14355         { &hf_smb_buffer_format,
14356                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
14357                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
14358
14359         { &hf_smb_dialect_name,
14360                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
14361                 NULL, 0, "Name of dialect", HFILL }},
14362
14363         { &hf_smb_dialect_index,
14364                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
14365                 NULL, 0, "Index of selected dialect", HFILL }},
14366
14367         { &hf_smb_max_trans_buf_size,
14368                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
14369                 NULL, 0, "Maximum transmit buffer size", HFILL }},
14370
14371         { &hf_smb_max_mpx_count,
14372                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
14373                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
14374
14375         { &hf_smb_max_vcs_num,
14376                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
14377                 NULL, 0, "Maximum VCs between client and server", HFILL }},
14378
14379         { &hf_smb_session_key,
14380                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
14381                 NULL, 0, "Unique token identifying this session", HFILL }},
14382
14383         { &hf_smb_server_timezone,
14384                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
14385                 NULL, 0, "Current timezone at server.", HFILL }},
14386
14387         { &hf_smb_encryption_key_length,
14388                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
14389                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
14390
14391         { &hf_smb_encryption_key,
14392                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
14393                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
14394
14395         { &hf_smb_primary_domain,
14396                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
14397                 NULL, 0, "The server's primary domain", HFILL }},
14398
14399         { &hf_smb_max_raw_buf_size,
14400                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
14401                 NULL, 0, "Maximum raw buffer size", HFILL }},
14402
14403         { &hf_smb_server_guid,
14404                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
14405                 NULL, 0, "Globally unique identifier for this server", HFILL }},
14406
14407         { &hf_smb_security_blob_len,
14408                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
14409                 NULL, 0, "Security blob length", HFILL }},
14410
14411         { &hf_smb_security_blob,
14412                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
14413                 NULL, 0, "Security blob", HFILL }},
14414
14415         { &hf_smb_sm_mode16,
14416                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
14417                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
14418
14419         { &hf_smb_sm_password16,
14420                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
14421                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
14422
14423         { &hf_smb_sm_mode,
14424                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
14425                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
14426
14427         { &hf_smb_sm_password,
14428                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
14429                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
14430
14431         { &hf_smb_sm_signatures,
14432                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
14433                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
14434
14435         { &hf_smb_sm_sig_required,
14436                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
14437                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
14438
14439         { &hf_smb_rm_read,
14440                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
14441                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
14442
14443         { &hf_smb_rm_write,
14444                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
14445                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
14446
14447         { &hf_smb_server_date_time,
14448                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
14449                 NULL, 0, "Current date and time at server", HFILL }},
14450
14451         { &hf_smb_server_smb_date,
14452                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
14453                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
14454
14455         { &hf_smb_server_smb_time,
14456                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
14457                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
14458
14459         { &hf_smb_server_cap_raw_mode,
14460                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
14461                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
14462
14463         { &hf_smb_server_cap_mpx_mode,
14464                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
14465                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
14466
14467         { &hf_smb_server_cap_unicode,
14468                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
14469                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
14470
14471         { &hf_smb_server_cap_large_files,
14472                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
14473                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
14474
14475         { &hf_smb_server_cap_nt_smbs,
14476                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
14477                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
14478
14479         { &hf_smb_server_cap_rpc_remote_apis,
14480                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
14481                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
14482
14483         { &hf_smb_server_cap_nt_status,
14484                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
14485                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
14486
14487         { &hf_smb_server_cap_level_ii_oplocks,
14488                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
14489                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
14490
14491         { &hf_smb_server_cap_lock_and_read,
14492                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
14493                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
14494
14495         { &hf_smb_server_cap_nt_find,
14496                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
14497                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
14498
14499         { &hf_smb_server_cap_dfs,
14500                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
14501                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
14502
14503         { &hf_smb_server_cap_infolevel_passthru,
14504                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
14505                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
14506
14507         { &hf_smb_server_cap_large_readx,
14508                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
14509                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
14510
14511         { &hf_smb_server_cap_large_writex,
14512                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
14513                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
14514
14515         { &hf_smb_server_cap_unix,
14516                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
14517                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
14518
14519         { &hf_smb_server_cap_reserved,
14520                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
14521                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
14522
14523         { &hf_smb_server_cap_bulk_transfer,
14524                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
14525                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
14526
14527         { &hf_smb_server_cap_compressed_data,
14528                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
14529                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
14530
14531         { &hf_smb_server_cap_extended_security,
14532                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
14533                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
14534
14535         { &hf_smb_system_time,
14536                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
14537                 NULL, 0, "System Time", HFILL }},
14538
14539         { &hf_smb_unknown,
14540                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
14541                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
14542
14543         { &hf_smb_dir_name,
14544                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
14545                 NULL, 0, "SMB Directory Name", HFILL }},
14546
14547         { &hf_smb_echo_count,
14548                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
14549                 NULL, 0, "Number of times to echo data back", HFILL }},
14550
14551         { &hf_smb_echo_data,
14552                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
14553                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
14554
14555         { &hf_smb_echo_seq_num,
14556                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
14557                 NULL, 0, "Sequence number for this echo response", HFILL }},
14558
14559         { &hf_smb_max_buf_size,
14560                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
14561                 NULL, 0, "Max client buffer size", HFILL }},
14562
14563         { &hf_smb_path,
14564                 { "Path", "smb.path", FT_STRING, BASE_NONE,
14565                 NULL, 0, "Path. Server name and share name", HFILL }},
14566
14567         { &hf_smb_service,
14568                 { "Service", "smb.service", FT_STRING, BASE_NONE,
14569                 NULL, 0, "Service name", HFILL }},
14570
14571         { &hf_smb_password,
14572                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
14573                 NULL, 0, "Password", HFILL }},
14574
14575         { &hf_smb_ansi_password,
14576                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
14577                 NULL, 0, "ANSI Password", HFILL }},
14578
14579         { &hf_smb_unicode_password,
14580                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
14581                 NULL, 0, "Unicode Password", HFILL }},
14582
14583         { &hf_smb_move_flags_file,
14584                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
14585                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
14586
14587         { &hf_smb_move_flags_dir,
14588                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
14589                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
14590
14591         { &hf_smb_move_flags_verify,
14592                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
14593                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
14594
14595         { &hf_smb_move_files_moved,
14596                 { "Files Moved", "smb.move.files_moved", FT_UINT16, BASE_DEC,
14597                 NULL, 0, "Number of files moved", HFILL }},
14598
14599         { &hf_smb_count,
14600                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
14601                 NULL, 0, "Count number of items/bytes", HFILL }},
14602
14603         { &hf_smb_file_name,
14604                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
14605                 NULL, 0, "File Name", HFILL }},
14606
14607         { &hf_smb_open_function_create,
14608                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
14609                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
14610
14611         { &hf_smb_open_function_open,
14612                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
14613                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
14614
14615         { &hf_smb_fid,
14616                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
14617                 NULL, 0, "FID: File ID", HFILL }},
14618
14619         { &hf_smb_file_attr_read_only_16bit,
14620                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
14621                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
14622
14623         { &hf_smb_file_attr_read_only_8bit,
14624                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
14625                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
14626
14627         { &hf_smb_file_attr_hidden_16bit,
14628                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
14629                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
14630
14631         { &hf_smb_file_attr_hidden_8bit,
14632                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
14633                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
14634
14635         { &hf_smb_file_attr_system_16bit,
14636                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
14637                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
14638
14639         { &hf_smb_file_attr_system_8bit,
14640                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
14641                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
14642
14643         { &hf_smb_file_attr_volume_16bit,
14644                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
14645                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
14646
14647         { &hf_smb_file_attr_volume_8bit,
14648                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
14649                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
14650
14651         { &hf_smb_file_attr_directory_16bit,
14652                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
14653                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
14654
14655         { &hf_smb_file_attr_directory_8bit,
14656                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
14657                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
14658
14659         { &hf_smb_file_attr_archive_16bit,
14660                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
14661                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
14662
14663         { &hf_smb_file_attr_archive_8bit,
14664                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
14665                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
14666
14667         { &hf_smb_file_attr_device,
14668                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
14669                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
14670
14671         { &hf_smb_file_attr_normal,
14672                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
14673                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
14674
14675         { &hf_smb_file_attr_temporary,
14676                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
14677                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
14678
14679         { &hf_smb_file_attr_sparse,
14680                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
14681                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
14682
14683         { &hf_smb_file_attr_reparse,
14684                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
14685                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
14686
14687         { &hf_smb_file_attr_compressed,
14688                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
14689                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
14690
14691         { &hf_smb_file_attr_offline,
14692                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
14693                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
14694
14695         { &hf_smb_file_attr_not_content_indexed,
14696                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
14697                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
14698
14699         { &hf_smb_file_attr_encrypted,
14700                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
14701                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
14702
14703         { &hf_smb_file_size,
14704                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
14705                 NULL, 0, "File Size", HFILL }},
14706
14707         { &hf_smb_search_attribute_read_only,
14708                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
14709                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
14710
14711         { &hf_smb_search_attribute_hidden,
14712                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
14713                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
14714
14715         { &hf_smb_search_attribute_system,
14716                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
14717                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
14718
14719         { &hf_smb_search_attribute_volume,
14720                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
14721                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
14722
14723         { &hf_smb_search_attribute_directory,
14724                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
14725                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
14726
14727         { &hf_smb_search_attribute_archive,
14728                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
14729                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
14730
14731         { &hf_smb_access_mode,
14732                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
14733                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
14734
14735         { &hf_smb_access_sharing,
14736                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
14737                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
14738
14739         { &hf_smb_access_locality,
14740                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
14741                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
14742
14743         { &hf_smb_access_caching,
14744                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
14745                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
14746
14747         { &hf_smb_access_writetru,
14748                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
14749                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
14750
14751         { &hf_smb_create_time,
14752                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
14753                 NULL, 0, "Creation Time", HFILL }},
14754
14755         { &hf_smb_create_dos_date,
14756                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
14757                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
14758
14759         { &hf_smb_create_dos_time,
14760                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
14761                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
14762
14763         { &hf_smb_last_write_time,
14764                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
14765                 NULL, 0, "Time this file was last written to", HFILL }},
14766
14767         { &hf_smb_last_write_dos_date,
14768                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
14769                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
14770
14771         { &hf_smb_last_write_dos_time,
14772                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
14773                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
14774
14775         { &hf_smb_old_file_name,
14776                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
14777                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
14778
14779         { &hf_smb_offset,
14780                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
14781                 NULL, 0, "Offset in file", HFILL }},
14782
14783         { &hf_smb_remaining,
14784                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
14785                 NULL, 0, "Remaining number of bytes", HFILL }},
14786
14787         { &hf_smb_padding,
14788                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
14789                 NULL, 0, "Padding or unknown data", HFILL }},
14790
14791         { &hf_smb_file_data,
14792                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
14793                 NULL, 0, "Data read/written to the file", HFILL }},
14794
14795         { &hf_smb_total_data_len,
14796                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
14797                 NULL, 0, "Total length of data", HFILL }},
14798
14799         { &hf_smb_data_len,
14800                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
14801                 NULL, 0, "Length of data", HFILL }},
14802
14803         { &hf_smb_seek_mode,
14804                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
14805                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
14806
14807         { &hf_smb_access_time,
14808                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
14809                 NULL, 0, "Last Access Time", HFILL }},
14810
14811         { &hf_smb_access_dos_date,
14812                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
14813                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
14814
14815         { &hf_smb_access_dos_time,
14816                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
14817                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
14818
14819         { &hf_smb_data_size,
14820                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
14821                 NULL, 0, "Data Size", HFILL }},
14822
14823         { &hf_smb_alloc_size,
14824                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
14825                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
14826
14827         { &hf_smb_max_count,
14828                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
14829                 NULL, 0, "Maximum Count", HFILL }},
14830
14831         { &hf_smb_min_count,
14832                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
14833                 NULL, 0, "Minimum Count", HFILL }},
14834
14835         { &hf_smb_timeout,
14836                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
14837                 NULL, 0, "Timeout in miliseconds", HFILL }},
14838
14839         { &hf_smb_high_offset,
14840                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
14841                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
14842
14843         { &hf_smb_units,
14844                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
14845                 NULL, 0, "Total number of units at server", HFILL }},
14846
14847         { &hf_smb_bpu,
14848                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
14849                 NULL, 0, "Blocks per unit at server", HFILL }},
14850
14851         { &hf_smb_blocksize,
14852                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
14853                 NULL, 0, "Block size (in bytes) at server", HFILL }},
14854
14855         { &hf_smb_freeunits,
14856                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
14857                 NULL, 0, "Number of free units at server", HFILL }},
14858
14859         { &hf_smb_data_offset,
14860                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
14861                 NULL, 0, "Data Offset", HFILL }},
14862
14863         { &hf_smb_dcm,
14864                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
14865                 NULL, 0, "Data Compaction Mode", HFILL }},
14866
14867         { &hf_smb_request_mask,
14868                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
14869                 NULL, 0, "Connectionless mode mask", HFILL }},
14870
14871         { &hf_smb_response_mask,
14872                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
14873                 NULL, 0, "Connectionless mode mask", HFILL }},
14874
14875         { &hf_smb_sid,
14876                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
14877                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
14878
14879         { &hf_smb_write_mode_write_through,
14880                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
14881                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
14882
14883         { &hf_smb_write_mode_return_remaining,
14884                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
14885                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
14886
14887         { &hf_smb_write_mode_raw,
14888                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
14889                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
14890
14891         { &hf_smb_write_mode_message_start,
14892                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
14893                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
14894
14895         { &hf_smb_write_mode_connectionless,
14896                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
14897                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
14898
14899         { &hf_smb_resume_key_len,
14900                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
14901                 NULL, 0, "Resume Key length", HFILL }},
14902
14903         { &hf_smb_resume_server_cookie,
14904                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
14905                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
14906
14907         { &hf_smb_resume_client_cookie,
14908                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
14909                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
14910
14911         { &hf_smb_andxoffset,
14912                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
14913                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
14914
14915         { &hf_smb_lock_type_large,
14916                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
14917                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
14918
14919         { &hf_smb_lock_type_cancel,
14920                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
14921                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
14922
14923         { &hf_smb_lock_type_change,
14924                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
14925                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
14926
14927         { &hf_smb_lock_type_oplock,
14928                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
14929                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
14930
14931         { &hf_smb_lock_type_shared,
14932                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
14933                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
14934
14935         { &hf_smb_locking_ol,
14936                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
14937                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
14938
14939         { &hf_smb_number_of_locks,
14940                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
14941                 NULL, 0, "Number of lock requests in this request", HFILL }},
14942
14943         { &hf_smb_number_of_unlocks,
14944                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
14945                 NULL, 0, "Number of unlock requests in this request", HFILL }},
14946
14947         { &hf_smb_lock_long_length,
14948                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
14949                 NULL, 0, "Length of lock/unlock region", HFILL }},
14950
14951         { &hf_smb_lock_long_offset,
14952                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
14953                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
14954
14955         { &hf_smb_file_type,
14956                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
14957                 VALS(filetype_vals), 0, "Type of file", HFILL }},
14958
14959         { &hf_smb_ipc_state_nonblocking,
14960                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
14961                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
14962
14963         { &hf_smb_ipc_state_endpoint,
14964                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
14965                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
14966
14967         { &hf_smb_ipc_state_pipe_type,
14968                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
14969                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
14970
14971         { &hf_smb_ipc_state_read_mode,
14972                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
14973                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
14974
14975         { &hf_smb_ipc_state_icount,
14976                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
14977                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
14978
14979         { &hf_smb_server_fid,
14980                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
14981                 NULL, 0, "Server unique File ID", HFILL }},
14982
14983         { &hf_smb_open_flags_add_info,
14984                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
14985                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
14986
14987         { &hf_smb_open_flags_ex_oplock,
14988                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
14989                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
14990
14991         { &hf_smb_open_flags_batch_oplock,
14992                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
14993                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
14994
14995         { &hf_smb_open_flags_ealen,
14996                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
14997                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
14998
14999         { &hf_smb_open_action_open,
15000                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
15001                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
15002
15003         { &hf_smb_open_action_lock,
15004                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
15005                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
15006
15007         { &hf_smb_vc_num,
15008                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
15009                 NULL, 0, "VC Number", HFILL }},
15010
15011         { &hf_smb_password_len,
15012                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
15013                 NULL, 0, "Length of password", HFILL }},
15014
15015         { &hf_smb_ansi_password_len,
15016                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
15017                 NULL, 0, "Length of ANSI password", HFILL }},
15018
15019         { &hf_smb_unicode_password_len,
15020                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
15021                 NULL, 0, "Length of Unicode password", HFILL }},
15022
15023         { &hf_smb_account,
15024                 { "Account", "smb.account", FT_STRING, BASE_NONE,
15025                 NULL, 0, "Account, username", HFILL }},
15026
15027         { &hf_smb_os,
15028                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
15029                 NULL, 0, "Which OS we are running", HFILL }},
15030
15031         { &hf_smb_lanman,
15032                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
15033                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
15034
15035         { &hf_smb_setup_action_guest,
15036                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
15037                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
15038
15039         { &hf_smb_fs,
15040                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
15041                 NULL, 0, "Native File System", HFILL }},
15042
15043         { &hf_smb_connect_flags_dtid,
15044                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
15045                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
15046
15047         { &hf_smb_connect_support_search,
15048                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
15049                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
15050
15051         { &hf_smb_connect_support_in_dfs,
15052                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
15053                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
15054
15055         { &hf_smb_max_setup_count,
15056                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
15057                 NULL, 0, "Maximum number of setup words to return", HFILL }},
15058
15059         { &hf_smb_total_param_count,
15060                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
15061                 NULL, 0, "Total number of parameter bytes", HFILL }},
15062
15063         { &hf_smb_total_data_count,
15064                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
15065                 NULL, 0, "Total number of data bytes", HFILL }},
15066
15067         { &hf_smb_max_param_count,
15068                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
15069                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
15070
15071         { &hf_smb_max_data_count,
15072                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
15073                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
15074
15075         { &hf_smb_param_disp16,
15076                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
15077                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15078
15079         { &hf_smb_param_count16,
15080                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
15081                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15082
15083         { &hf_smb_param_offset16,
15084                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
15085                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15086
15087         { &hf_smb_param_disp32,
15088                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
15089                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
15090
15091         { &hf_smb_param_count32,
15092                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
15093                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
15094
15095         { &hf_smb_param_offset32,
15096                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
15097                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
15098
15099         { &hf_smb_data_count16,
15100                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
15101                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15102
15103         { &hf_smb_data_disp16,
15104                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
15105                 NULL, 0, "Data Displacement", HFILL }},
15106
15107         { &hf_smb_data_offset16,
15108                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
15109                 NULL, 0, "Data Offset", HFILL }},
15110
15111         { &hf_smb_data_count32,
15112                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
15113                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
15114
15115         { &hf_smb_data_disp32,
15116                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
15117                 NULL, 0, "Data Displacement", HFILL }},
15118
15119         { &hf_smb_data_offset32,
15120                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
15121                 NULL, 0, "Data Offset", HFILL }},
15122
15123         { &hf_smb_setup_count,
15124                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
15125                 NULL, 0, "Number of setup words in this buffer", HFILL }},
15126
15127         { &hf_smb_nt_trans_subcmd,
15128                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
15129                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
15130
15131         { &hf_smb_nt_ioctl_function_code,
15132                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
15133                 NULL, 0, "NT IOCTL function code", HFILL }},
15134
15135         { &hf_smb_nt_ioctl_isfsctl,
15136                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
15137                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
15138
15139         { &hf_smb_nt_ioctl_flags_root_handle,
15140                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
15141                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
15142
15143         { &hf_smb_nt_ioctl_data,
15144                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
15145                 NULL, 0, "Data for the IOCTL call", HFILL }},
15146
15147         { &hf_smb_nt_notify_action,
15148                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
15149                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
15150
15151         { &hf_smb_nt_notify_watch_tree,
15152                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
15153                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
15154
15155         { &hf_smb_nt_notify_stream_write,
15156                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
15157                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
15158
15159         { &hf_smb_nt_notify_stream_size,
15160                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
15161                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
15162
15163         { &hf_smb_nt_notify_stream_name,
15164                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
15165                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
15166
15167         { &hf_smb_nt_notify_security,
15168                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
15169                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
15170
15171         { &hf_smb_nt_notify_ea,
15172                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
15173                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
15174
15175         { &hf_smb_nt_notify_creation,
15176                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
15177                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
15178
15179         { &hf_smb_nt_notify_last_access,
15180                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
15181                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
15182
15183         { &hf_smb_nt_notify_last_write,
15184                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
15185                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
15186
15187         { &hf_smb_nt_notify_size,
15188                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
15189                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
15190
15191         { &hf_smb_nt_notify_attributes,
15192                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
15193                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
15194
15195         { &hf_smb_nt_notify_dir_name,
15196                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
15197                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
15198
15199         { &hf_smb_nt_notify_file_name,
15200                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
15201                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
15202
15203         { &hf_smb_root_dir_fid,
15204                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
15205                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
15206
15207         { &hf_smb_alloc_size64,
15208                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
15209                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
15210
15211         { &hf_smb_nt_create_disposition,
15212                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
15213                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
15214
15215         { &hf_smb_sd_length,
15216                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
15217                 NULL, 0, "Total length of security descriptor", HFILL }},
15218
15219         { &hf_smb_ea_length,
15220                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
15221                 NULL, 0, "Total EA length for opened file", HFILL }},
15222
15223         { &hf_smb_file_name_len,
15224                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
15225                 NULL, 0, "Length of File Name", HFILL }},
15226
15227         { &hf_smb_nt_impersonation_level,
15228                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
15229                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
15230
15231         { &hf_smb_nt_security_flags_context_tracking,
15232                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
15233                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
15234
15235         { &hf_smb_nt_security_flags_effective_only,
15236                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
15237                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
15238
15239         { &hf_smb_nt_access_mask_generic_read,
15240                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
15241                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
15242
15243         { &hf_smb_nt_access_mask_generic_write,
15244                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
15245                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
15246
15247         { &hf_smb_nt_access_mask_generic_execute,
15248                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
15249                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
15250
15251         { &hf_smb_nt_access_mask_generic_all,
15252                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
15253                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
15254
15255         { &hf_smb_nt_access_mask_maximum_allowed,
15256                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
15257                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
15258
15259         { &hf_smb_nt_access_mask_system_security,
15260                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
15261                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
15262
15263         { &hf_smb_nt_access_mask_synchronize,
15264                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
15265                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
15266
15267         { &hf_smb_nt_access_mask_write_owner,
15268                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
15269                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
15270
15271         { &hf_smb_nt_access_mask_write_dac,
15272                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
15273                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
15274
15275         { &hf_smb_nt_access_mask_read_control,
15276                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
15277                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
15278
15279         { &hf_smb_nt_access_mask_delete,
15280                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
15281                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
15282
15283         { &hf_smb_nt_access_mask_write_attributes,
15284                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
15285                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
15286
15287         { &hf_smb_nt_access_mask_read_attributes,
15288                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
15289                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
15290
15291         { &hf_smb_nt_access_mask_delete_child,
15292                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
15293                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
15294
15295         /*
15296          * "Execute" for files, "traverse" for directories.
15297          */
15298         { &hf_smb_nt_access_mask_execute,
15299                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
15300                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
15301
15302         { &hf_smb_nt_access_mask_write_ea,
15303                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
15304                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
15305
15306         { &hf_smb_nt_access_mask_read_ea,
15307                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
15308                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
15309
15310         /*
15311          * "Append data" for files, "add subdirectory" for directories,
15312          * "create pipe instance" for named pipes.
15313          */
15314         { &hf_smb_nt_access_mask_append,
15315                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
15316                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
15317
15318         /*
15319          * "Write data" for files and pipes, "add file" for directory.
15320          */
15321         { &hf_smb_nt_access_mask_write,
15322                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
15323                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
15324
15325         /*
15326          * "Read data" for files and pipes, "list directory" for directory.
15327          */
15328         { &hf_smb_nt_access_mask_read,
15329                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
15330                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
15331
15332         { &hf_smb_nt_create_bits_oplock,
15333                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
15334                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
15335
15336         { &hf_smb_nt_create_bits_boplock,
15337                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
15338                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
15339
15340         { &hf_smb_nt_create_bits_dir,
15341                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
15342                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
15343
15344         { &hf_smb_nt_create_options_directory_file,
15345                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
15346                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
15347
15348         { &hf_smb_nt_create_options_write_through,
15349                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
15350                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
15351
15352         { &hf_smb_nt_create_options_sequential_only,
15353                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
15354                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
15355
15356         { &hf_smb_nt_create_options_sync_io_alert,
15357                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
15358                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
15359
15360         { &hf_smb_nt_create_options_sync_io_nonalert,
15361                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
15362                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
15363
15364         { &hf_smb_nt_create_options_non_directory_file,
15365                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
15366                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
15367
15368         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
15369            and "NtOpenFile()"; is that sent over the wire?  Network
15370            Monitor thinks so, but its author may just have grabbed
15371            the flag bits from a system header file. */
15372
15373         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
15374            and "NtOpenFile()"; is that sent over the wire?  NetMon
15375            thinks so, but see previous comment. */
15376
15377         { &hf_smb_nt_create_options_no_ea_knowledge,
15378                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
15379                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
15380
15381         { &hf_smb_nt_create_options_eight_dot_three_only,
15382                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
15383                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
15384
15385         { &hf_smb_nt_create_options_random_access,
15386                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
15387                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
15388
15389         { &hf_smb_nt_create_options_delete_on_close,
15390                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
15391                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
15392
15393         /* 0x00002000 is "open by FID", or something such as that (which
15394            I suspect is like "open by inumber" on UNIX), at least in
15395            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
15396            wire?  NetMon thinks so, but see previous comment. */
15397
15398         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
15399            and "NtOpenFile()"; is that sent over the wire?  NetMon
15400            thinks so, but see previous comment. */
15401
15402         { &hf_smb_nt_share_access_read,
15403                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
15404                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
15405
15406         { &hf_smb_nt_share_access_write,
15407                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
15408                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
15409
15410         { &hf_smb_nt_share_access_delete,
15411                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
15412                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
15413
15414         { &hf_smb_file_eattr_read_only,
15415                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
15416                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
15417
15418         { &hf_smb_file_eattr_hidden,
15419                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
15420                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
15421
15422         { &hf_smb_file_eattr_system,
15423                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
15424                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
15425
15426         { &hf_smb_file_eattr_volume,
15427                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
15428                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
15429
15430         { &hf_smb_file_eattr_directory,
15431                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
15432                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
15433
15434         { &hf_smb_file_eattr_archive,
15435                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
15436                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
15437
15438         { &hf_smb_file_eattr_device,
15439                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
15440                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
15441
15442         { &hf_smb_file_eattr_normal,
15443                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
15444                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
15445
15446         { &hf_smb_file_eattr_temporary,
15447                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
15448                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
15449
15450         { &hf_smb_file_eattr_sparse,
15451                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
15452                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
15453
15454         { &hf_smb_file_eattr_reparse,
15455                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
15456                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
15457
15458         { &hf_smb_file_eattr_compressed,
15459                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
15460                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
15461
15462         { &hf_smb_file_eattr_offline,
15463                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
15464                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
15465
15466         { &hf_smb_file_eattr_not_content_indexed,
15467                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
15468                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
15469
15470         { &hf_smb_file_eattr_encrypted,
15471                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
15472                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
15473
15474         { &hf_smb_file_eattr_write_through,
15475                 { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
15476                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
15477
15478         { &hf_smb_file_eattr_no_buffering,
15479                 { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
15480                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
15481
15482         { &hf_smb_file_eattr_random_access,
15483                 { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
15484                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
15485
15486         { &hf_smb_file_eattr_sequential_scan,
15487                 { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
15488                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
15489
15490         { &hf_smb_file_eattr_delete_on_close,
15491                 { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
15492                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
15493
15494         { &hf_smb_file_eattr_backup_semantics,
15495                 { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
15496                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
15497
15498         { &hf_smb_file_eattr_posix_semantics,
15499                 { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
15500                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
15501
15502         { &hf_smb_sec_desc_len,
15503                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
15504                 NULL, 0, "Security Descriptor Length", HFILL }},
15505
15506         { &hf_smb_nt_qsd_owner,
15507                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
15508                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
15509
15510         { &hf_smb_nt_qsd_group,
15511                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
15512                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
15513
15514         { &hf_smb_nt_qsd_dacl,
15515                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
15516                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
15517
15518         { &hf_smb_nt_qsd_sacl,
15519                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
15520                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
15521
15522         { &hf_smb_extended_attributes,
15523                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
15524                 NULL, 0, "Extended Attributes", HFILL }},
15525
15526         { &hf_smb_oplock_level,
15527                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
15528                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
15529
15530         { &hf_smb_create_action,
15531                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
15532                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
15533
15534         { &hf_smb_ea_error_offset,
15535                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
15536                 NULL, 0, "Offset into EA list if EA error", HFILL }},
15537
15538         { &hf_smb_end_of_file,
15539                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
15540                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
15541
15542         { &hf_smb_device_type,
15543                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
15544                 VALS(device_type_vals), 0, "Type of device", HFILL }},
15545
15546         { &hf_smb_is_directory,
15547                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
15548                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
15549
15550         { &hf_smb_next_entry_offset,
15551                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
15552                 NULL, 0, "Offset to next entry", HFILL }},
15553
15554         { &hf_smb_change_time,
15555                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
15556                 NULL, 0, "Last Change Time", HFILL }},
15557
15558         { &hf_smb_setup_len,
15559                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
15560                 NULL, 0, "Length of prionter setup data", HFILL }},
15561
15562         { &hf_smb_print_mode,
15563                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
15564                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
15565
15566         { &hf_smb_print_identifier,
15567                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
15568                 NULL, 0, "Identifier string for this print job", HFILL }},
15569
15570         { &hf_smb_restart_index,
15571                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
15572                 NULL, 0, "Index of entry after last returned", HFILL }},
15573
15574         { &hf_smb_print_queue_date,
15575                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
15576                 NULL, 0, "Date when this entry was queued", HFILL }},
15577
15578         { &hf_smb_print_queue_dos_date,
15579                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
15580                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
15581
15582         { &hf_smb_print_queue_dos_time,
15583                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
15584                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
15585
15586         { &hf_smb_print_status,
15587                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
15588                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
15589
15590         { &hf_smb_print_spool_file_number,
15591                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
15592                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
15593
15594         { &hf_smb_print_spool_file_size,
15595                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
15596                 NULL, 0, "Number of bytes in spool file", HFILL }},
15597
15598         { &hf_smb_print_spool_file_name,
15599                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
15600                 NULL, 0, "Name of client that submitted this job", HFILL }},
15601
15602         { &hf_smb_start_index,
15603                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
15604                 NULL, 0, "First queue entry to return", HFILL }},
15605
15606         { &hf_smb_cancel_to,
15607                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
15608                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
15609
15610         { &hf_smb_trans2_subcmd,
15611                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
15612                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
15613
15614         { &hf_smb_trans_name,
15615                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
15616                 NULL, 0, "Name of transaction", HFILL }},
15617
15618         { &hf_smb_transaction_flags_dtid,
15619                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
15620                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
15621
15622         { &hf_smb_transaction_flags_owt,
15623                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
15624                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
15625
15626         { &hf_smb_search_count,
15627                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
15628                 NULL, 0, "Maximum number of search entries to return", HFILL }},
15629
15630         { &hf_smb_search_pattern,
15631                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
15632                 NULL, 0, "Search Pattern", HFILL }},
15633
15634         { &hf_smb_ff2_backup,
15635                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
15636                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
15637
15638         { &hf_smb_ff2_continue,
15639                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
15640                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
15641
15642         { &hf_smb_ff2_resume,
15643                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
15644                 TFS(&tfs_ff2_resume), 0x0004, "Return resume keys for each entry found", HFILL }},
15645
15646         { &hf_smb_ff2_close_eos,
15647                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
15648                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
15649
15650         { &hf_smb_ff2_close,
15651                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
15652                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
15653
15654         { &hf_smb_ff2_information_level,
15655                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
15656                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
15657
15658         { &hf_smb_qpi_loi,
15659                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
15660                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
15661
15662         { &hf_smb_storage_type,
15663                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
15664                 NULL, 0, "Type of storage", HFILL }},
15665
15666         { &hf_smb_resume,
15667                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
15668                 NULL, 0, "Resume Key", HFILL }},
15669
15670         { &hf_smb_max_referral_level,
15671                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
15672                 NULL, 0, "Latest referral version number understood", HFILL }},
15673
15674         { &hf_smb_qfsi_information_level,
15675                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
15676                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
15677
15678         { &hf_smb_ea_size,
15679                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
15680                 NULL, 0, "Size of file's EA information", HFILL }},
15681
15682         { &hf_smb_list_length,
15683                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
15684                 NULL, 0, "Length of the remaining data", HFILL }},
15685
15686         { &hf_smb_number_of_links,
15687                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
15688                 NULL, 0, "Number of hard links to the file", HFILL }},
15689
15690         { &hf_smb_delete_pending,
15691                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
15692                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
15693
15694         { &hf_smb_index_number,
15695                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
15696                 NULL, 0, "File system unique identifier", HFILL }},
15697
15698         { &hf_smb_current_offset,
15699                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
15700                 NULL, 0, "Current offset in the file", HFILL }},
15701
15702         { &hf_smb_t2_alignment,
15703                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
15704                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
15705
15706         { &hf_smb_t2_stream_name_length,
15707                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
15708                 NULL, 0, "Length of stream name", HFILL }},
15709
15710         { &hf_smb_t2_stream_size,
15711                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
15712                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
15713
15714         { &hf_smb_t2_stream_name,
15715                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
15716                 NULL, 0, "Name of the stream", HFILL }},
15717
15718         { &hf_smb_t2_compressed_file_size,
15719                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
15720                 NULL, 0, "Size of the compressed file", HFILL }},
15721
15722         { &hf_smb_t2_compressed_format,
15723                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
15724                 NULL, 0, "Compression algorithm used", HFILL }},
15725
15726         { &hf_smb_t2_compressed_unit_shift,
15727                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
15728                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
15729
15730         { &hf_smb_t2_compressed_chunk_shift,
15731                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
15732                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
15733
15734         { &hf_smb_t2_compressed_cluster_shift,
15735                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
15736                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
15737
15738         { &hf_smb_dfs_path_consumed,
15739                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
15740                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
15741
15742         { &hf_smb_dfs_num_referrals,
15743                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
15744                 NULL, 0, "Number of referrals in this pdu", HFILL }},
15745
15746         { &hf_smb_get_dfs_server_hold_storage,
15747                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
15748                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
15749
15750         { &hf_smb_get_dfs_fielding,
15751                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
15752                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
15753
15754         { &hf_smb_dfs_referral_version,
15755                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
15756                 NULL, 0, "Version of referral element", HFILL }},
15757
15758         { &hf_smb_dfs_referral_size,
15759                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
15760                 NULL, 0, "Size of referral element", HFILL }},
15761
15762         { &hf_smb_dfs_referral_server_type,
15763                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
15764                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
15765
15766         { &hf_smb_dfs_referral_flags_strip,
15767                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
15768                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
15769
15770         { &hf_smb_dfs_referral_node_offset,
15771                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
15772                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
15773
15774         { &hf_smb_dfs_referral_node,
15775                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
15776                 NULL, 0, "Name of entity to visit next", HFILL }},
15777
15778         { &hf_smb_dfs_referral_proximity,
15779                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
15780                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
15781
15782         { &hf_smb_dfs_referral_ttl,
15783                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
15784                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
15785
15786         { &hf_smb_dfs_referral_path_offset,
15787                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
15788                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
15789
15790         { &hf_smb_dfs_referral_path,
15791                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
15792                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
15793
15794         { &hf_smb_dfs_referral_alt_path_offset,
15795                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
15796                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
15797
15798         { &hf_smb_dfs_referral_alt_path,
15799                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
15800                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
15801
15802         { &hf_smb_end_of_search,
15803                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
15804                 NULL, 0, "Was last entry returned?", HFILL }},
15805
15806         { &hf_smb_last_name_offset,
15807                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
15808                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
15809
15810         { &hf_smb_file_index,
15811                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
15812                 NULL, 0, "File index", HFILL }},
15813
15814         { &hf_smb_short_file_name,
15815                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
15816                 NULL, 0, "Short (8.3) File Name", HFILL }},
15817
15818         { &hf_smb_short_file_name_len,
15819                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
15820                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
15821
15822         { &hf_smb_fs_id,
15823                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
15824                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
15825
15826         { &hf_smb_sector_unit,
15827                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
15828                 NULL, 0, "Sectors per allocation unit", HFILL }},
15829
15830         { &hf_smb_fs_units,
15831                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
15832                 NULL, 0, "Total number of units on this filesystem", HFILL }},
15833
15834         { &hf_smb_fs_sector,
15835                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
15836                 NULL, 0, "Bytes per sector", HFILL }},
15837
15838         { &hf_smb_avail_units,
15839                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
15840                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
15841
15842         { &hf_smb_volume_serial_num,
15843                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
15844                 NULL, 0, "Volume serial number", HFILL }},
15845
15846         { &hf_smb_volume_label_len,
15847                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
15848                 NULL, 0, "Length of volume label", HFILL }},
15849
15850         { &hf_smb_volume_label,
15851                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
15852                 NULL, 0, "Volume label", HFILL }},
15853
15854         { &hf_smb_free_alloc_units64,
15855                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
15856                 NULL, 0, "Number of free allocation units", HFILL }},
15857
15858         { &hf_smb_max_name_len,
15859                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
15860                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
15861
15862         { &hf_smb_fs_name_len,
15863                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
15864                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
15865
15866         { &hf_smb_fs_name,
15867                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
15868                 NULL, 0, "Name of filesystem", HFILL }},
15869
15870         { &hf_smb_device_char_removable,
15871                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
15872                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
15873
15874         { &hf_smb_device_char_read_only,
15875                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
15876                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
15877
15878         { &hf_smb_device_char_floppy,
15879                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
15880                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
15881
15882         { &hf_smb_device_char_write_once,
15883                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
15884                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
15885
15886         { &hf_smb_device_char_remote,
15887                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
15888                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
15889
15890         { &hf_smb_device_char_mounted,
15891                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
15892                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
15893
15894         { &hf_smb_device_char_virtual,
15895                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
15896                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
15897
15898         { &hf_smb_fs_attr_css,
15899                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
15900                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
15901
15902         { &hf_smb_fs_attr_cpn,
15903                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
15904                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
15905
15906         { &hf_smb_fs_attr_pacls,
15907                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
15908                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
15909
15910         { &hf_smb_fs_attr_fc,
15911                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
15912                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
15913
15914         { &hf_smb_fs_attr_vq,
15915                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
15916                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
15917
15918         { &hf_smb_fs_attr_dim,
15919                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
15920                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
15921
15922         { &hf_smb_fs_attr_vic,
15923                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
15924                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
15925
15926         { &hf_smb_sec_desc_revision,
15927                 { "Revision", "smb.sec_desc.revision", FT_UINT16, BASE_DEC,
15928                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
15929
15930         { &hf_smb_sid_revision,
15931                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
15932                 NULL, 0, "Version of SID structure", HFILL }},
15933
15934         { &hf_smb_sid_num_auth,
15935                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
15936                 NULL, 0, "Number of authorities for this SID", HFILL }},
15937
15938         { &hf_smb_acl_revision,
15939                 { "Revision", "smb.acl.revision", FT_UINT16, BASE_DEC,
15940                 NULL, 0, "Version of NT ACL structure", HFILL }},
15941
15942         { &hf_smb_acl_size,
15943                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
15944                 NULL, 0, "Size of NT ACL structure", HFILL }},
15945
15946         { &hf_smb_acl_num_aces,
15947                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
15948                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
15949
15950         { &hf_smb_ace_type,
15951                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
15952                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
15953
15954         { &hf_smb_ace_size,
15955                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
15956                 NULL, 0, "Size of this ACE", HFILL }},
15957
15958         { &hf_smb_ace_flags_object_inherit,
15959                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
15960                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
15961
15962         { &hf_smb_ace_flags_container_inherit,
15963                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
15964                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
15965
15966         { &hf_smb_ace_flags_non_propagate_inherit,
15967                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
15968                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
15969
15970         { &hf_smb_ace_flags_inherit_only,
15971                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
15972                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
15973
15974         { &hf_smb_ace_flags_inherited_ace,
15975                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
15976                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
15977
15978         { &hf_smb_ace_flags_successful_access,
15979                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
15980                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
15981
15982         { &hf_smb_ace_flags_failed_access,
15983                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
15984                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
15985
15986         { &hf_smb_sec_desc_type_owner_defaulted,
15987                 { "Onwer Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
15988                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
15989
15990         { &hf_smb_sec_desc_type_group_defaulted,
15991                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
15992                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
15993
15994         { &hf_smb_sec_desc_type_dacl_present,
15995                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
15996                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
15997
15998         { &hf_smb_sec_desc_type_dacl_defaulted,
15999                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
16000                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
16001
16002         { &hf_smb_sec_desc_type_sacl_present,
16003                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
16004                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
16005
16006         { &hf_smb_sec_desc_type_sacl_defaulted,
16007                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
16008                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
16009
16010         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
16011                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
16012                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
16013
16014         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
16015                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
16016                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
16017
16018         { &hf_smb_sec_desc_type_dacl_auto_inherited,
16019                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
16020                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
16021
16022         { &hf_smb_sec_desc_type_sacl_auto_inherited,
16023                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
16024                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
16025
16026         { &hf_smb_sec_desc_type_dacl_protected,
16027                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
16028                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
16029
16030         { &hf_smb_sec_desc_type_sacl_protected,
16031                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
16032                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
16033
16034         { &hf_smb_sec_desc_type_self_relative,
16035                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
16036                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
16037
16038         { &hf_smb_quota_flags_deny_disk,
16039                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
16040                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
16041
16042         { &hf_smb_quota_flags_log_limit,
16043                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
16044                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
16045
16046         { &hf_smb_quota_flags_log_warning,
16047                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
16048                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
16049
16050         };
16051         static gint *ett[] = {
16052                 &ett_smb,
16053                 &ett_smb_hdr,
16054                 &ett_smb_command,
16055                 &ett_smb_fileattributes,
16056                 &ett_smb_capabilities,
16057                 &ett_smb_aflags,
16058                 &ett_smb_dialect,
16059                 &ett_smb_dialects,
16060                 &ett_smb_mode,
16061                 &ett_smb_rawmode,
16062                 &ett_smb_flags,
16063                 &ett_smb_flags2,
16064                 &ett_smb_desiredaccess,
16065                 &ett_smb_search,
16066                 &ett_smb_file,
16067                 &ett_smb_openfunction,
16068                 &ett_smb_filetype,
16069                 &ett_smb_openaction,
16070                 &ett_smb_writemode,
16071                 &ett_smb_lock_type,
16072                 &ett_smb_ssetupandxaction,
16073                 &ett_smb_optionsup,
16074                 &ett_smb_time_date,
16075                 &ett_smb_move_flags,
16076                 &ett_smb_file_attributes,
16077                 &ett_smb_search_resume_key,
16078                 &ett_smb_search_dir_info,
16079                 &ett_smb_unlocks,
16080                 &ett_smb_unlock,
16081                 &ett_smb_locks,
16082                 &ett_smb_lock,
16083                 &ett_smb_open_flags,
16084                 &ett_smb_ipc_state,
16085                 &ett_smb_open_action,
16086                 &ett_smb_setup_action,
16087                 &ett_smb_connect_flags,
16088                 &ett_smb_connect_support_bits,
16089                 &ett_smb_nt_access_mask,
16090                 &ett_smb_nt_create_bits,
16091                 &ett_smb_nt_create_options,
16092                 &ett_smb_nt_share_access,
16093                 &ett_smb_nt_security_flags,
16094                 &ett_smb_nt_trans_setup,
16095                 &ett_smb_nt_notify_completion_filter,
16096                 &ett_smb_nt_ioctl_flags,
16097                 &ett_smb_security_information_mask,
16098                 &ett_smb_print_queue_entry,
16099                 &ett_smb_transaction_flags,
16100                 &ett_smb_transaction_params,
16101                 &ett_smb_find_first2_flags,
16102                 &ett_smb_transaction_data,
16103                 &ett_smb_stream_info,
16104                 &ett_smb_dfs_referrals,
16105                 &ett_smb_dfs_referral,
16106                 &ett_smb_dfs_referral_flags,
16107                 &ett_smb_get_dfs_flags,
16108                 &ett_smb_ff2_data,
16109                 &ett_smb_device_characteristics,
16110                 &ett_smb_fs_attributes,
16111                 &ett_smb_segments,
16112                 &ett_smb_sec_desc,
16113                 &ett_smb_sid,
16114                 &ett_smb_acl,
16115                 &ett_smb_ace,
16116                 &ett_smb_ace_flags,
16117                 &ett_smb_sec_desc_type,
16118                 &ett_smb_quotaflags,
16119         };
16120         module_t *smb_module;
16121
16122         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
16123             "SMB", "smb");
16124         proto_register_subtree_array(ett, array_length(ett));
16125         proto_register_field_array(proto_smb, hf, array_length(hf));
16126         register_init_routine(&smb_init_protocol);
16127         smb_module = prefs_register_protocol(proto_smb, NULL);
16128         prefs_register_bool_preference(smb_module, "trans_reassembly",
16129                 "Reassemble SMB Transaction payload",
16130                 "Whether the dissector should do reassembly the payload of SMB Transaction commands spanning multiple SMB PDUs",
16131                 &smb_trans_reassembly);
16132         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
16133                 "Reassemble DCERPC over SMB",
16134                 "Whether the dissector should do reassembly of DCERPC over SMB commands",
16135                 &smb_dcerpc_reassembly);
16136         register_init_routine(smb_trans_reassembly_init);
16137         register_init_routine(smb_dcerpc_reassembly_init);
16138 }
16139
16140 void
16141 proto_reg_handoff_smb(void)
16142 {
16143         heur_dissector_add("netbios", dissect_smb, proto_smb);
16144 }