af163ba06b930e66e3afc5439614e12e6cc054e0
[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  *
5  * $Id: packet-smb.c,v 1.160 2001/11/19 11:41:51 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-pop.c
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <stdio.h>
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
40 #endif
41
42 #include <time.h>
43 #include <string.h>
44 #include <glib.h>
45 #include <ctype.h>
46 #include "packet.h"
47 #include "conversation.h"
48 #include "smb.h"
49 #include "alignment.h"
50 #include "strutil.h"
51
52 #include "packet-smb-mailslot.h"
53 #include "packet-smb-pipe.h"
54
55 /*
56  * Various specifications and documents about SMB can be found in
57  *
58  *      ftp://ftp.microsoft.com/developr/drg/CIFS/
59  *
60  * and a CIFS draft from the Storage Networking Industry Association
61  * can be found on a link from the page at
62  *
63  *      http://www.snia.org/English/Work_Groups/NAS/CIFS/WG_CIFS_Docs.html
64  *
65  * (it supercedes the document at
66  *
67  *      ftp://ftp.microsoft.com/developr/drg/CIFS/draft-leach-cifs-v1-spec-01.txt
68  *
69  * ).
70  *
71  * There are also some Open Group publications documenting CIFS for sale;
72  * catalog entries for them are at:
73  *
74  *      http://www.opengroup.org/products/publications/catalog/c209.htm
75  *
76  *      http://www.opengroup.org/products/publications/catalog/c195.htm
77  *
78  * The document "NT LAN Manager SMB File Sharing Protocol Extensions"
79  * can be found at
80  *
81  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
82  *
83  * (or, presumably a similar path under the Samba mirrors).  As the
84  * ".doc" indicates, it's a Word document.  Some of the specs from the
85  * Microsoft FTP site can be found in the
86  *
87  *      http://www.samba.org/samba/ftp/specs/
88  *
89  * directory as well.
90  *
91  * Beware - these specs may have errors.
92  */
93 static int proto_smb = -1;
94 static int hf_smb_cmd = -1;
95 static int hf_smb_pid = -1;
96 static int hf_smb_tid = -1;
97 static int hf_smb_uid = -1;
98 static int hf_smb_mid = -1;
99 static int hf_smb_response_to = -1;
100 static int hf_smb_response_in = -1;
101 static int hf_smb_nt_status = -1;
102 static int hf_smb_error_class = -1;
103 static int hf_smb_error_code = -1;
104 static int hf_smb_reserved = -1;
105 static int hf_smb_flags_lock = -1;
106 static int hf_smb_flags_receive_buffer = -1;
107 static int hf_smb_flags_caseless = -1;
108 static int hf_smb_flags_canon = -1;
109 static int hf_smb_flags_oplock = -1;
110 static int hf_smb_flags_notify = -1;
111 static int hf_smb_flags_response = -1;
112 static int hf_smb_flags2_long_names_allowed = -1;
113 static int hf_smb_flags2_ea = -1;
114 static int hf_smb_flags2_sec_sig = -1;
115 static int hf_smb_flags2_long_names_used = -1;
116 static int hf_smb_flags2_esn = -1;
117 static int hf_smb_flags2_dfs = -1;
118 static int hf_smb_flags2_roe = -1;
119 static int hf_smb_flags2_nt_error = -1;
120 static int hf_smb_flags2_string = -1;
121 static int hf_smb_word_count = -1;
122 static int hf_smb_byte_count = -1;
123 static int hf_smb_buffer_format = -1;
124 static int hf_smb_dialect_name = -1;
125 static int hf_smb_dialect_index = -1;
126 static int hf_smb_max_trans_buf_size = -1;
127 static int hf_smb_max_mpx_count = -1;
128 static int hf_smb_max_vcs_num = -1;
129 static int hf_smb_session_key = -1;
130 static int hf_smb_server_timezone = -1;
131 static int hf_smb_encryption_key_length = -1;
132 static int hf_smb_encryption_key = -1;
133 static int hf_smb_primary_domain = -1;
134 static int hf_smb_max_raw_buf_size = -1;
135 static int hf_smb_server_guid = -1;
136 static int hf_smb_security_blob_len = -1;
137 static int hf_smb_security_blob = -1;
138 static int hf_smb_sm_mode16 = -1;
139 static int hf_smb_sm_password16 = -1;
140 static int hf_smb_sm_mode = -1;
141 static int hf_smb_sm_password = -1;
142 static int hf_smb_sm_signatures = -1;
143 static int hf_smb_sm_sig_required = -1;
144 static int hf_smb_rm_read = -1;
145 static int hf_smb_rm_write = -1;
146 static int hf_smb_server_date_time = -1;
147 static int hf_smb_server_smb_date = -1;
148 static int hf_smb_server_smb_time = -1;
149 static int hf_smb_server_cap_raw_mode = -1;
150 static int hf_smb_server_cap_mpx_mode = -1;
151 static int hf_smb_server_cap_unicode = -1;
152 static int hf_smb_server_cap_large_files = -1;
153 static int hf_smb_server_cap_nt_smbs = -1;
154 static int hf_smb_server_cap_rpc_remote_apis = -1;
155 static int hf_smb_server_cap_nt_status = -1;
156 static int hf_smb_server_cap_level_ii_oplocks = -1;
157 static int hf_smb_server_cap_lock_and_read = -1;
158 static int hf_smb_server_cap_nt_find = -1;
159 static int hf_smb_server_cap_dfs = -1;
160 static int hf_smb_server_cap_infolevel_passthru = -1;
161 static int hf_smb_server_cap_large_readx = -1;
162 static int hf_smb_server_cap_large_writex = -1;
163 static int hf_smb_server_cap_unix = -1;
164 static int hf_smb_server_cap_reserved = -1;
165 static int hf_smb_server_cap_bulk_transfer = -1;
166 static int hf_smb_server_cap_compressed_data = -1;
167 static int hf_smb_server_cap_extended_security = -1;
168 static int hf_smb_system_time = -1;
169 static int hf_smb_unknown = -1;
170 static int hf_smb_dir_name = -1;
171 static int hf_smb_echo_count = -1;
172 static int hf_smb_echo_data = -1;
173 static int hf_smb_echo_seq_num = -1;
174 static int hf_smb_max_buf_size = -1;
175 static int hf_smb_password = -1;
176 static int hf_smb_password_len = -1;
177 static int hf_smb_ansi_password = -1;
178 static int hf_smb_ansi_password_len = -1;
179 static int hf_smb_unicode_password = -1;
180 static int hf_smb_unicode_password_len = -1;
181 static int hf_smb_path = -1;
182 static int hf_smb_service = -1;
183 static int hf_smb_move_flags_file = -1;
184 static int hf_smb_move_flags_dir = -1;
185 static int hf_smb_move_flags_verify = -1;
186 static int hf_smb_count = -1;
187 static int hf_smb_file_name = -1;
188 static int hf_smb_open_function_open = -1;
189 static int hf_smb_open_function_create = -1;
190 static int hf_smb_fid = -1;
191 static int hf_smb_file_attr_read_only_16bit = -1;
192 static int hf_smb_file_attr_read_only_8bit = -1;
193 static int hf_smb_file_attr_hidden_16bit = -1;
194 static int hf_smb_file_attr_hidden_8bit = -1;
195 static int hf_smb_file_attr_system_16bit = -1;
196 static int hf_smb_file_attr_system_8bit = -1;
197 static int hf_smb_file_attr_volume_16bit = -1;
198 static int hf_smb_file_attr_volume_8bit = -1;
199 static int hf_smb_file_attr_directory_16bit = -1;
200 static int hf_smb_file_attr_directory_8bit = -1;
201 static int hf_smb_file_attr_archive_16bit = -1;
202 static int hf_smb_file_attr_archive_8bit = -1;
203 static int hf_smb_file_attr_device = -1;
204 static int hf_smb_file_attr_normal = -1;
205 static int hf_smb_file_attr_temporary = -1;
206 static int hf_smb_file_attr_sparse = -1;
207 static int hf_smb_file_attr_reparse = -1;
208 static int hf_smb_file_attr_compressed = -1;
209 static int hf_smb_file_attr_offline = -1;
210 static int hf_smb_file_attr_not_content_indexed = -1;
211 static int hf_smb_file_attr_encrypted = -1;
212 static int hf_smb_file_size = -1;
213 static int hf_smb_search_attribute_read_only = -1;
214 static int hf_smb_search_attribute_hidden = -1;
215 static int hf_smb_search_attribute_system = -1;
216 static int hf_smb_search_attribute_volume = -1;
217 static int hf_smb_search_attribute_directory = -1;
218 static int hf_smb_search_attribute_archive = -1;
219 static int hf_smb_access_mode = -1;
220 static int hf_smb_access_sharing = -1;
221 static int hf_smb_access_locality = -1;
222 static int hf_smb_access_caching = -1;
223 static int hf_smb_access_writetru = -1;
224 static int hf_smb_create_time = -1;
225 static int hf_smb_create_dos_date = -1;
226 static int hf_smb_create_dos_time = -1;
227 static int hf_smb_last_write_time = -1;
228 static int hf_smb_last_write_dos_date = -1;
229 static int hf_smb_last_write_dos_time = -1;
230 static int hf_smb_access_time = -1;
231 static int hf_smb_access_dos_date = -1;
232 static int hf_smb_access_dos_time = -1;
233 static int hf_smb_old_file_name = -1;
234 static int hf_smb_offset = -1;
235 static int hf_smb_remaining = -1;
236 static int hf_smb_padding = -1;
237 static int hf_smb_file_data = -1;
238 static int hf_smb_total_data_len = -1;
239 static int hf_smb_data_len = -1;
240 static int hf_smb_seek_mode = -1;
241 static int hf_smb_data_size = -1;
242 static int hf_smb_alloc_size = -1;
243 static int hf_smb_alloc_size64 = -1;
244 static int hf_smb_max_count = -1;
245 static int hf_smb_min_count = -1;
246 static int hf_smb_timeout = -1;
247 static int hf_smb_high_offset = -1;
248 static int hf_smb_units = -1;
249 static int hf_smb_bpu = -1;
250 static int hf_smb_blocksize = -1;
251 static int hf_smb_freeunits = -1;
252 static int hf_smb_data_offset = -1;
253 static int hf_smb_dcm = -1;
254 static int hf_smb_request_mask = -1;
255 static int hf_smb_response_mask = -1;
256 static int hf_smb_sid = -1;
257 static int hf_smb_write_mode_write_through = -1;
258 static int hf_smb_write_mode_return_remaining = -1;
259 static int hf_smb_write_mode_raw = -1;
260 static int hf_smb_write_mode_message_start = -1;
261 static int hf_smb_write_mode_connectionless = -1;
262 static int hf_smb_resume_key_len = -1;
263 static int hf_smb_resume_server_cookie = -1;
264 static int hf_smb_resume_client_cookie = -1;
265 static int hf_smb_andxoffset = -1;
266 static int hf_smb_lock_type_large = -1;
267 static int hf_smb_lock_type_cancel = -1;
268 static int hf_smb_lock_type_change = -1;
269 static int hf_smb_lock_type_oplock = -1;
270 static int hf_smb_lock_type_shared = -1;
271 static int hf_smb_locking_ol = -1;
272 static int hf_smb_number_of_locks = -1;
273 static int hf_smb_number_of_unlocks = -1;
274 static int hf_smb_lock_long_offset = -1;
275 static int hf_smb_lock_long_length = -1;
276 static int hf_smb_file_type = -1;
277 static int hf_smb_ipc_state_nonblocking = -1;
278 static int hf_smb_ipc_state_endpoint = -1;
279 static int hf_smb_ipc_state_pipe_type = -1;
280 static int hf_smb_ipc_state_read_mode = -1;
281 static int hf_smb_ipc_state_icount = -1;
282 static int hf_smb_server_fid = -1;
283 static int hf_smb_open_flags_add_info = -1;
284 static int hf_smb_open_flags_ex_oplock = -1;
285 static int hf_smb_open_flags_batch_oplock = -1;
286 static int hf_smb_open_flags_ealen = -1;
287 static int hf_smb_open_action_open = -1;
288 static int hf_smb_open_action_lock = -1;
289 static int hf_smb_vc_num = -1;
290 static int hf_smb_account = -1;
291 static int hf_smb_os = -1;
292 static int hf_smb_lanman = -1;
293 static int hf_smb_setup_action_guest = -1;
294 static int hf_smb_fs = -1;
295 static int hf_smb_connect_flags_dtid = -1;
296 static int hf_smb_connect_support_search = -1;
297 static int hf_smb_connect_support_in_dfs = -1;
298 static int hf_smb_max_setup_count = -1;
299 static int hf_smb_total_param_count = -1;
300 static int hf_smb_total_data_count = -1;
301 static int hf_smb_max_param_count = -1;
302 static int hf_smb_max_data_count = -1;
303 static int hf_smb_param_disp16 = -1;
304 static int hf_smb_param_count16 = -1;
305 static int hf_smb_param_offset16 = -1;
306 static int hf_smb_param_disp32 = -1;
307 static int hf_smb_param_count32 = -1;
308 static int hf_smb_param_offset32 = -1;
309 static int hf_smb_data_disp16 = -1;
310 static int hf_smb_data_count16 = -1;
311 static int hf_smb_data_offset16 = -1;
312 static int hf_smb_data_disp32 = -1;
313 static int hf_smb_data_count32 = -1;
314 static int hf_smb_data_offset32 = -1;
315 static int hf_smb_setup_count = -1;
316 static int hf_smb_nt_trans_subcmd = -1;
317 static int hf_smb_nt_ioctl_function_code = -1;
318 static int hf_smb_nt_ioctl_isfsctl = -1;
319 static int hf_smb_nt_ioctl_flags_root_handle = -1;
320 static int hf_smb_nt_ioctl_data = -1;
321 static int hf_smb_nt_security_information = -1;
322 static int hf_smb_nt_notify_action = -1;
323 static int hf_smb_nt_notify_watch_tree = -1;
324 static int hf_smb_nt_notify_stream_write = -1;
325 static int hf_smb_nt_notify_stream_size = -1;
326 static int hf_smb_nt_notify_stream_name = -1;
327 static int hf_smb_nt_notify_security = -1;
328 static int hf_smb_nt_notify_ea = -1;
329 static int hf_smb_nt_notify_creation = -1;
330 static int hf_smb_nt_notify_last_access = -1;
331 static int hf_smb_nt_notify_last_write = -1;
332 static int hf_smb_nt_notify_size = -1;
333 static int hf_smb_nt_notify_attributes = -1;
334 static int hf_smb_nt_notify_dir_name = -1;
335 static int hf_smb_nt_notify_file_name = -1;
336 static int hf_smb_root_dir_fid = -1;
337 static int hf_smb_nt_create_disposition = -1;
338 static int hf_smb_sd_length = -1;
339 static int hf_smb_ea_length = -1;
340 static int hf_smb_file_name_len = -1;
341 static int hf_smb_nt_impersonation_level = -1;
342 static int hf_smb_nt_security_flags_context_tracking = -1;
343 static int hf_smb_nt_security_flags_effective_only = -1;
344 static int hf_smb_nt_access_mask_generic_read = -1;
345 static int hf_smb_nt_access_mask_generic_write = -1;
346 static int hf_smb_nt_access_mask_generic_execute = -1;
347 static int hf_smb_nt_access_mask_generic_all = -1;
348 static int hf_smb_nt_access_mask_maximum_allowed = -1;
349 static int hf_smb_nt_access_mask_system_security = -1;
350 static int hf_smb_nt_access_mask_synchronize = -1;
351 static int hf_smb_nt_access_mask_write_owner = -1;
352 static int hf_smb_nt_access_mask_write_dac = -1;
353 static int hf_smb_nt_access_mask_read_control = -1;
354 static int hf_smb_nt_access_mask_delete = -1;
355 static int hf_smb_nt_access_mask_write_attributes = -1;
356 static int hf_smb_nt_access_mask_read_attributes = -1;
357 static int hf_smb_nt_access_mask_delete_child = -1;
358 static int hf_smb_nt_access_mask_execute = -1;
359 static int hf_smb_nt_access_mask_write_ea = -1;
360 static int hf_smb_nt_access_mask_read_ea = -1;
361 static int hf_smb_nt_access_mask_append = -1;
362 static int hf_smb_nt_access_mask_write = -1;
363 static int hf_smb_nt_access_mask_read = -1;
364 static int hf_smb_nt_create_bits_oplock = -1;
365 static int hf_smb_nt_create_bits_boplock = -1;
366 static int hf_smb_nt_create_bits_dir = -1;
367 static int hf_smb_nt_create_options_directory_file = -1;
368 static int hf_smb_nt_create_options_write_through = -1;
369 static int hf_smb_nt_create_options_sequential_only = -1;
370 static int hf_smb_nt_create_options_sync_io_alert = -1;
371 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
372 static int hf_smb_nt_create_options_non_directory_file = -1;
373 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
374 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
375 static int hf_smb_nt_create_options_random_access = -1;
376 static int hf_smb_nt_create_options_delete_on_close = -1;
377 static int hf_smb_nt_share_access_read = -1;
378 static int hf_smb_nt_share_access_write = -1;
379 static int hf_smb_nt_share_access_delete = -1;
380 static int hf_smb_file_eattr_read_only = -1;
381 static int hf_smb_file_eattr_hidden = -1;
382 static int hf_smb_file_eattr_system = -1;
383 static int hf_smb_file_eattr_volume = -1;
384 static int hf_smb_file_eattr_directory = -1;
385 static int hf_smb_file_eattr_archive = -1;
386 static int hf_smb_file_eattr_device = -1;
387 static int hf_smb_file_eattr_normal = -1;
388 static int hf_smb_file_eattr_temporary = -1;
389 static int hf_smb_file_eattr_sparse = -1;
390 static int hf_smb_file_eattr_reparse = -1;
391 static int hf_smb_file_eattr_compressed = -1;
392 static int hf_smb_file_eattr_offline = -1;
393 static int hf_smb_file_eattr_not_content_indexed = -1;
394 static int hf_smb_file_eattr_encrypted = -1;
395 static int hf_smb_file_eattr_write_through = -1;
396 static int hf_smb_file_eattr_no_buffering = -1;
397 static int hf_smb_file_eattr_random_access = -1;
398 static int hf_smb_file_eattr_sequential_scan = -1;
399 static int hf_smb_file_eattr_delete_on_close = -1;
400 static int hf_smb_file_eattr_backup_semantics = -1;
401 static int hf_smb_file_eattr_posix_semantics = -1;
402 static int hf_smb_security_descriptor_len = -1;
403 static int hf_smb_security_descriptor = -1;
404 static int hf_smb_nt_qsd_owner = -1;
405 static int hf_smb_nt_qsd_group = -1;
406 static int hf_smb_nt_qsd_dacl = -1;
407 static int hf_smb_nt_qsd_sacl = -1;
408 static int hf_smb_extended_attributes = -1;
409 static int hf_smb_oplock_level = -1;
410 static int hf_smb_create_action = -1;
411 static int hf_smb_ea_error_offset = -1;
412 static int hf_smb_end_of_file = -1;
413 static int hf_smb_device_type = -1;
414 static int hf_smb_is_directory = -1;
415 static int hf_smb_next_entry_offset = -1;
416 static int hf_smb_change_time = -1;
417 static int hf_smb_setup_len = -1;
418 static int hf_smb_print_mode = -1;
419 static int hf_smb_print_identifier = -1;
420 static int hf_smb_restart_index = -1;
421 static int hf_smb_print_queue_date = -1;
422 static int hf_smb_print_queue_dos_date = -1;
423 static int hf_smb_print_queue_dos_time = -1;
424 static int hf_smb_print_status = -1;
425 static int hf_smb_print_spool_file_number = -1;
426 static int hf_smb_print_spool_file_size = -1;
427 static int hf_smb_print_spool_file_name = -1;
428 static int hf_smb_start_index = -1;
429 static int hf_smb_cancel_to = -1;
430 static int hf_smb_trans2_subcmd = -1;
431 static int hf_smb_trans_name = -1;
432 static int hf_smb_transaction_flags_dtid = -1;
433 static int hf_smb_transaction_flags_owt = -1;
434 static int hf_smb_search_count = -1;
435 static int hf_smb_search_pattern = -1;
436 static int hf_smb_ff2_backup = -1;
437 static int hf_smb_ff2_continue = -1;
438 static int hf_smb_ff2_resume = -1;
439 static int hf_smb_ff2_close_eos = -1;
440 static int hf_smb_ff2_close = -1;
441 static int hf_smb_ff2_information_level = -1;
442 static int hf_smb_qpi_loi = -1;
443 static int hf_smb_storage_type = -1;
444 static int hf_smb_resume = -1;
445 static int hf_smb_max_referral_level = -1;
446 static int hf_smb_qfsi_information_level = -1;
447 static int hf_smb_ea_size = -1;
448 static int hf_smb_list_length = -1;
449 static int hf_smb_number_of_links = -1;
450 static int hf_smb_delete_pending = -1;
451 static int hf_smb_index_number = -1;
452 static int hf_smb_current_offset = -1;
453 static int hf_smb_t2_alignment = -1;
454 static int hf_smb_t2_stream_name_length = -1;
455 static int hf_smb_t2_stream_size = -1;
456 static int hf_smb_t2_stream_name = -1;
457 static int hf_smb_t2_compressed_file_size = -1;
458 static int hf_smb_t2_compressed_format = -1;
459 static int hf_smb_t2_compressed_unit_shift = -1;
460 static int hf_smb_t2_compressed_chunk_shift = -1;
461 static int hf_smb_t2_compressed_cluster_shift = -1;
462 static int hf_smb_dfs_path_consumed = -1;
463 static int hf_smb_dfs_num_referrals = -1;
464 static int hf_smb_get_dfs_server_hold_storage = -1;
465 static int hf_smb_get_dfs_fielding = -1;
466 static int hf_smb_dfs_referral_version = -1;
467 static int hf_smb_dfs_referral_size = -1;
468 static int hf_smb_dfs_referral_server_type = -1;
469 static int hf_smb_dfs_referral_flags_strip = -1;
470 static int hf_smb_dfs_referral_node_offset = -1;
471 static int hf_smb_dfs_referral_node = -1;
472 static int hf_smb_dfs_referral_proximity = -1;
473 static int hf_smb_dfs_referral_ttl = -1;
474 static int hf_smb_dfs_referral_path_offset = -1;
475 static int hf_smb_dfs_referral_path = -1;
476 static int hf_smb_dfs_referral_alt_path_offset = -1;
477 static int hf_smb_dfs_referral_alt_path = -1;
478 static int hf_smb_end_of_search = -1;
479 static int hf_smb_last_name_offset = -1;
480 static int hf_smb_file_index = -1;
481 static int hf_smb_short_file_name = -1;
482 static int hf_smb_short_file_name_len = -1;
483 static int hf_smb_fs_id = -1;
484 static int hf_smb_sector_unit = -1;
485 static int hf_smb_fs_units = -1;
486 static int hf_smb_fs_sector = -1;
487 static int hf_smb_avail_units = -1;
488 static int hf_smb_volume_serial_num = -1;
489 static int hf_smb_volume_label_len = -1;
490 static int hf_smb_volume_label = -1;
491 static int hf_smb_free_alloc_units64 = -1;
492 static int hf_smb_max_name_len = -1;
493 static int hf_smb_fs_name_len = -1;
494 static int hf_smb_fs_name = -1;
495 static int hf_smb_device_char_removable = -1;
496 static int hf_smb_device_char_read_only = -1;
497 static int hf_smb_device_char_floppy = -1;
498 static int hf_smb_device_char_write_once = -1;
499 static int hf_smb_device_char_remote = -1;
500 static int hf_smb_device_char_mounted = -1;
501 static int hf_smb_device_char_virtual = -1;
502 static int hf_smb_fs_attr_css = -1;
503 static int hf_smb_fs_attr_cpn = -1;
504 static int hf_smb_fs_attr_pacls = -1;
505 static int hf_smb_fs_attr_fc = -1;
506 static int hf_smb_fs_attr_vq = -1;
507 static int hf_smb_fs_attr_dim = -1;
508 static int hf_smb_fs_attr_vic = -1;
509 static int hf_smb_setupword1 = -1;
510 static int hf_smb_setupword2 = -1;
511
512 static gint ett_smb = -1;
513 static gint ett_smb_hdr = -1;
514 static gint ett_smb_command = -1;
515 static gint ett_smb_fileattributes = -1;
516 static gint ett_smb_capabilities = -1;
517 static gint ett_smb_aflags = -1;
518 static gint ett_smb_dialect = -1;
519 static gint ett_smb_dialects = -1;
520 static gint ett_smb_mode = -1;
521 static gint ett_smb_rawmode = -1;
522 static gint ett_smb_flags = -1;
523 static gint ett_smb_flags2 = -1;
524 static gint ett_smb_desiredaccess = -1;
525 static gint ett_smb_search = -1;
526 static gint ett_smb_file = -1;
527 static gint ett_smb_openfunction = -1;
528 static gint ett_smb_filetype = -1;
529 static gint ett_smb_openaction = -1;
530 static gint ett_smb_writemode = -1;
531 static gint ett_smb_lock_type = -1;
532 static gint ett_smb_ssetupandxaction = -1;
533 static gint ett_smb_optionsup = -1;
534 static gint ett_smb_time_date = -1;
535 static gint ett_smb_64bit_time = -1;
536 static gint ett_smb_move_flags = -1;
537 static gint ett_smb_file_attributes = -1;
538 static gint ett_smb_search_resume_key = -1;
539 static gint ett_smb_search_dir_info = -1;
540 static gint ett_smb_unlocks = -1;
541 static gint ett_smb_unlock = -1;
542 static gint ett_smb_locks = -1;
543 static gint ett_smb_lock = -1;
544 static gint ett_smb_open_flags = -1;
545 static gint ett_smb_ipc_state = -1;
546 static gint ett_smb_open_action = -1;
547 static gint ett_smb_setup_action = -1;
548 static gint ett_smb_connect_flags = -1;
549 static gint ett_smb_connect_support_bits = -1;
550 static gint ett_smb_nt_access_mask = -1;
551 static gint ett_smb_nt_create_bits = -1;
552 static gint ett_smb_nt_create_options = -1;
553 static gint ett_smb_nt_share_access = -1;
554 static gint ett_smb_nt_security_flags = -1;
555 static gint ett_smb_nt_trans_setup = -1;
556 static gint ett_smb_nt_notify_completion_filter = -1;
557 static gint ett_smb_nt_ioctl_flags = -1;
558 static gint ett_smb_security_information_mask = -1;
559 static gint ett_smb_print_queue_entry = -1;
560 static gint ett_smb_transaction_flags = -1;
561 static gint ett_smb_transaction_params = -1;
562 static gint ett_smb_find_first2_flags = -1;
563 static gint ett_smb_transaction_data = -1;
564 static gint ett_smb_stream_info = -1;
565 static gint ett_smb_dfs_referrals = -1;
566 static gint ett_smb_dfs_referral = -1;
567 static gint ett_smb_dfs_referral_flags = -1;
568 static gint ett_smb_get_dfs_flags = -1;
569 static gint ett_smb_ff2_data = -1;
570 static gint ett_smb_device_characteristics = -1;
571 static gint ett_smb_fs_attributes = -1;
572
573 proto_tree *top_tree=NULL;     /* ugly */
574
575 static char *decode_smb_name(unsigned char);
576 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree, guint8 cmd);
577 static const gchar *get_unicode_or_ascii_string(tvbuff_t *tvb,
578     int *offsetp, packet_info *pinfo, int *len, gboolean nopad,
579     gboolean exactlen, guint16 *bcp);
580
581 /*
582  * Macros for use in the main dissector routines for an SMB.
583  */
584
585 #define WORD_COUNT      \
586         /* Word Count */                                \
587         wc = tvb_get_guint8(tvb, offset);               \
588         proto_tree_add_uint(tree, hf_smb_word_count,    \
589                 tvb, offset, 1, wc);                    \
590         offset += 1;                                    \
591         if(wc==0) goto bytecount;
592
593 #define BYTE_COUNT      \
594         bytecount:                                      \
595         bc = tvb_get_letohs(tvb, offset);               \
596         proto_tree_add_uint(tree, hf_smb_byte_count,    \
597                         tvb, offset, 2, bc);            \
598         offset += 2;                                    \
599         if(bc==0) goto endofcommand;
600
601 #define CHECK_BYTE_COUNT(len)   \
602         if (bc < len) goto endofcommand;
603
604 #define COUNT_BYTES(len)        \
605         offset += len;          \
606         bc -= len;
607
608 #define END_OF_SMB      \
609         if (bc != 0) { \
610                 proto_tree_add_text(tree, tvb, offset, bc, \
611                     "Extra byte parameters");           \
612                 offset += bc;                           \
613         }                                               \
614         endofcommand:
615
616 /*
617  * Macros for use in routines called by them.
618  */
619 #define CHECK_BYTE_COUNT_SUBR(len)      \
620         if (*bcp < len) {               \
621                 *trunc = TRUE;          \
622                 return offset;          \
623         }
624
625 #define CHECK_STRING_SUBR(fn)   \
626         if (fn == NULL) {       \
627                 *trunc = TRUE;  \
628                 return offset;  \
629         }
630
631 #define COUNT_BYTES_SUBR(len)   \
632         offset += len;          \
633         *bcp -= len;
634
635 /*
636  * Macros for use when dissecting transaction parameters and data
637  */
638 #define CHECK_BYTE_COUNT_TRANS(len)     \
639         if (bc < len) return offset;
640
641 #define CHECK_STRING_TRANS(fn)  \
642         if (fn == NULL) return offset;
643
644 #define COUNT_BYTES_TRANS(len)  \
645         offset += len;          \
646         bc -= len;
647
648 /*
649  * Macros for use in subrroutines dissecting transaction parameters or data
650  */
651 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
652         if (*bcp < len) return offset;
653
654 #define CHECK_STRING_TRANS_SUBR(fn)     \
655         if (fn == NULL) return offset;
656
657 #define COUNT_BYTES_TRANS_SUBR(len)     \
658         offset += len;                  \
659         *bcp -= len;
660
661 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
662    These variables and functions are used to match
663    responses with calls
664    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
665 /*
666  * The information we need to save about a request in order to show the
667  * frame number of the request in the dissection of the reply.
668  */
669 static GMemChunk *smb_saved_info_chunk = NULL;
670 static int smb_saved_info_init_count = 200;
671
672 /* matched smb_saved_info structures.
673   For matched smb_saved_info structures we store the smb_saved_info
674   structure twice in the table using the frame number as the key.
675   The frame number is guaranteed to be unique but if ever someone makes
676   some change that will renumber the frames in a capture we are in BIG trouble.
677   This is not likely though since that would break (among other things) all the
678   reassembly routines as well.
679
680   Oh, yes, the key is really a pointer, but we use it as if it was an integer.
681   Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
682 */
683 static gint
684 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
685 {
686         register int key1 = (int)k1;
687         register int key2 = (int)k2;
688         return key1==key2;
689 }
690 static guint
691 smb_saved_info_hash_matched(gconstpointer k)
692 {
693         register int key = (int)k;
694         return key;
695 }
696
697 /*
698  * The information we need to save about an NT Transaction request in order
699  * to dissect the reply.
700  */
701 typedef struct {
702         int subcmd;
703 } smb_nt_transact_info_t;
704
705 static GMemChunk *smb_nt_transact_info_chunk = NULL;
706 static int smb_nt_transact_info_init_count = 200;
707
708 /*
709  * The information we need to save about a Transaction2 request in order
710  * to dissect the reply.
711  */
712 typedef struct {
713         int subcmd;
714         int info_level;
715 } smb_transact2_info_t;
716
717 static GMemChunk *smb_transact2_info_chunk = NULL;
718 static int smb_transact2_info_init_count = 200;
719
720 /*
721  * The information we need to save about a Transaction request in order
722  * to dissect the reply; this includes information for use by the
723  * Remote API dissector.
724  */
725 static GMemChunk *smb_transact_info_chunk = NULL;
726 static int smb_transact_info_init_count = 200;
727
728 typedef struct conv_tables {
729         GHashTable *unmatched;
730         GHashTable *matched;
731 } conv_tables_t;
732 static GMemChunk *conv_tables_chunk = NULL;
733 static int conv_tables_count = 10;
734
735
736 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
737    End of request/response matching functions
738    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
739
740 static const value_string buffer_format_vals[] = {
741         {1,     "Data Block"},
742         {2,     "Dialect"},
743         {3,     "Pathname"},
744         {4,     "ASCII"},
745         {5,     "Variable Block"},
746         {0,     NULL}
747 };
748
749 /*
750  * UTIME - this is *almost* like a UNIX time stamp, except that it's
751  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
752  * January 1, 1970, 00:00:00 GMT.
753  *
754  * This means we have to do some extra work to convert it.  This code is
755  * based on the Samba code:
756  *
757  *      Unix SMB/Netbios implementation.
758  *      Version 1.9.
759  *      time handling functions
760  *      Copyright (C) Andrew Tridgell 1992-1998
761  */
762
763 /*
764  * Yield the difference between *A and *B, in seconds, ignoring leap
765  * seconds.
766  */
767 #define TM_YEAR_BASE 1900
768
769 static int
770 tm_diff(struct tm *a, struct tm *b)
771 {
772         int ay = a->tm_year + (TM_YEAR_BASE - 1);
773         int by = b->tm_year + (TM_YEAR_BASE - 1);
774         int intervening_leap_days =
775             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
776         int years = ay - by;
777         int days =
778             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
779         int hours = 24*days + (a->tm_hour - b->tm_hour);
780         int minutes = 60*hours + (a->tm_min - b->tm_min);
781         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
782
783         return seconds;
784 }
785
786 /*
787  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
788  * determined.
789  */
790 static int
791 TimeZone(time_t t)
792 {
793         struct tm *tm = gmtime(&t);
794         struct tm tm_utc;
795
796         if (tm == NULL)
797                 return 0;
798         tm_utc = *tm;
799         tm = localtime(&t);
800         if (tm == NULL)
801                 return 0;
802         return tm_diff(&tm_utc,tm);
803 }
804
805 /*
806  * Return the same value as TimeZone, but it should be more efficient.
807  *
808  * We keep a table of DST offsets to prevent calling localtime() on each 
809  * call of this function. This saves a LOT of time on many unixes.
810  *
811  * Updated by Paul Eggert <eggert@twinsun.com>
812  */
813 #ifndef CHAR_BIT
814 #define CHAR_BIT 8
815 #endif
816
817 #ifndef TIME_T_MIN
818 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
819                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
820 #endif
821 #ifndef TIME_T_MAX
822 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
823 #endif
824
825 static int
826 TimeZoneFaster(time_t t)
827 {
828         static struct dst_table {time_t start,end; int zone;} *tdt;
829         static struct dst_table *dst_table = NULL;
830         static int table_size = 0;
831         int i;
832         int zone = 0;
833
834         if (t == 0)
835                 t = time(NULL);
836
837         /* Tunis has a 8 day DST region, we need to be careful ... */
838 #define MAX_DST_WIDTH (365*24*60*60)
839 #define MAX_DST_SKIP (7*24*60*60)
840
841         for (i = 0; i < table_size; i++) {
842                 if (t >= dst_table[i].start && t <= dst_table[i].end)
843                         break;
844         }
845
846         if (i < table_size) {
847                 zone = dst_table[i].zone;
848         } else {
849                 time_t low,high;
850
851                 zone = TimeZone(t);
852                 if (dst_table == NULL)
853                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
854                 else
855                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
856                 if (tdt == NULL) {
857                         if (dst_table)
858                                 free(dst_table);
859                         table_size = 0;
860                 } else {
861                         dst_table = tdt;
862                         table_size++;
863     
864                         dst_table[i].zone = zone; 
865                         dst_table[i].start = dst_table[i].end = t;
866     
867                         /* no entry will cover more than 6 months */
868                         low = t - MAX_DST_WIDTH/2;
869                         if (t < low)
870                                 low = TIME_T_MIN;
871       
872                         high = t + MAX_DST_WIDTH/2;
873                         if (high < t)
874                                 high = TIME_T_MAX;
875       
876                         /*
877                          * Widen the new entry using two bisection searches.
878                          */
879                         while (low+60*60 < dst_table[i].start) {
880                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
881                                         t = dst_table[i].start - MAX_DST_SKIP;
882                                 else
883                                         t = low + (dst_table[i].start-low)/2;
884                                 if (TimeZone(t) == zone)
885                                         dst_table[i].start = t;
886                                 else
887                                         low = t;
888                         }
889
890                         while (high-60*60 > dst_table[i].end) {
891                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
892                                         t = dst_table[i].end + MAX_DST_SKIP;
893                                 else
894                                         t = high - (high-dst_table[i].end)/2;
895                                 if (TimeZone(t) == zone)
896                                         dst_table[i].end = t;
897                                 else
898                                         high = t;
899                         }
900                 }
901         }
902         return zone;
903 }
904
905 /*
906  * Return the UTC offset in seconds west of UTC, adjusted for extra time
907  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
908  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
909  * daylight savings transitions because some local times are ambiguous.
910  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
911  */
912 static int
913 LocTimeDiff(time_t lt)
914 {
915         int d = TimeZoneFaster(lt);
916         time_t t = lt + d;
917
918         /* if overflow occurred, ignore all the adjustments so far */
919         if (((t < lt) ^ (d < 0)))
920                 t = lt;
921
922         /*
923          * Now t should be close enough to the true UTC to yield the
924          * right answer.
925          */
926         return TimeZoneFaster(t);
927 }
928
929 static int
930 dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
931 {
932         guint32 timeval;
933         nstime_t ts;
934  
935         timeval = tvb_get_letohl(tvb, offset);
936         if (timeval == 0xffffffff) {
937                 proto_tree_add_text(tree, tvb, offset, 4,
938                     "%s: No time specified (0xffffffff)",
939                     proto_registrar_get_name(hf_date));
940                 offset += 4;
941                 return offset;
942         }
943
944         /*
945          * We add the local time offset.
946          */
947         ts.secs = timeval + LocTimeDiff(timeval);
948         ts.nsecs = 0;
949
950         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
951         offset += 4;
952  
953         return offset;
954 }
955
956 static int
957 dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *str, int hf_date)
958 {
959         proto_item *item = NULL;
960         proto_tree *tree = NULL;
961         nstime_t tv;
962
963         /* XXXX we need some way to represent this as a time
964            properly. For now we display everything as 8 bytes*/
965
966         if(parent_tree){
967                 item = proto_tree_add_text(parent_tree, tvb, offset, 8,
968                         str);
969                 tree = proto_item_add_subtree(item, ett_smb_64bit_time);
970         }
971
972         proto_tree_add_bytes_format(tree, hf_smb_unknown, tvb, offset, 8, tvb_get_ptr(tvb, offset, 8), "%s: can't decode this yet", str);
973
974         offset += 8;
975         return offset;
976 }
977
978 static int
979 dissect_smb_datetime(tvbuff_t *tvb, packet_info *pinfo,
980     proto_tree *parent_tree, int offset, int hf_date, int hf_dos_date,
981     int hf_dos_time, gboolean time_first)
982 {
983         guint16 dos_time, dos_date;
984         proto_item *item = NULL;
985         proto_tree *tree = NULL;
986         struct tm tm;
987         time_t t;
988         static const int mday_noleap[12] = {
989                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
990         };
991         static const int mday_leap[12] = {
992                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
993         };
994 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
995         nstime_t tv;
996
997         if (time_first) {
998                 dos_time = tvb_get_letohs(tvb, offset);
999                 dos_date = tvb_get_letohs(tvb, offset+2);
1000         } else {
1001                 dos_date = tvb_get_letohs(tvb, offset);
1002                 dos_time = tvb_get_letohs(tvb, offset+2);
1003         }
1004
1005         if ((dos_time == 0xffff && dos_time == 0xffff) ||
1006             (dos_time == 0 && dos_time == 0)) {
1007                 /*
1008                  * No date/time specified.
1009                  */
1010                 if(parent_tree){
1011                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1012                             "%s: No time specified (0x%08x)",
1013                             proto_registrar_get_name(hf_date),
1014                             (dos_date << 16) | dos_time);
1015                 }
1016                 offset += 4;
1017                 return offset;
1018         }
1019
1020         tm.tm_sec = (dos_time&0x1f)*2;
1021         tm.tm_min = (dos_time>>5)&0x3f;
1022         tm.tm_hour = (dos_time>>11)&0x1f;
1023         tm.tm_mday = dos_date&0x1f;
1024         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1025         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1026         tm.tm_isdst = -1;
1027
1028         /*
1029          * Do some sanity checks before calling "mktime()";
1030          * "mktime()" doesn't do them, it "normalizes" out-of-range
1031          * values.
1032          */
1033         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1034            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1035            (ISLEAP(tm.tm_year + 1900) ?
1036              tm.tm_mday > mday_leap[tm.tm_mon] :
1037              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1038              (t = mktime(&tm)) == -1) {
1039                 /*
1040                  * Invalid date/time.
1041                  */
1042                 if (parent_tree) {
1043                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1044                             "%s: Invalid time",
1045                             proto_registrar_get_name(hf_date));
1046                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1047                         if (time_first) {
1048                                 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);
1049                                 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);
1050                         } else {
1051                                 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);
1052                                 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);
1053                         }
1054                 }
1055                 offset += 4;
1056                 return offset;
1057         }
1058
1059         tv.secs = t;
1060         tv.nsecs = 0;
1061
1062         if(parent_tree){
1063                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1064                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1065                 if (time_first) {
1066                         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);
1067                         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);
1068                 } else {
1069                         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);
1070                         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);
1071                 }
1072         }
1073
1074         offset += 4;
1075
1076         return offset;
1077 }
1078
1079
1080 static const value_string da_access_vals[] = {
1081         { 0,            "Open for reading"},
1082         { 1,            "Open for writing"},
1083         { 2,            "Open for reading and writing"},
1084         { 3,            "Open for execute"},
1085         {0, NULL}
1086 };
1087 static const value_string da_sharing_vals[] = {
1088         { 0,            "Compatibility mode"},
1089         { 1,            "Deny read/write/execute (exclusive)"},
1090         { 2,            "Deny write"},
1091         { 3,            "Deny read/execute"},
1092         { 4,            "Deny none"},
1093         {0, NULL}
1094 };
1095 static const value_string da_locality_vals[] = {
1096         { 0,            "Locality of reference unknown"},
1097         { 1,            "Mainly sequential access"},
1098         { 2,            "Mainly random access"},
1099         { 3,            "Random access with some locality"},
1100         {0, NULL}
1101 };
1102 static const true_false_string tfs_da_caching = {
1103         "Do not cache this file",
1104         "Caching permitted on this file"
1105 };
1106 static const true_false_string tfs_da_writetru = {
1107         "Write through enabled",
1108         "Write through disabled"
1109 };
1110 static int
1111 dissect_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *type)
1112 {
1113         guint16 mask;
1114         proto_item *item = NULL;
1115         proto_tree *tree = NULL;
1116
1117         mask = tvb_get_letohs(tvb, offset);
1118
1119         if(parent_tree){
1120                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1121                         "%s Access: 0x%04x", type, mask);
1122                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1123         }
1124
1125         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1126                 tvb, offset, 2, mask);
1127         proto_tree_add_boolean(tree, hf_smb_access_caching,
1128                 tvb, offset, 2, mask);
1129         proto_tree_add_uint(tree, hf_smb_access_locality,
1130                 tvb, offset, 2, mask);
1131         proto_tree_add_uint(tree, hf_smb_access_sharing,
1132                 tvb, offset, 2, mask);
1133         proto_tree_add_uint(tree, hf_smb_access_mode,
1134                 tvb, offset, 2, mask);
1135
1136         offset += 2;
1137
1138         return offset;
1139 }
1140
1141 #define FILE_ATTRIBUTE_READ_ONLY                0x00000001
1142 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
1143 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
1144 #define FILE_ATTRIBUTE_VOLUME                   0x00000008
1145 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
1146 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
1147 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
1148 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
1149 #define FILE_ATTRIBUTE_TEMPORARY                0x00000100
1150 #define FILE_ATTRIBUTE_SPARSE                   0x00000200
1151 #define FILE_ATTRIBUTE_REPARSE                  0x00000400
1152 #define FILE_ATTRIBUTE_COMPRESSED               0x00000800
1153 #define FILE_ATTRIBUTE_OFFLINE                  0x00001000
1154 #define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED      0x00002000
1155 #define FILE_ATTRIBUTE_ENCRYPTED                0x00004000
1156
1157 /*
1158  * These are flags to be used in NT Create operations.
1159  */
1160 #define FILE_ATTRIBUTE_WRITE_THROUGH            0x80000000
1161 #define FILE_ATTRIBUTE_NO_BUFFERING             0x20000000
1162 #define FILE_ATTRIBUTE_RANDOM_ACCESS            0x10000000
1163 #define FILE_ATTRIBUTE_SEQUENTIAL_SCAN          0x08000000
1164 #define FILE_ATTRIBUTE_DELETE_ON_CLOSE          0x04000000
1165 #define FILE_ATTRIBUTE_BACKUP_SEMANTICS         0x02000000
1166 #define FILE_ATTRIBUTE_POSIX_SEMANTICS          0x01000000
1167
1168 static const true_false_string tfs_file_attribute_write_through = {
1169         "This object requires WRITE THROUGH",
1170         "This object does NOT require write through",
1171 };
1172 static const true_false_string tfs_file_attribute_no_buffering = {
1173         "This object requires NO BUFFERING",
1174         "This object can be buffered",
1175 };
1176 static const true_false_string tfs_file_attribute_random_access = {
1177         "This object will be RANDOM ACCESSed",
1178         "Random access is NOT requested",
1179 };
1180 static const true_false_string tfs_file_attribute_sequential_scan = {
1181         "This object is optimized for SEQUENTIAL SCAN",
1182         "This object is NOT optimized for sequential scan",
1183 };
1184 static const true_false_string tfs_file_attribute_delete_on_close = {
1185         "This object will be DELETED ON CLOSE",
1186         "This object will not be deleted on close",
1187 };
1188 static const true_false_string tfs_file_attribute_backup_semantics = {
1189         "This object supports BACKUP SEMANTICS",
1190         "This object does NOT support backup semantics",
1191 };
1192 static const true_false_string tfs_file_attribute_posix_semantics = {
1193         "This object supports POSIX SEMANTICS",
1194         "This object does NOT support POSIX semantics",
1195 };
1196 static const true_false_string tfs_file_attribute_read_only = {
1197         "This file is READ ONLY",
1198         "This file is NOT read only",
1199 };
1200 static const true_false_string tfs_file_attribute_hidden = {
1201         "This is a HIDDEN file",
1202         "This is NOT a hidden file"
1203 };
1204 static const true_false_string tfs_file_attribute_system = {
1205         "This is a SYSTEM file",
1206         "This is NOT a system file"
1207 };
1208 static const true_false_string tfs_file_attribute_volume = {
1209         "This is a VOLUME ID",
1210         "This is NOT a volume ID"
1211 };
1212 static const true_false_string tfs_file_attribute_directory = {
1213         "This is a DIRECTORY",
1214         "This is NOT a directory"
1215 };
1216 static const true_false_string tfs_file_attribute_archive = {
1217         "This is an ARCHIVE file",
1218         "This is NOT an archive file"
1219 };
1220 static const true_false_string tfs_file_attribute_device = {
1221         "This is a DEVICE",
1222         "This is NOT a device"
1223 };
1224 static const true_false_string tfs_file_attribute_normal = {
1225         "This file is an ordinary file",
1226         "This file has some attribute set"
1227 };
1228 static const true_false_string tfs_file_attribute_temporary = {
1229         "This is a TEMPORARY file",
1230         "This is NOT a temporary file"
1231 };
1232 static const true_false_string tfs_file_attribute_sparse = {
1233         "This is a SPARSE file",
1234         "This is NOT a sparse file"
1235 };
1236 static const true_false_string tfs_file_attribute_reparse = {
1237         "This file has an associated REPARSE POINT",
1238         "This file does NOT have an associated reparse point"
1239 };
1240 static const true_false_string tfs_file_attribute_compressed = {
1241         "This is a COMPRESSED file",
1242         "This is NOT a compressed file"
1243 };
1244 static const true_false_string tfs_file_attribute_offline = {
1245         "This file is OFFLINE",
1246         "This file is NOT offline"
1247 };
1248 static const true_false_string tfs_file_attribute_not_content_indexed = {
1249         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1250         "This file MAY be indexed by the content indexing service"
1251 };
1252 static const true_false_string tfs_file_attribute_encrypted = {
1253         "This is an ENCRYPTED file",
1254         "This is NOT an encrypted file"
1255 };
1256
1257 static int
1258 dissect_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1259 {
1260         guint16 mask;
1261         proto_item *item = NULL;
1262         proto_tree *tree = NULL;
1263
1264         mask = tvb_get_letohs(tvb, offset);
1265
1266         if(parent_tree){
1267                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1268                         "File Attributes: 0x%04x", mask);
1269                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1270         }
1271         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1272                 tvb, offset, 2, mask);
1273         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1274                 tvb, offset, 2, mask);
1275         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1276                 tvb, offset, 2, mask);
1277         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1278                 tvb, offset, 2, mask);
1279         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1280                 tvb, offset, 2, mask);
1281         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1282                 tvb, offset, 2, mask);
1283
1284         offset += 2;
1285
1286         return offset;
1287 }
1288
1289 /* 3.11 */
1290 static int
1291 dissect_file_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1292 {
1293         guint32 mask;
1294         proto_item *item = NULL;
1295         proto_tree *tree = NULL;
1296
1297         mask = tvb_get_letohl(tvb, offset);
1298
1299         if(parent_tree){
1300                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1301                         "File Attributes: 0x%08x", mask);
1302                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1303         }
1304
1305         /*
1306          * XXX - Network Monitor disagrees on some of the
1307          * bits, e.g. the bits above temporary are "atomic write"
1308          * and "transaction write", and it says nothing about the
1309          * bits above that.
1310          *
1311          * Does the Win32 API documentation, or the NT Native API book,
1312          * suggest anything?
1313          */
1314         proto_tree_add_boolean(tree, hf_smb_file_eattr_write_through,
1315                 tvb, offset, 4, mask);
1316         proto_tree_add_boolean(tree, hf_smb_file_eattr_no_buffering,
1317                 tvb, offset, 4, mask);
1318         proto_tree_add_boolean(tree, hf_smb_file_eattr_random_access,
1319                 tvb, offset, 4, mask);
1320         proto_tree_add_boolean(tree, hf_smb_file_eattr_sequential_scan,
1321                 tvb, offset, 4, mask);
1322         proto_tree_add_boolean(tree, hf_smb_file_eattr_delete_on_close,
1323                 tvb, offset, 4, mask);
1324         proto_tree_add_boolean(tree, hf_smb_file_eattr_backup_semantics,
1325                 tvb, offset, 4, mask);
1326         proto_tree_add_boolean(tree, hf_smb_file_eattr_posix_semantics,
1327                 tvb, offset, 4, mask);
1328         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1329                 tvb, offset, 4, mask);
1330         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1331                 tvb, offset, 4, mask);
1332         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1333                 tvb, offset, 4, mask);
1334         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1335                 tvb, offset, 4, mask);
1336         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1337                 tvb, offset, 4, mask);
1338         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1339                 tvb, offset, 4, mask);
1340         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1341                 tvb, offset, 4, mask);
1342         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1343                 tvb, offset, 4, mask);
1344         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1345                 tvb, offset, 4, mask);
1346         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1347                 tvb, offset, 4, mask);
1348         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1349                 tvb, offset, 4, mask);
1350         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1351                 tvb, offset, 4, mask);
1352         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1353                 tvb, offset, 4, mask);
1354         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1355                 tvb, offset, 4, mask);
1356         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1357                 tvb, offset, 4, mask);
1358
1359         offset += 4;
1360
1361         return offset;
1362 }
1363
1364 static int
1365 dissect_dir_info_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1366 {
1367         guint8 mask;
1368         proto_item *item = NULL;
1369         proto_tree *tree = NULL;
1370
1371         mask = tvb_get_guint8(tvb, offset);
1372
1373         if(parent_tree){
1374                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1375                         "File Attributes: 0x%02x", mask);
1376                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1377         }
1378         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1379                 tvb, offset, 1, mask);
1380         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1381                 tvb, offset, 1, mask);
1382         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1383                 tvb, offset, 1, mask);
1384         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1385                 tvb, offset, 1, mask);
1386         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1387                 tvb, offset, 1, mask);
1388         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1389                 tvb, offset, 1, mask);
1390
1391         offset += 1;
1392
1393         return offset;
1394 }
1395
1396 static const true_false_string tfs_search_attribute_read_only = {
1397         "Include READ ONLY files in search results",
1398         "Do NOT include read only files in search results",
1399 };
1400 static const true_false_string tfs_search_attribute_hidden = {
1401         "Include HIDDEN files in search results",
1402         "Do NOT include hidden files in search results"
1403 };
1404 static const true_false_string tfs_search_attribute_system = {
1405         "Include SYSTEM files in search results",
1406         "Do NOT include system files in search results"
1407 };
1408 static const true_false_string tfs_search_attribute_volume = {
1409         "Include VOLUME IDs in search results",
1410         "Do NOT include volume IDs in search results"
1411 };
1412 static const true_false_string tfs_search_attribute_directory = {
1413         "Include DIRECTORIES in search results",
1414         "Do NOT include directories in search results"
1415 };
1416 static const true_false_string tfs_search_attribute_archive = {
1417         "Include ARCHIVE files in search results",
1418         "Do NOT include archive files in search results"
1419 };
1420
1421 static int
1422 dissect_search_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1423 {
1424         guint16 mask;
1425         proto_item *item = NULL;
1426         proto_tree *tree = NULL;
1427
1428         mask = tvb_get_letohs(tvb, offset);
1429
1430         if(parent_tree){
1431                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1432                         "Search Attributes: 0x%04x", mask);
1433                 tree = proto_item_add_subtree(item, ett_smb_search);
1434         }
1435
1436         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1437                 tvb, offset, 2, mask);
1438         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1439                 tvb, offset, 2, mask);
1440         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1441                 tvb, offset, 2, mask);  
1442         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1443                 tvb, offset, 2, mask);
1444         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1445                 tvb, offset, 2, mask);
1446         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1447                 tvb, offset, 2, mask);
1448
1449         offset += 2;
1450         return offset;
1451 }
1452
1453 #if 0
1454 /*
1455  * XXX - this isn't used.
1456  * Is this used for anything?  NT Create AndX doesn't use it.
1457  * Is there some 16-bit attribute field with more bits than Read Only,
1458  * Hidden, System, Volume ID, Directory, and Archive?
1459  */
1460 static int
1461 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1462 {
1463         guint32 mask;
1464         proto_item *item = NULL;
1465         proto_tree *tree = NULL;
1466
1467         mask = tvb_get_letohl(tvb, offset);
1468
1469         if(parent_tree){
1470                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1471                         "File Attributes: 0x%08x", mask);
1472                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1473         }
1474         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1475                 tvb, offset, 2, mask);
1476         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1477                 tvb, offset, 2, mask);
1478         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1479                 tvb, offset, 2, mask);
1480         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1481                 tvb, offset, 2, mask);
1482         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1483                 tvb, offset, 2, mask);
1484         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1485                 tvb, offset, 2, mask);
1486         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1487                 tvb, offset, 2, mask);
1488         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1489                 tvb, offset, 2, mask);
1490         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1491                 tvb, offset, 2, mask);
1492         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1493                 tvb, offset, 2, mask);
1494         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1495                 tvb, offset, 2, mask);
1496         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1497                 tvb, offset, 2, mask);
1498         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1499                 tvb, offset, 2, mask);
1500         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1501                 tvb, offset, 2, mask);
1502         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1503                 tvb, offset, 2, mask);
1504
1505         offset += 2;
1506
1507         return offset;
1508 }
1509 #endif
1510
1511
1512 #define SERVER_CAP_RAW_MODE            0x00000001
1513 #define SERVER_CAP_MPX_MODE            0x00000002
1514 #define SERVER_CAP_UNICODE             0x00000004
1515 #define SERVER_CAP_LARGE_FILES         0x00000008
1516 #define SERVER_CAP_NT_SMBS             0x00000010
1517 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1518 #define SERVER_CAP_STATUS32            0x00000040
1519 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1520 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1521 #define SERVER_CAP_NT_FIND             0x00000200
1522 #define SERVER_CAP_DFS                 0x00001000
1523 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1524 #define SERVER_CAP_LARGE_READX         0x00004000
1525 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1526 #define SERVER_CAP_UNIX                0x00800000
1527 #define SERVER_CAP_RESERVED            0x02000000
1528 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1529 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1530 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1531 static const true_false_string tfs_server_cap_raw_mode = {
1532         "Read Raw and Write Raw are supported",
1533         "Read Raw and Write Raw are not supported"
1534 };
1535 static const true_false_string tfs_server_cap_mpx_mode = {
1536         "Read Mpx and Write Mpx are supported",
1537         "Read Mpx and Write Mpx are not supported"
1538 };
1539 static const true_false_string tfs_server_cap_unicode = {
1540         "Unicode strings are supported",
1541         "Unicode strings are not supported"
1542 };
1543 static const true_false_string tfs_server_cap_large_files = {
1544         "Large files are supported",
1545         "Large files are not supported",
1546 };
1547 static const true_false_string tfs_server_cap_nt_smbs = {
1548         "NT SMBs are supported",
1549         "NT SMBs are not supported"
1550 };
1551 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1552         "RPC remote APIs are supported",
1553         "RPC remote APIs are not supported"
1554 };
1555 static const true_false_string tfs_server_cap_nt_status = {
1556         "NT status codes are supported",
1557         "NT status codes are not supported"
1558 };
1559 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1560         "Level 2 oplocks are supported",
1561         "Level 2 oplocks are not supported"
1562 };
1563 static const true_false_string tfs_server_cap_lock_and_read = {
1564         "Lock and Read is supported",
1565         "Lock and Read is not supported"
1566 };
1567 static const true_false_string tfs_server_cap_nt_find = {
1568         "NT Find is supported",
1569         "NT Find is not supported"
1570 };
1571 static const true_false_string tfs_server_cap_dfs = {
1572         "Dfs is supported",
1573         "Dfs is not supported"
1574 };
1575 static const true_false_string tfs_server_cap_infolevel_passthru = {
1576         "NT information level request passthrough is supported",
1577         "NT information level request passthrough is not supported"
1578 };
1579 static const true_false_string tfs_server_cap_large_readx = {
1580         "Large Read andX is supported",
1581         "Large Read andX is not supported"
1582 };
1583 static const true_false_string tfs_server_cap_large_writex = {
1584         "Large Write andX is supported",
1585         "Large Write andX is not supported"
1586 };
1587 static const true_false_string tfs_server_cap_unix = {
1588         "UNIX extensions are supported",
1589         "UNIX extensions are not supported"
1590 };
1591 static const true_false_string tfs_server_cap_reserved = {
1592         "Reserved",
1593         "Reserved"
1594 };
1595 static const true_false_string tfs_server_cap_bulk_transfer = {
1596         "Bulk Read and Bulk Write are supported",
1597         "Bulk Read and Bulk Write are not supported"
1598 };
1599 static const true_false_string tfs_server_cap_compressed_data = {
1600         "Compressed data transfer is supported",
1601         "Compressed data transfer is not supported"
1602 };
1603 static const true_false_string tfs_server_cap_extended_security = {
1604         "Extended security exchanges are supported",
1605         "Extended security exchanges are not supported"
1606 };
1607 static int
1608 dissect_negprot_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1609 {
1610         guint32 mask;
1611         proto_item *item = NULL;
1612         proto_tree *tree = NULL;
1613
1614         mask = tvb_get_letohl(tvb, offset);
1615
1616         if(parent_tree){
1617                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1618                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1619         }
1620
1621         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1622                 tvb, offset, 4, mask);
1623         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1624                 tvb, offset, 4, mask);
1625         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1626                 tvb, offset, 4, mask);
1627         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1628                 tvb, offset, 4, mask);
1629         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1630                 tvb, offset, 4, mask);
1631         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1632                 tvb, offset, 4, mask);
1633         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1634                 tvb, offset, 4, mask);
1635         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1636                 tvb, offset, 4, mask);
1637         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1638                 tvb, offset, 4, mask);
1639         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1640                 tvb, offset, 4, mask);
1641         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1642                 tvb, offset, 4, mask);
1643         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1644                 tvb, offset, 4, mask);
1645         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1646                 tvb, offset, 4, mask);
1647         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1648                 tvb, offset, 4, mask);
1649         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1650                 tvb, offset, 4, mask);
1651         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1652                 tvb, offset, 4, mask);
1653         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1654                 tvb, offset, 4, mask);
1655         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1656                 tvb, offset, 4, mask);
1657         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1658                 tvb, offset, 4, mask);
1659
1660         return mask;
1661 }
1662
1663 #define RAWMODE_READ   0x01
1664 #define RAWMODE_WRITE  0x02
1665 static const true_false_string tfs_rm_read = {
1666         "Read Raw is supported",
1667         "Read Raw is not supported"
1668 };
1669 static const true_false_string tfs_rm_write = {
1670         "Write Raw is supported",
1671         "Write Raw is not supported"
1672 };
1673
1674 static int
1675 dissect_negprot_rawmode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1676 {
1677         guint16 mask;
1678         proto_item *item = NULL;
1679         proto_tree *tree = NULL;
1680
1681         mask = tvb_get_letohs(tvb, offset);
1682
1683         if(parent_tree){
1684                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
1685                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
1686         }
1687
1688         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
1689         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
1690
1691         offset += 2;
1692
1693         return offset;
1694 }
1695
1696 #define SECURITY_MODE_MODE             0x01
1697 #define SECURITY_MODE_PASSWORD         0x02
1698 #define SECURITY_MODE_SIGNATURES       0x04
1699 #define SECURITY_MODE_SIG_REQUIRED     0x08
1700 static const true_false_string tfs_sm_mode = {
1701         "USER security mode",
1702         "SHARE security mode"
1703 };
1704 static const true_false_string tfs_sm_password = {
1705         "ENCRYPTED password. Use challenge/response",
1706         "PLAINTEXT password"
1707 };
1708 static const true_false_string tfs_sm_signatures = {
1709         "Security signatures ENABLED",
1710         "Security signatures NOT enabled"
1711 };
1712 static const true_false_string tfs_sm_sig_required = {
1713         "Security signatures REQUIRED",
1714         "Security signatures NOT required"
1715 };
1716
1717 static int
1718 dissect_negprot_security_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int wc)
1719 {
1720         guint16 mask = 0;
1721         proto_item *item = NULL;
1722         proto_tree *tree = NULL;
1723
1724         switch(wc){
1725         case 13:
1726                 mask = tvb_get_letohs(tvb, offset);
1727                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1728                                 "Security Mode: 0x%04x", mask);
1729                 tree = proto_item_add_subtree(item, ett_smb_mode);
1730                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
1731                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
1732                 offset += 2;
1733                 break;
1734
1735         case 17:
1736                 mask = tvb_get_guint8(tvb, offset);
1737                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1738                                 "Security Mode: 0x%02x", mask);
1739                 tree = proto_item_add_subtree(item, ett_smb_mode);
1740                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
1741                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
1742                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
1743                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
1744                 offset += 1;
1745                 break;
1746         }
1747
1748         return offset;
1749 }
1750
1751 static int
1752 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1753 {
1754         proto_item *it = NULL;
1755         proto_tree *tr = NULL;
1756         guint16 bc;
1757         guint8 wc;
1758
1759         WORD_COUNT;
1760
1761         BYTE_COUNT;
1762
1763         if(tree){
1764                 it = proto_tree_add_text(tree, tvb, offset, bc,
1765                                 "Requested Dialects");
1766                 tr = proto_item_add_subtree(it, ett_smb_dialects);
1767         }
1768
1769         while(bc){
1770                 int len;
1771                 int old_offset = offset;
1772                 const guint8 *str;
1773                 proto_item *dit = NULL;
1774                 proto_tree *dtr = NULL;
1775
1776                 /* XXX - what if this runs past bc? */
1777                 len = tvb_strsize(tvb, offset+1);
1778                 str = tvb_get_ptr(tvb, offset+1, len);
1779
1780                 if(tr){
1781                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
1782                                         "Dialect: %s", str);
1783                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
1784                 }
1785
1786                 /* Buffer Format */
1787                 CHECK_BYTE_COUNT(1);
1788                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
1789                         TRUE);
1790                 COUNT_BYTES(1);
1791
1792                 /*Dialect Name */
1793                 CHECK_BYTE_COUNT(len);
1794                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
1795                         len, str);
1796                 COUNT_BYTES(len);
1797         }
1798
1799         END_OF_SMB
1800
1801         return offset;
1802 }
1803
1804 static int
1805 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
1806 {
1807         guint8 wc;
1808         guint16 dialect;
1809         const char *dn;
1810         int dn_len;
1811         guint16 bc;
1812         guint16 ekl=0;
1813         guint32 caps=0;
1814         gint16 tz;
1815
1816         WORD_COUNT;
1817
1818         /* Dialect Index */
1819         dialect = tvb_get_letohs(tvb, offset);
1820         switch(wc){
1821         case 1:
1822                 if(dialect==0xffff){
1823                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
1824                                 tvb, offset, 2, dialect,
1825                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
1826                 } else {
1827                         proto_tree_add_uint(tree, hf_smb_dialect_index,
1828                                 tvb, offset, 2, dialect);
1829                 }
1830                 break;
1831         case 13:
1832                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
1833                         tvb, offset, 2, dialect,
1834                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
1835                 break;
1836         case 17:
1837                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
1838                         tvb, offset, 2, dialect,
1839                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
1840                 break;
1841         default:
1842                 proto_tree_add_text(tree, tvb, offset, wc*2,
1843                         "Words for unknown response format");
1844                 offset += wc*2;
1845                 goto bytecount;
1846         }
1847         offset += 2;
1848
1849         switch(wc){
1850         case 13:
1851                 /* Security Mode */
1852                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset,
1853                                 wc);
1854
1855                 /* Maximum Transmit Buffer Size */
1856                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
1857                         tvb, offset, 2, TRUE);
1858                 offset += 2;
1859
1860                 /* Maximum Multiplex Count */
1861                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
1862                         tvb, offset, 2, TRUE);
1863                 offset += 2;
1864
1865                 /* Maximum Vcs Number */
1866                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
1867                         tvb, offset, 2, TRUE);
1868                 offset += 2;
1869
1870                 /* raw mode */
1871                 offset = dissect_negprot_rawmode(tvb, pinfo, tree, offset);
1872
1873                 /* session key */
1874                 proto_tree_add_item(tree, hf_smb_session_key,
1875                         tvb, offset, 4, TRUE);
1876                 offset += 4;
1877
1878                 /* current time and date at server */
1879                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
1880                     TRUE);
1881
1882                 /* time zone */
1883                 tz = tvb_get_letohs(tvb, offset);
1884                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
1885                 offset += 2;
1886
1887                 /* encryption key length */
1888                 ekl = tvb_get_letohs(tvb, offset);
1889                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
1890                 offset += 2;
1891
1892                 /* 2 reserved bytes */
1893                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
1894                 offset += 2;
1895
1896                 break;
1897
1898         case 17:
1899                 /* Security Mode */
1900                 offset = dissect_negprot_security_mode(tvb, pinfo, tree, offset, wc);
1901
1902                 /* Maximum Multiplex Count */
1903                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
1904                         tvb, offset, 2, TRUE);
1905                 offset += 2;
1906
1907                 /* Maximum Vcs Number */
1908                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
1909                         tvb, offset, 2, TRUE);
1910                 offset += 2;
1911
1912                 /* Maximum Transmit Buffer Size */
1913                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
1914                         tvb, offset, 4, TRUE);
1915                 offset += 4;
1916
1917                 /* maximum raw buffer size */
1918                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
1919                         tvb, offset, 4, TRUE);
1920                 offset += 4;
1921
1922                 /* session key */
1923                 proto_tree_add_item(tree, hf_smb_session_key,
1924                         tvb, offset, 4, TRUE);
1925                 offset += 4;
1926
1927                 /* server capabilities */
1928                 caps = dissect_negprot_capabilities(tvb, pinfo, tree, offset);
1929                 offset += 4;
1930
1931                 /* system time */
1932                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
1933                                 "System Time", hf_smb_system_time);
1934
1935                 /* time zone */
1936                 tz = tvb_get_letohs(tvb, offset);
1937                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
1938                         tvb, offset, 2, tz,
1939                         "Server Time Zone: %d min from UTC", tz);
1940                 offset += 2;
1941
1942                 /* encryption key length */
1943                 ekl = tvb_get_guint8(tvb, offset);
1944                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
1945                         tvb, offset, 1, ekl);
1946                 offset += 1;
1947
1948                 break;
1949         }
1950
1951         BYTE_COUNT;
1952
1953         switch(wc){
1954         case 13:
1955                 /* challenge/response encryption key */
1956                 if(ekl){
1957                         CHECK_BYTE_COUNT(ekl);
1958                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
1959                         COUNT_BYTES(ekl);
1960                 }
1961
1962                 /* domain */
1963                 dn = get_unicode_or_ascii_string(tvb, &offset,
1964                         pinfo, &dn_len, FALSE, FALSE, &bc);
1965                 if (dn == NULL)
1966                         goto endofcommand;
1967                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
1968                         offset, dn_len,dn);
1969                 COUNT_BYTES(dn_len);
1970                 break;
1971
1972         case 17:
1973                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
1974                         smb_info_t *si;
1975
1976                         /* challenge/response encryption key */
1977                         /* XXX - is this aligned on an even boundary? */
1978                         if(ekl){
1979                                 CHECK_BYTE_COUNT(ekl);
1980                                 proto_tree_add_item(tree, hf_smb_encryption_key,
1981                                         tvb, offset, ekl, TRUE);
1982                                 COUNT_BYTES(ekl);
1983                         }
1984
1985                         /* domain */
1986                         /* this string is special, unicode is flagged in caps */
1987                         /* This string is NOT padded to be 16bit aligned. (seen in actual capture) */
1988                         si = pinfo->private_data;
1989                         si->unicode = (caps&SERVER_CAP_UNICODE);
1990                         dn = get_unicode_or_ascii_string(tvb,
1991                                 &offset, pinfo, &dn_len, TRUE, FALSE,
1992                                 &bc);
1993                         if (dn == NULL)
1994                                 goto endofcommand;
1995                         proto_tree_add_string(tree, hf_smb_primary_domain,
1996                                 tvb, offset, dn_len, dn);
1997                         COUNT_BYTES(dn_len);
1998                 } else {
1999                         int len;
2000
2001                         /* guid */
2002                         /* XXX - show it in the standard Microsoft format
2003                            for GUIDs? */
2004                         CHECK_BYTE_COUNT(16);
2005                         proto_tree_add_item(tree, hf_smb_server_guid,
2006                                 tvb, offset, 16, TRUE);
2007                         COUNT_BYTES(16);
2008
2009                         /* security blob */
2010                         /* XXX - is this ASN.1-encoded?  Is it a Kerberos
2011                            data structure, at least in NT 5.0-and-later
2012                            server replies? */
2013                         if(bc){
2014                                 proto_tree_add_item(tree, hf_smb_security_blob,
2015                                         tvb, offset, bc, TRUE);
2016                                 COUNT_BYTES(bc);
2017                         }
2018                 }
2019                 break;
2020         }
2021
2022         END_OF_SMB
2023
2024         return offset;
2025 }
2026
2027
2028 static int
2029 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2030 {
2031         int dn_len;
2032         const char *dn;
2033         guint8 wc;
2034         guint16 bc;
2035
2036         WORD_COUNT;
2037  
2038         BYTE_COUNT;
2039
2040         /* buffer format */
2041         CHECK_BYTE_COUNT(1);
2042         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2043         COUNT_BYTES(1);
2044
2045         /* dir name */
2046         dn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &dn_len,
2047                 FALSE, FALSE, &bc);
2048         if (dn == NULL)
2049                 goto endofcommand;
2050         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2051                 dn);
2052         COUNT_BYTES(dn_len);
2053
2054         if (check_col(pinfo->fd, COL_INFO)) {
2055                 col_append_fstr(pinfo->fd, COL_INFO, ", Directory: %s", dn);
2056         }
2057
2058         END_OF_SMB
2059
2060         return offset;
2061 }
2062
2063 static int
2064 dissect_empty(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2065 {
2066         guint8 wc;
2067         guint16 bc;
2068  
2069         WORD_COUNT;
2070  
2071         BYTE_COUNT;
2072
2073         END_OF_SMB
2074
2075         return offset;
2076 }
2077
2078 static int
2079 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2080 {
2081         guint16 ec, bc;
2082         guint8 wc;
2083
2084         WORD_COUNT;
2085
2086         /* echo count */
2087         ec = tvb_get_letohs(tvb, offset);
2088         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2089         offset += 2;
2090
2091         BYTE_COUNT;
2092
2093         if (bc != 0) {
2094                 /* echo data */
2095                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2096                 COUNT_BYTES(bc);
2097         }
2098
2099         END_OF_SMB
2100
2101         return offset;
2102 }
2103
2104 static int
2105 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2106 {
2107         guint16 bc;
2108         guint8 wc;
2109
2110         WORD_COUNT;
2111
2112         /* echo sequence number */
2113         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2114         offset += 2;
2115
2116         BYTE_COUNT;
2117
2118         if (bc != 0) {
2119                 /* echo data */
2120                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2121                 COUNT_BYTES(bc);
2122         }
2123
2124         END_OF_SMB
2125
2126         return offset;
2127 }
2128
2129 static int
2130 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2131 {
2132         int an_len, pwlen;
2133         const char *an;
2134         guint8 wc;
2135         guint16 bc;
2136
2137         WORD_COUNT;
2138  
2139         BYTE_COUNT;
2140
2141         /* buffer format */
2142         CHECK_BYTE_COUNT(1);
2143         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2144         COUNT_BYTES(1);
2145
2146         /* Path */
2147         an = get_unicode_or_ascii_string(tvb, &offset,
2148                 pinfo, &an_len, FALSE, FALSE, &bc);
2149         if (an == NULL)
2150                 goto endofcommand;
2151         proto_tree_add_string(tree, hf_smb_path, tvb,
2152                 offset, an_len, an);
2153         COUNT_BYTES(an_len);
2154
2155         if (check_col(pinfo->fd, COL_INFO)) {
2156                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", an);
2157         }
2158
2159         /* buffer format */
2160         CHECK_BYTE_COUNT(1);
2161         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2162         COUNT_BYTES(1);
2163
2164         /* password, ANSI */
2165         /* XXX - what if this runs past bc? */
2166         pwlen = tvb_strsize(tvb, offset);
2167         CHECK_BYTE_COUNT(pwlen);
2168         proto_tree_add_item(tree, hf_smb_password,
2169                 tvb, offset, pwlen, TRUE);
2170         COUNT_BYTES(pwlen);
2171
2172         /* buffer format */
2173         CHECK_BYTE_COUNT(1);
2174         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2175         COUNT_BYTES(1);
2176
2177         /* Service */
2178         an = get_unicode_or_ascii_string(tvb, &offset,
2179                 pinfo, &an_len, FALSE, FALSE, &bc);
2180         if (an == NULL)
2181                 goto endofcommand;
2182         proto_tree_add_string(tree, hf_smb_service, tvb,
2183                 offset, an_len, an);
2184         COUNT_BYTES(an_len);
2185
2186         END_OF_SMB
2187
2188         return offset;
2189 }
2190
2191 static int
2192 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2193 {
2194         guint8 wc;
2195         guint16 bc;
2196
2197         WORD_COUNT;
2198  
2199         /* Maximum Buffer Size */
2200         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2201         offset += 2;
2202
2203         /* tid */
2204         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2205         offset += 2;
2206
2207         BYTE_COUNT;
2208
2209         END_OF_SMB
2210
2211         return offset;
2212 }
2213  
2214
2215 static const true_false_string tfs_of_create = {
2216         "Create file if it does not exist",
2217         "Fail if file does not exist"
2218 };
2219 static const value_string of_open[] = {
2220         { 0,            "Fail if file exists"},
2221         { 1,            "Open file if it exists"},
2222         { 2,            "Truncate file if it exists"},
2223         {0, NULL}
2224 };
2225 static int
2226 dissect_open_function(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2227 {
2228         guint16 mask;
2229         proto_item *item = NULL;
2230         proto_tree *tree = NULL;
2231
2232         mask = tvb_get_letohs(tvb, offset);
2233
2234         if(parent_tree){
2235                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2236                         "Open Function: 0x%04x", mask);
2237                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2238         }
2239
2240         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2241                 tvb, offset, 2, mask);
2242         proto_tree_add_uint(tree, hf_smb_open_function_open,
2243                 tvb, offset, 2, mask);
2244
2245         offset += 2;
2246
2247         return offset;
2248 }
2249
2250
2251 static const true_false_string tfs_mf_file = {
2252         "Target must be a file",
2253         "Target needn't be a file"
2254  };
2255 static const true_false_string tfs_mf_dir = {
2256         "Target must be a directory",
2257         "Target needn't be a directory"
2258 };
2259 static const true_false_string tfs_mf_verify = {
2260         "MUST verify all writes",
2261         "Don't have to verify writes"
2262 };
2263 static int
2264 dissect_move_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
2265 {
2266         guint16 mask;
2267         proto_item *item = NULL;
2268         proto_tree *tree = NULL;
2269
2270         mask = tvb_get_letohs(tvb, offset);
2271
2272         if(parent_tree){
2273                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2274                         "Flags: 0x%04x", mask);
2275                 tree = proto_item_add_subtree(item, ett_smb_move_flags);
2276         }
2277  
2278         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2279                 tvb, offset, 2, mask);
2280         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2281                 tvb, offset, 2, mask);
2282         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2283                 tvb, offset, 2, mask);
2284
2285         offset += 2;
2286
2287         return offset;
2288 }
2289
2290 static int
2291 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2292 {
2293         int fn_len;
2294         guint16 tid;
2295         guint16 bc;
2296         guint8 wc;
2297         const char *fn;
2298
2299         WORD_COUNT;
2300
2301         /* tid */
2302         tid = tvb_get_letohs(tvb, offset);
2303         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2304                 "TID (target): 0x%04x", tid);
2305         offset += 2;
2306
2307         /* open function */
2308         offset = dissect_open_function(tvb, pinfo, tree, offset);
2309
2310         /* move flags */
2311         offset = dissect_move_flags(tvb, pinfo, tree, offset);
2312
2313         BYTE_COUNT;
2314
2315         /* buffer format */
2316         CHECK_BYTE_COUNT(1);
2317         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2318         COUNT_BYTES(1);
2319
2320         /* file name */
2321         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2322                 FALSE, FALSE, &bc);
2323         if (fn == NULL)
2324                 goto endofcommand;
2325         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2326                 fn_len, fn, "Old File Name: %s", fn);
2327         COUNT_BYTES(fn_len);
2328
2329         if (check_col(pinfo->fd, COL_INFO)) {
2330                 col_append_fstr(pinfo->fd, COL_INFO, ", Old Name: %s", fn);
2331         }
2332
2333         /* buffer format */
2334         CHECK_BYTE_COUNT(1);
2335         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2336         COUNT_BYTES(1);
2337
2338         /* file name */
2339         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2340                 FALSE, FALSE, &bc);
2341         if (fn == NULL)
2342                 goto endofcommand;
2343         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2344                 fn_len, fn, "New File Name: %s", fn);
2345         COUNT_BYTES(fn_len);
2346
2347         if (check_col(pinfo->fd, COL_INFO)) {
2348                 col_append_fstr(pinfo->fd, COL_INFO, ", New Name: %s", fn);
2349         }
2350
2351         END_OF_SMB
2352
2353         return offset;
2354 }
2355
2356 static int
2357 dissect_move_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2358 {
2359         int fn_len;
2360         const char *fn;
2361         guint8 wc;
2362         guint16 bc;
2363
2364         WORD_COUNT;
2365
2366         /* read count */
2367         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
2368         offset += 2;
2369
2370         BYTE_COUNT;
2371
2372         /* buffer format */
2373         CHECK_BYTE_COUNT(1);
2374         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2375         COUNT_BYTES(1);
2376
2377         /* file name */
2378         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2379                 FALSE, FALSE, &bc);
2380         if (fn == NULL)
2381                 goto endofcommand;
2382         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2383                 fn);
2384         COUNT_BYTES(fn_len);
2385
2386         END_OF_SMB
2387
2388         return offset;
2389 }
2390
2391 static int
2392 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2393 {
2394         int fn_len;
2395         const char *fn;
2396         guint8 wc;
2397         guint16 bc;
2398
2399         WORD_COUNT;
2400
2401         /* desired access */
2402         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
2403
2404         /* Search Attributes */
2405         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2406
2407         BYTE_COUNT;
2408
2409         /* buffer format */
2410         CHECK_BYTE_COUNT(1);
2411         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2412         COUNT_BYTES(1);
2413
2414         /* file name */
2415         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2416                 FALSE, FALSE, &bc);
2417         if (fn == NULL)
2418                 goto endofcommand;
2419         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2420                 fn);
2421         COUNT_BYTES(fn_len);
2422
2423         if (check_col(pinfo->fd, COL_INFO)) {
2424                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
2425         }
2426
2427         END_OF_SMB
2428
2429         return offset;
2430 }
2431
2432 void
2433 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2434     guint16 fid)
2435 {
2436         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, 2, fid);
2437         if (check_col(pinfo->fd, COL_INFO))
2438                 col_append_fstr(pinfo->fd, COL_INFO, ", FID: 0x%04x", fid);
2439 }
2440
2441 static int
2442 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2443 {
2444         guint8 wc;
2445         guint16 bc;
2446         guint16 fid;
2447
2448         WORD_COUNT;
2449
2450         /* fid */
2451         fid = tvb_get_letohs(tvb, offset);
2452         add_fid(tvb, pinfo, tree, offset, fid);
2453         offset += 2;
2454
2455         /* File Attributes */
2456         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2457
2458         /* last write time */
2459         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2460         
2461         /* File Size */
2462         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2463         offset += 4;
2464
2465         /* granted access */
2466         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
2467
2468         BYTE_COUNT;
2469
2470         END_OF_SMB
2471
2472         return offset;
2473 }
2474
2475 static int
2476 dissect_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2477 {
2478         guint8 wc;
2479         guint16 bc;
2480         guint16 fid;
2481
2482         WORD_COUNT;
2483
2484         /* fid */
2485         fid = tvb_get_letohs(tvb, offset);
2486         add_fid(tvb, pinfo, tree, offset, fid);
2487         offset += 2;
2488
2489         BYTE_COUNT;
2490
2491         END_OF_SMB
2492
2493         return offset;
2494 }
2495
2496 static int
2497 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2498 {
2499         int fn_len;
2500         const char *fn;
2501         guint8 wc;
2502         guint16 bc;
2503
2504         WORD_COUNT;
2505
2506         /* file attributes */
2507         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2508
2509         /* creation time */
2510         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
2511
2512         BYTE_COUNT;
2513
2514         /* buffer format */
2515         CHECK_BYTE_COUNT(1);
2516         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2517         COUNT_BYTES(1);
2518
2519         /* File Name */
2520         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2521                 FALSE, FALSE, &bc);
2522         if (fn == NULL)
2523                 goto endofcommand;
2524         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2525                 fn);
2526         COUNT_BYTES(fn_len);
2527
2528         if (check_col(pinfo->fd, COL_INFO)) {
2529                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
2530         }
2531
2532         END_OF_SMB
2533
2534         return offset;
2535 }
2536
2537 static int
2538 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2539 {
2540         guint8 wc;
2541         guint16 bc;
2542
2543         WORD_COUNT;
2544
2545         /* fid */
2546         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
2547         offset += 2;
2548
2549         /* last write time */
2550         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2551
2552         BYTE_COUNT;
2553
2554         END_OF_SMB
2555
2556         return offset;
2557 }
2558
2559 static int
2560 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2561 {
2562         int fn_len;
2563         const char *fn;
2564         guint8 wc;
2565         guint16 bc;
2566
2567         WORD_COUNT;
2568
2569         /* search attributes */
2570         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2571
2572         BYTE_COUNT;
2573
2574         /* buffer format */
2575         CHECK_BYTE_COUNT(1);
2576         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2577         COUNT_BYTES(1);
2578
2579         /* file name */
2580         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2581                 FALSE, FALSE, &bc);
2582         if (fn == NULL)
2583                 goto endofcommand;
2584         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2585                 fn);
2586         COUNT_BYTES(fn_len);
2587
2588         if (check_col(pinfo->fd, COL_INFO)) {
2589                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
2590         }
2591
2592         END_OF_SMB
2593
2594         return offset;
2595 }
2596
2597 static int
2598 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2599 {
2600         int fn_len;
2601         const char *fn;
2602         guint8 wc;
2603         guint16 bc;
2604
2605         WORD_COUNT;
2606
2607         /* search attributes */
2608         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
2609
2610         BYTE_COUNT;
2611
2612         /* buffer format */
2613         CHECK_BYTE_COUNT(1);
2614         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2615         COUNT_BYTES(1);
2616
2617         /* old file name */
2618         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2619                 FALSE, FALSE, &bc);
2620         if (fn == NULL)
2621                 goto endofcommand;
2622         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
2623                 fn);
2624         COUNT_BYTES(fn_len);
2625
2626         if (check_col(pinfo->fd, COL_INFO)) {
2627                 col_append_fstr(pinfo->fd, COL_INFO, ", Old Name: %s", fn);
2628         }
2629
2630         /* buffer format */
2631         CHECK_BYTE_COUNT(1);
2632         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2633         COUNT_BYTES(1);
2634
2635         /* file name */
2636         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2637                 FALSE, FALSE, &bc);
2638         if (fn == NULL)
2639                 goto endofcommand;
2640         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2641                 fn);
2642         COUNT_BYTES(fn_len);
2643
2644         if (check_col(pinfo->fd, COL_INFO)) {
2645                 col_append_fstr(pinfo->fd, COL_INFO, ", New Name: %s", fn);
2646         }
2647
2648         END_OF_SMB
2649
2650         return offset;
2651 }
2652
2653 static int
2654 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2655 {
2656         guint16 bc;
2657         guint8 wc;
2658         const char *fn;
2659         int fn_len;
2660
2661         WORD_COUNT;
2662
2663         BYTE_COUNT;
2664
2665         /* Buffer Format */
2666         CHECK_BYTE_COUNT(1);
2667         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2668         COUNT_BYTES(1);
2669
2670         /* File Name */
2671         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2672                 FALSE, FALSE, &bc);
2673         if (fn == NULL)
2674                 goto endofcommand;
2675         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2676                 fn);
2677         COUNT_BYTES(fn_len);
2678
2679         if (check_col(pinfo->fd, COL_INFO)) {
2680                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
2681         }
2682
2683         END_OF_SMB
2684
2685         return offset;
2686 }
2687  
2688 static int
2689 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2690 {
2691         guint16 bc;
2692         guint8 wc;
2693         nstime_t ts;
2694
2695         WORD_COUNT;
2696
2697         /* File Attributes */
2698         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2699
2700         /* Last Write Time */
2701         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2702
2703         /* File Size */
2704         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2705         offset += 4;
2706
2707         /* 10 reserved bytes */
2708         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2709         offset += 10;
2710
2711         BYTE_COUNT;
2712
2713         END_OF_SMB
2714
2715         return offset;
2716 }
2717
2718 static int
2719 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2720 {
2721         int fn_len;
2722         const char *fn;
2723         guint8 wc;
2724         guint16 bc;
2725
2726         WORD_COUNT;
2727
2728         /* file attributes */
2729         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
2730
2731         /* last write time */
2732         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
2733
2734         /* 10 reserved bytes */
2735         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
2736         offset += 10;
2737
2738         BYTE_COUNT;
2739
2740         /* buffer format */
2741         CHECK_BYTE_COUNT(1);
2742         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2743         COUNT_BYTES(1);
2744
2745         /* file name */
2746         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
2747                 FALSE, FALSE, &bc);
2748         if (fn == NULL)
2749                 goto endofcommand;
2750         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2751                 fn);
2752         COUNT_BYTES(fn_len);
2753
2754         if (check_col(pinfo->fd, COL_INFO)) {
2755                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
2756         }
2757
2758         END_OF_SMB
2759
2760         return offset;
2761 }
2762
2763 static int
2764 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2765 {
2766         guint8 wc;
2767         guint16 bc;
2768
2769         WORD_COUNT;
2770
2771         /* fid */
2772         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
2773         offset += 2;
2774
2775         /* read count */
2776         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
2777         offset += 2;
2778
2779         /* offset */
2780         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
2781         offset += 4;
2782
2783         /* remaining */
2784         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
2785         offset += 2;
2786
2787         BYTE_COUNT;
2788
2789         END_OF_SMB
2790
2791         return offset;
2792 }
2793
2794 static int
2795 dissect_file_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
2796 {
2797         int tvblen;
2798
2799         if(bc>datalen){
2800                 /* We have some initial padding bytes. */
2801                 /* XXX - use the data offset here instead? */
2802                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
2803                         TRUE);
2804                 offset += bc-datalen;
2805                 bc = datalen;
2806         }
2807         tvblen = tvb_length_remaining(tvb, offset);
2808         if(bc>tvblen){
2809                 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);
2810                 offset += tvblen;
2811         } else {
2812                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
2813                 offset += bc;
2814         }
2815         return offset;
2816 }
2817
2818 static int
2819 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2820 {
2821         guint16 cnt=0, bc;
2822         guint8 wc;
2823
2824         WORD_COUNT;
2825
2826         /* read count */
2827         cnt = tvb_get_letohs(tvb, offset);
2828         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
2829         offset += 2;
2830
2831         /* 8 reserved bytes */
2832         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
2833         offset += 8;
2834
2835         BYTE_COUNT;
2836
2837         /* buffer format */
2838         CHECK_BYTE_COUNT(1);
2839         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2840         COUNT_BYTES(1);
2841
2842         /* data len */
2843         CHECK_BYTE_COUNT(2);
2844         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
2845         COUNT_BYTES(2);
2846
2847         if (bc != 0) {
2848                 /* file data */
2849                 offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
2850                 bc = 0;
2851         }
2852
2853         END_OF_SMB
2854
2855         return offset;
2856 }
2857
2858 static int
2859 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2860 {
2861         guint16 cnt, bc;
2862         guint8 wc;
2863
2864         WORD_COUNT;
2865
2866         /* read count */
2867         cnt = tvb_get_letohs(tvb, offset);
2868         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
2869         offset += 2;
2870
2871         /* 8 reserved bytes */
2872         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
2873         offset += 8;
2874
2875         BYTE_COUNT;
2876
2877         /* buffer format */
2878         CHECK_BYTE_COUNT(1);
2879         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2880         COUNT_BYTES(1);
2881
2882         /* data len */
2883         CHECK_BYTE_COUNT(2);
2884         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
2885         COUNT_BYTES(2);
2886
2887         END_OF_SMB
2888
2889         return offset;
2890 }
2891
2892
2893 static int
2894 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2895 {
2896         guint16 cnt=0, bc;
2897         guint8 wc;
2898
2899         WORD_COUNT;
2900
2901         /* fid */
2902         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
2903         offset += 2;
2904
2905         /* write count */
2906         cnt = tvb_get_letohs(tvb, offset);
2907         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
2908         offset += 2;
2909
2910         /* offset */
2911         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
2912         offset += 4;
2913
2914         /* remaining */
2915         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
2916         offset += 2;
2917
2918         BYTE_COUNT;
2919
2920         /* buffer format */
2921         CHECK_BYTE_COUNT(1);
2922         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2923         COUNT_BYTES(1);
2924
2925         /* data len */
2926         CHECK_BYTE_COUNT(2);
2927         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
2928         COUNT_BYTES(2);
2929
2930         if (bc != 0) {
2931                 /* file data */
2932                 offset = dissect_file_data(tvb, pinfo, tree, offset, bc, bc);
2933                 bc = 0;
2934         }
2935
2936         END_OF_SMB
2937
2938         return offset;
2939 }
2940  
2941 static int
2942 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2943 {
2944         guint8 wc;
2945         guint16 bc;
2946
2947         WORD_COUNT;
2948
2949         /* write count */
2950         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
2951         offset += 2;
2952
2953         BYTE_COUNT;
2954
2955         END_OF_SMB
2956
2957         return offset;
2958 }
2959
2960 static int
2961 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2962 {
2963         guint8 wc;
2964         guint16 bc;
2965
2966         WORD_COUNT;
2967
2968         /* fid */
2969         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
2970         offset += 2;
2971
2972         /* lock count */
2973         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
2974         offset += 4;
2975
2976         /* offset */
2977         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
2978         offset += 4;
2979
2980         BYTE_COUNT;
2981
2982         END_OF_SMB
2983
2984         return offset;
2985 }
2986
2987 static int
2988 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
2989 {
2990         int fn_len;
2991         const char *fn;
2992         guint8 wc;
2993         guint16 bc;
2994
2995         WORD_COUNT;
2996
2997         /* 2 reserved bytes */
2998         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2999         offset += 2;
3000
3001         /* Creation time */
3002         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
3003
3004         BYTE_COUNT;
3005
3006         /* buffer format */
3007         CHECK_BYTE_COUNT(1);
3008         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3009         COUNT_BYTES(1);
3010
3011         /* directory name */
3012         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3013                 FALSE, FALSE, &bc);
3014         if (fn == NULL)
3015                 goto endofcommand;
3016         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3017                 fn);
3018         COUNT_BYTES(fn_len);
3019
3020         if (check_col(pinfo->fd, COL_INFO)) {
3021                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
3022         }
3023
3024         END_OF_SMB
3025
3026         return offset;
3027 }
3028
3029 static int
3030 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3031 {
3032         int fn_len;
3033         const char *fn;
3034         guint8 wc;
3035         guint16 bc;
3036         guint16 fid;
3037
3038         WORD_COUNT;
3039
3040         /* fid */
3041         fid = tvb_get_letohs(tvb, offset);
3042         add_fid(tvb, pinfo, tree, offset, fid);
3043         offset += 2;
3044
3045         BYTE_COUNT;
3046
3047         /* buffer format */
3048         CHECK_BYTE_COUNT(1);
3049         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3050         COUNT_BYTES(1);
3051
3052         /* file name */
3053         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3054                 FALSE, FALSE, &bc);
3055         if (fn == NULL)
3056                 goto endofcommand;
3057         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3058                 fn);
3059         COUNT_BYTES(fn_len);
3060
3061         END_OF_SMB
3062
3063         return offset;
3064 }
3065
3066 static const value_string seek_mode_vals[] = {
3067         {0,     "From Start Of File"},
3068         {1,     "From Current Position"},
3069         {2,     "From End Of File"},
3070         {0,     NULL}
3071 };
3072
3073 static int
3074 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3075 {
3076         guint8 wc;
3077         guint16 bc;
3078
3079         WORD_COUNT;
3080
3081         /* fid */
3082         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3083         offset += 2;
3084
3085         /* Seek Mode */
3086         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3087         offset += 2;
3088
3089         /* offset */
3090         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3091         offset += 4;
3092
3093         BYTE_COUNT;
3094
3095         END_OF_SMB
3096
3097         return offset;
3098 }
3099
3100 static int
3101 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3102 {
3103         guint8 wc;
3104         guint16 bc;
3105
3106         WORD_COUNT;
3107
3108         /* offset */
3109         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3110         offset += 4;
3111
3112         BYTE_COUNT;
3113
3114         END_OF_SMB
3115
3116         return offset;
3117 }
3118  
3119 static int
3120 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3121 {
3122         guint8 wc;
3123         guint16 bc;
3124
3125         WORD_COUNT;
3126
3127         /* fid */
3128         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3129         offset += 2;
3130
3131         /* create time */
3132         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3133                 hf_smb_create_time,
3134                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3135
3136         /* access time */
3137         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3138                 hf_smb_access_time,
3139                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3140
3141         /* last write time */
3142         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3143                 hf_smb_last_write_time,
3144                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3145
3146         BYTE_COUNT;
3147
3148         END_OF_SMB
3149
3150         return offset;
3151 }
3152
3153 static int
3154 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3155 {
3156         guint8 wc;
3157         guint16 bc;
3158
3159         WORD_COUNT;
3160
3161         /* create time */
3162         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3163                 hf_smb_create_time,
3164                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3165
3166         /* access time */
3167         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3168                 hf_smb_access_time,
3169                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3170
3171         /* last write time */
3172         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3173                 hf_smb_last_write_time,
3174                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3175
3176         /* data size */
3177         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3178         offset += 4;
3179
3180         /* allocation size */
3181         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3182         offset += 4;
3183
3184         /* File Attributes */
3185         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
3186
3187         BYTE_COUNT;
3188
3189         END_OF_SMB
3190
3191         return offset;
3192 }
3193
3194 static int
3195 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3196 {
3197         guint8 wc;
3198         guint16 cnt=0;
3199         guint16 bc;
3200
3201         WORD_COUNT;
3202
3203         /* fid */
3204         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3205         offset += 2;
3206
3207         /* write count */
3208         cnt = tvb_get_letohs(tvb, offset);
3209         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3210         offset += 2;
3211
3212         /* offset */
3213         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3214         offset += 4;
3215
3216         /* last write time */
3217         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
3218         
3219         if(wc==12){
3220                 /* 12 reserved bytes */
3221                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3222                 offset += 12;
3223         }
3224
3225         BYTE_COUNT;
3226
3227         /* 1 pad byte */
3228         CHECK_BYTE_COUNT(1);
3229         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3230         COUNT_BYTES(1);
3231         
3232         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
3233         bc = 0; /* XXX */
3234
3235         END_OF_SMB
3236
3237         return offset;
3238 }
3239  
3240 static int
3241 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3242 {
3243         guint16 cnt;
3244         guint8 wc;
3245         guint16 bc;
3246
3247         WORD_COUNT;
3248
3249         /* write count */
3250         cnt = tvb_get_letohs(tvb, offset);
3251         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3252         offset += 2;
3253
3254         BYTE_COUNT;
3255
3256         END_OF_SMB
3257
3258         return offset;
3259 }
3260
3261 static int
3262 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3263 {
3264         guint8 wc;
3265         guint16 bc;
3266         guint32 to;
3267
3268         WORD_COUNT;
3269
3270         /* fid */
3271         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3272         offset += 2;
3273
3274         /* offset */
3275         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3276         offset += 4;
3277
3278         /* max count */
3279         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3280         offset += 2;
3281
3282         /* min count */
3283         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3284         offset += 2;
3285
3286         /* timeout */
3287         to = tvb_get_letohl(tvb, offset);
3288         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3289         offset += 4;
3290
3291         /* 2 reserved bytes */
3292         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3293         offset += 2;
3294
3295         if(wc==10){
3296                 /* high offset */
3297                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3298                 offset += 4;
3299         }
3300
3301         BYTE_COUNT;
3302
3303         END_OF_SMB
3304
3305         return offset;
3306 }
3307
3308 static int
3309 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3310 {
3311         guint8 wc;
3312         guint16 bc;
3313
3314         WORD_COUNT;
3315
3316         /* units */
3317         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3318         offset += 2;
3319
3320         /* bpu */
3321         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3322         offset += 2;
3323
3324         /* block size */
3325         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3326         offset += 2;
3327
3328         /* free units */
3329         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3330         offset += 2;
3331
3332         /* 2 reserved bytes */
3333         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3334         offset += 2;
3335
3336         BYTE_COUNT;
3337
3338         END_OF_SMB
3339
3340         return offset;
3341 }
3342
3343 static int
3344 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3345 {
3346         guint8 wc;
3347         guint16 bc;
3348
3349         WORD_COUNT;
3350
3351         /* fid */
3352         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3353         offset += 2;
3354
3355         /* offset */
3356         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3357         offset += 4;
3358
3359         /* max count */
3360         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3361         offset += 2;
3362
3363         /* min count */
3364         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3365         offset += 2;
3366
3367         /* 6 reserved bytes */
3368         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
3369         offset += 6;
3370
3371         BYTE_COUNT;
3372
3373         END_OF_SMB
3374
3375         return offset;
3376 }
3377
3378 static int
3379 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3380 {
3381         guint16 datalen=0, bc;
3382         guint8 wc;
3383         int tvblen;
3384
3385         WORD_COUNT;
3386
3387         /* offset */
3388         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3389         offset += 4;
3390
3391         /* count */
3392         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3393         offset += 2;
3394
3395         /* 2 reserved bytes */
3396         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3397         offset += 2;
3398
3399         /* data compaction mode */
3400         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
3401         offset += 2;
3402
3403         /* 2 reserved bytes */
3404         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3405         offset += 2;
3406
3407         /* data len */
3408         datalen = tvb_get_letohs(tvb, offset);
3409         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3410         offset += 2;
3411
3412         /* data offset */
3413         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3414         offset += 2;
3415
3416         BYTE_COUNT;
3417
3418         /* file data */
3419         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3420         bc = 0;
3421
3422         END_OF_SMB
3423
3424         return offset;
3425 }
3426
3427
3428 static const true_false_string tfs_write_mode_write_through = {
3429         "WRITE THROUGH requested",
3430         "Write through not requested"
3431 };
3432 static const true_false_string tfs_write_mode_return_remaining = {
3433         "RETURN REMAINING (pipe/dev) requested",
3434         "DON'T return remaining (pipe/dev)"
3435 };
3436 static const true_false_string tfs_write_mode_raw = {
3437         "Use WriteRawNamedPipe (pipe)",
3438         "DON'T use WriteRawNamedPipe (pipe)"
3439 };
3440 static const true_false_string tfs_write_mode_message_start = {
3441         "This is the START of a MESSAGE (pipe)",
3442         "This is NOT the start of a message (pipe)"
3443 };
3444 static const true_false_string tfs_write_mode_connectionless = {
3445         "CONNECTIONLESS mode requested",
3446         "Connectionless mode NOT requested"
3447 };
3448 static int
3449 dissect_write_mode(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
3450 {
3451         guint16 mask;
3452         proto_item *item = NULL;
3453         proto_tree *tree = NULL;
3454
3455         mask = tvb_get_letohs(tvb, offset);
3456
3457         if(parent_tree){
3458                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
3459                         "Write Mode: 0x%04x", mask);
3460                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
3461         }
3462
3463         if(bm&0x0080){
3464                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
3465                         tvb, offset, 2, mask);
3466         }
3467         if(bm&0x0008){
3468                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
3469                         tvb, offset, 2, mask);
3470         }
3471         if(bm&0x0004){
3472                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
3473                         tvb, offset, 2, mask);
3474         }
3475         if(bm&0x0002){
3476                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
3477                         tvb, offset, 2, mask);
3478         }
3479         if(bm&0x0001){
3480                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
3481                         tvb, offset, 2, mask);
3482         }
3483
3484         offset += 2;
3485         return offset;
3486 }
3487
3488 static int
3489 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3490 {
3491         guint32 to;
3492         guint16 datalen=0, bc;
3493         guint8 wc;
3494         int tvblen;
3495
3496         WORD_COUNT;
3497
3498         /* fid */
3499         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3500         offset += 2;
3501
3502         /* total data length */
3503         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3504         offset += 2;
3505
3506         /* 2 reserved bytes */
3507         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3508         offset += 2;
3509
3510         /* offset */
3511         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3512         offset += 4;
3513
3514         /* timeout */
3515         to = tvb_get_letohl(tvb, offset);
3516         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3517         offset += 4;
3518
3519         /* mode */
3520         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0003);
3521
3522         /* 4 reserved bytes */
3523         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
3524         offset += 4;
3525
3526         /* data len */
3527         datalen = tvb_get_letohs(tvb, offset);
3528         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3529         offset += 2;
3530
3531         /* data offset */
3532         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3533         offset += 2;
3534
3535         BYTE_COUNT;
3536
3537         /* file data */
3538         /* XXX - use the data offset to determine where the data starts? */
3539         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3540         bc = 0;
3541
3542         END_OF_SMB
3543
3544         return offset;
3545 }
3546  
3547 static int
3548 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3549 {
3550         guint8 wc;
3551         guint16 bc;
3552
3553         WORD_COUNT;
3554
3555         /* remaining */
3556         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3557         offset += 2;
3558
3559         BYTE_COUNT;
3560
3561         END_OF_SMB
3562
3563         return offset;
3564 }
3565
3566 static int
3567 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3568 {
3569         guint32 to;
3570         guint16 datalen=0, bc;
3571         guint8 wc;
3572         int tvblen;
3573
3574         WORD_COUNT;
3575
3576         /* fid */
3577         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3578         offset += 2;
3579
3580         /* total data length */
3581         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
3582         offset += 2;
3583
3584         /* 2 reserved bytes */
3585         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3586         offset += 2;
3587
3588         /* offset */
3589         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3590         offset += 4;
3591
3592         /* timeout */
3593         to = tvb_get_letohl(tvb, offset);
3594         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3595         offset += 4;
3596
3597         /* mode */
3598         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x0083);
3599
3600         /* request mask */
3601         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
3602         offset += 4;
3603         
3604         /* data len */
3605         datalen = tvb_get_letohs(tvb, offset);
3606         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
3607         offset += 2;
3608
3609         /* data offset */
3610         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
3611         offset += 2;
3612
3613         BYTE_COUNT;
3614
3615         /* file data */
3616         /* XXX - use the data offset to determine where the data starts? */
3617         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
3618         bc = 0;
3619
3620         END_OF_SMB
3621
3622         return offset;
3623 }
3624  
3625 static int
3626 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3627 {
3628         guint8 wc;
3629         guint16 bc;
3630
3631         WORD_COUNT;
3632
3633         /* response mask */
3634         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
3635         offset += 4;
3636         
3637         BYTE_COUNT;
3638
3639         END_OF_SMB
3640
3641         return offset;
3642 }
3643
3644 static int
3645 dissect_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3646 {
3647         guint8 wc;
3648         guint16 bc;
3649
3650         WORD_COUNT;
3651
3652         /* sid */
3653         proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
3654         offset += 2;
3655
3656         BYTE_COUNT;
3657
3658         END_OF_SMB
3659
3660         return offset;
3661 }
3662
3663 static int
3664 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
3665     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3666 {
3667         proto_item *item = NULL;
3668         proto_tree *tree = NULL;
3669         int fn_len;
3670         const char *fn;
3671         char fname[11+1];
3672
3673         if(parent_tree){
3674                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
3675                         "Resume Key");
3676                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
3677         }
3678
3679         /* reserved byte */
3680         CHECK_BYTE_COUNT_SUBR(1);
3681         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
3682         COUNT_BYTES_SUBR(1);
3683
3684         /* file name */
3685         fn_len = 11;
3686         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3687                 TRUE, TRUE, bcp);
3688         CHECK_STRING_SUBR(fn);
3689         /* ensure that it's null-terminated */
3690         strncpy(fname, fn, 11);
3691         fname[11] = '\0';
3692         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
3693                 fname);
3694         COUNT_BYTES_SUBR(fn_len);
3695
3696         /* server cookie */
3697         CHECK_BYTE_COUNT_SUBR(5);
3698         proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
3699         COUNT_BYTES_SUBR(5);
3700
3701         /* client cookie */
3702         CHECK_BYTE_COUNT_SUBR(4);
3703         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
3704         COUNT_BYTES_SUBR(4);
3705
3706         *trunc = FALSE;
3707         return offset;
3708 }
3709
3710 static int
3711 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
3712     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
3713 {
3714         proto_item *item = NULL;
3715         proto_tree *tree = NULL;
3716         int fn_len;
3717         const char *fn;
3718         char fname[13+1];
3719
3720         if(parent_tree){
3721                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
3722                         "Directory Information");
3723                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
3724         }
3725
3726         /* resume key */
3727         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp, trunc);
3728         if (*trunc)
3729                 return offset;
3730
3731         /* File Attributes */
3732         CHECK_BYTE_COUNT_SUBR(1);
3733         offset = dissect_dir_info_file_attributes(tvb, pinfo, tree, offset);
3734         *bcp -= 1;
3735
3736         /* last write time */
3737         CHECK_BYTE_COUNT_SUBR(4);
3738         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
3739                 hf_smb_last_write_time,
3740                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
3741                 TRUE);
3742         *bcp -= 4;
3743
3744         /* File Size */
3745         CHECK_BYTE_COUNT_SUBR(4);
3746         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3747         COUNT_BYTES_SUBR(4);
3748
3749         /* file name */
3750         fn_len = 13;
3751         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3752                 TRUE, TRUE, bcp);
3753         CHECK_STRING_SUBR(fn);
3754         /* ensure that it's null-terminated */
3755         strncpy(fname, fn, 13);
3756         fname[13] = '\0';
3757         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3758                 fname);
3759         COUNT_BYTES_SUBR(fn_len);
3760
3761         *trunc = FALSE;
3762         return offset;
3763 }
3764
3765
3766 static int
3767 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3768 {
3769         int fn_len;
3770         const char *fn;
3771         guint16 rkl;
3772         guint8 wc;
3773         guint16 bc;
3774         gboolean trunc;
3775
3776         WORD_COUNT;
3777
3778         /* max count */
3779         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3780         offset += 2;
3781
3782         /* Search Attributes */
3783         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
3784
3785         BYTE_COUNT;
3786
3787         /* buffer format */
3788         CHECK_BYTE_COUNT(1);
3789         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3790         COUNT_BYTES(1);
3791
3792         /* file name */
3793         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
3794                 TRUE, FALSE, &bc);
3795         if (fn == NULL)
3796                 goto endofcommand;
3797         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3798                 fn);
3799         COUNT_BYTES(fn_len);
3800
3801         if (check_col(pinfo->fd, COL_INFO)) {
3802                 col_append_fstr(pinfo->fd, COL_INFO, ", File: %s", fn);
3803         }
3804
3805         /* buffer format */
3806         CHECK_BYTE_COUNT(1);
3807         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3808         COUNT_BYTES(1);
3809
3810         /* resume key length */
3811         CHECK_BYTE_COUNT(2);
3812         rkl = tvb_get_letohs(tvb, offset);
3813         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
3814         COUNT_BYTES(2);
3815
3816         /* resume key */
3817         if(rkl){
3818                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
3819                     &bc, &trunc);
3820                 if (trunc)
3821                         goto endofcommand;
3822         }
3823
3824         END_OF_SMB
3825
3826         return offset;
3827 }
3828
3829 static int
3830 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3831 {
3832         guint16 count=0;
3833         guint8 wc;
3834         guint16 bc;
3835         gboolean trunc;
3836
3837         WORD_COUNT;
3838
3839         /* count */
3840         count = tvb_get_letohs(tvb, offset);
3841         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
3842         offset += 2;
3843
3844         BYTE_COUNT;
3845
3846         /* buffer format */
3847         CHECK_BYTE_COUNT(1);
3848         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3849         COUNT_BYTES(1);
3850
3851         /* data len */
3852         CHECK_BYTE_COUNT(2);
3853         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3854         COUNT_BYTES(2);
3855
3856         while(count--){
3857                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
3858                     &bc, &trunc);
3859                 if (trunc)
3860                         goto endofcommand;
3861         }
3862
3863         END_OF_SMB
3864
3865         return offset;
3866 }
3867
3868 static const value_string locking_ol_vals[] = {
3869         {0,     "Client is not holding oplock on this file"},
3870         {1,     "Level 2 oplock currently held by client"},
3871         {0, NULL}
3872 };
3873
3874 static const true_false_string tfs_lock_type_large = {
3875         "Large file locking format requested",
3876         "Large file locking format not requested"
3877 };
3878 static const true_false_string tfs_lock_type_cancel = {
3879         "Cancel outstanding lock request",
3880         "Don't cancel outstanding lock request"
3881 };
3882 static const true_false_string tfs_lock_type_change = {
3883         "Change lock type",
3884         "Don't change lock type"
3885 };
3886 static const true_false_string tfs_lock_type_oplock = {
3887         "This is an oplock break notification/response",
3888         "This is not an oplock break notification/response"
3889 };
3890 static const true_false_string tfs_lock_type_shared = {
3891         "This is a shared lock",
3892         "This is an exclusive lock"
3893 };
3894 static int
3895 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
3896 {
3897         guint8  wc, cmd=0xff, lt=0;
3898         guint16 andxoffset=0, un=0, ln=0, bc;
3899         guint32 to;
3900         proto_item *litem = NULL;
3901         proto_tree *ltree = NULL;
3902         proto_item *it = NULL;
3903         proto_tree *tr = NULL;
3904         int old_offset = offset;
3905
3906         WORD_COUNT;
3907
3908         /* next smb command */
3909         cmd = tvb_get_guint8(tvb, offset);
3910         if(cmd!=0xff){
3911                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
3912         } else {
3913                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
3914         }
3915         offset += 1;
3916
3917         /* reserved byte */
3918         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
3919         offset += 1;
3920
3921         /* andxoffset */
3922         andxoffset = tvb_get_letohs(tvb, offset);
3923         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
3924         offset += 2;
3925
3926         /* fid */
3927         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
3928         offset += 2;
3929
3930         /* lock type */
3931         lt = tvb_get_guint8(tvb, offset);
3932         if(tree){
3933                 litem = proto_tree_add_text(tree, tvb, offset, 1,
3934                         "Lock Type: 0x%02x", lt);
3935                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
3936         }
3937         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
3938                 tvb, offset, 1, lt);
3939         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
3940                 tvb, offset, 1, lt);
3941         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
3942                 tvb, offset, 1, lt);
3943         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
3944                 tvb, offset, 1, lt);
3945         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
3946                 tvb, offset, 1, lt);
3947         offset += 1;
3948
3949         /* oplock level */
3950         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
3951         offset += 1;
3952
3953         /* timeout */
3954         to = tvb_get_letohl(tvb, offset);
3955         if (to == 0)
3956                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
3957         else if (to == 0xffffffff)
3958                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
3959         else
3960                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3961         offset += 4;
3962
3963         /* number of unlocks */
3964         un = tvb_get_letohs(tvb, offset);
3965         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
3966         offset += 2;
3967
3968         /* number of locks */
3969         ln = tvb_get_letohs(tvb, offset);
3970         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
3971         offset += 2;
3972
3973         BYTE_COUNT;
3974
3975         /* unlocks */
3976         if(un){
3977                 old_offset = offset;
3978
3979                 it = proto_tree_add_text(tree, tvb, offset, 0,
3980                         "Unlocks");
3981                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
3982                 while(un--){
3983                         proto_item *litem = NULL;
3984                         proto_tree *ltree = NULL;
3985                         if(lt&0x10){
3986                                 /* large lock format */
3987                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
3988                                         "Unlock");
3989                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
3990                                 
3991                                 /* PID */
3992                                 CHECK_BYTE_COUNT(2);
3993                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
3994                                 COUNT_BYTES(2);
3995
3996                                 /* 2 reserved bytes */
3997                                 CHECK_BYTE_COUNT(2);
3998                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
3999                                 COUNT_BYTES(2);
4000
4001                                 /* offset */
4002                                 CHECK_BYTE_COUNT(8);
4003                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4004                                 COUNT_BYTES(8);
4005
4006                                 /* length */
4007                                 CHECK_BYTE_COUNT(8);
4008                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4009                                 COUNT_BYTES(8);
4010                         } else {
4011                                 /* normal lock format */
4012                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4013                                         "Unlock");
4014                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4015                                 
4016                                 /* PID */
4017                                 CHECK_BYTE_COUNT(2);
4018                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4019                                 COUNT_BYTES(2);
4020
4021                                 /* offset */
4022                                 CHECK_BYTE_COUNT(4);
4023                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4024                                 COUNT_BYTES(4);
4025
4026                                 /* lock count */
4027                                 CHECK_BYTE_COUNT(4);
4028                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4029                                 COUNT_BYTES(4);
4030                         }
4031                 }
4032                 proto_item_set_len(it, offset-old_offset);
4033                 it = NULL;
4034         }
4035
4036         /* locks */
4037         if(ln){
4038                 old_offset = offset;
4039
4040                 it = proto_tree_add_text(tree, tvb, offset, 0,
4041                         "Locks");
4042                 tr = proto_item_add_subtree(it, ett_smb_locks);
4043                 while(ln--){
4044                         proto_item *litem = NULL;
4045                         proto_tree *ltree = NULL;
4046                         if(lt&0x10){
4047                                 /* large lock format */
4048                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4049                                         "Lock");
4050                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4051                                 
4052                                 /* PID */
4053                                 CHECK_BYTE_COUNT(2);
4054                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4055                                 COUNT_BYTES(2);
4056
4057                                 /* 2 reserved bytes */
4058                                 CHECK_BYTE_COUNT(2);
4059                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4060                                 COUNT_BYTES(2);
4061
4062                                 /* offset */
4063                                 CHECK_BYTE_COUNT(8);
4064                                 proto_tree_add_item(ltree, hf_smb_lock_long_offset, tvb, offset, 8, TRUE);
4065                                 COUNT_BYTES(8);
4066
4067                                 /* length */
4068                                 CHECK_BYTE_COUNT(8);
4069                                 proto_tree_add_item(ltree, hf_smb_lock_long_length, tvb, offset, 8, TRUE);
4070                                 COUNT_BYTES(8);
4071                         } else {
4072                                 /* normal lock format */
4073                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4074                                         "Unlock");
4075                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4076                                 
4077                                 /* PID */
4078                                 CHECK_BYTE_COUNT(2);
4079                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4080                                 COUNT_BYTES(2);
4081
4082                                 /* offset */
4083                                 CHECK_BYTE_COUNT(4);
4084                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4085                                 COUNT_BYTES(4);
4086
4087                                 /* lock count */
4088                                 CHECK_BYTE_COUNT(4);
4089                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4090                                 COUNT_BYTES(4);
4091                         }
4092                 }
4093                 proto_item_set_len(it, offset-old_offset);
4094                 it = NULL;
4095         }
4096
4097         END_OF_SMB
4098
4099         if (it != NULL) {
4100                 /*
4101                  * We ran out of byte count in the middle of dissecting
4102                  * the locks or the unlocks; set the site of the item
4103                  * we were dissecting.
4104                  */
4105                 proto_item_set_len(it, offset-old_offset);
4106         }
4107
4108         /* call AndXCommand (if there are any) */
4109         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4110
4111         return offset;
4112 }
4113
4114 static int
4115 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4116 {
4117         guint8  wc, cmd=0xff;
4118         guint16 andxoffset=0;
4119         guint16 bc;
4120
4121         WORD_COUNT;
4122
4123         /* next smb command */
4124         cmd = tvb_get_guint8(tvb, offset);
4125         if(cmd!=0xff){
4126                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4127         } else {
4128                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4129         }
4130         offset += 1;
4131
4132         /* reserved byte */
4133         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4134         offset += 1;
4135
4136         /* andxoffset */
4137         andxoffset = tvb_get_letohs(tvb, offset);
4138         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4139         offset += 2;
4140
4141         BYTE_COUNT;
4142
4143         END_OF_SMB
4144
4145         /* call AndXCommand (if there are any) */
4146         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4147
4148         return offset;
4149 }
4150
4151
4152 static const value_string oa_open_vals[] = {
4153         { 0,            "No action taken?"},
4154         { 1,            "The file existed and was opened"},
4155         { 2,            "The file did not exist but was created"},
4156         { 3,            "The file existed and was truncated"},
4157         {0,     NULL}
4158 };
4159 static const true_false_string tfs_oa_lock = {
4160         "File is currently opened only by this user",
4161         "File is opened by another user (or mode not supported by server)"
4162 };
4163 static int
4164 dissect_open_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4165 {
4166         guint16 mask;
4167         proto_item *item = NULL;
4168         proto_tree *tree = NULL;
4169
4170         mask = tvb_get_letohs(tvb, offset);
4171
4172         if(parent_tree){
4173                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4174                         "Action: 0x%04x", mask);
4175                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4176         }
4177
4178         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4179                 tvb, offset, 2, mask);
4180         proto_tree_add_uint(tree, hf_smb_open_action_open,
4181                 tvb, offset, 2, mask);
4182
4183         offset += 2;
4184
4185         return offset;
4186 }
4187
4188 static const true_false_string tfs_open_flags_add_info = {
4189         "Additional information requested",
4190         "Additional information not requested"
4191 };
4192 static const true_false_string tfs_open_flags_ex_oplock = {
4193         "Exclusive oplock requested",
4194         "Exclusive oplock not requested"
4195 };
4196 static const true_false_string tfs_open_flags_batch_oplock = {
4197         "Batch oplock requested",
4198         "Batch oplock not requested"
4199 };
4200 static const true_false_string tfs_open_flags_ealen = {
4201         "Total length of EAs requested",
4202         "Total length of EAs not requested"
4203 };
4204 static int
4205 dissect_open_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int bm)
4206 {
4207         guint16 mask;
4208         proto_item *item = NULL;
4209         proto_tree *tree = NULL;
4210
4211         mask = tvb_get_letohs(tvb, offset);
4212
4213         if(parent_tree){
4214                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4215                         "Flags: 0x%04x", mask);
4216                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
4217         }
4218
4219         if(bm&0x0001){
4220                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
4221                         tvb, offset, 2, mask);
4222         }
4223         if(bm&0x0002){
4224                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
4225                         tvb, offset, 2, mask);
4226         }
4227         if(bm&0x0004){
4228                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
4229                         tvb, offset, 2, mask);
4230         }
4231         if(bm&0x0008){
4232                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
4233                         tvb, offset, 2, mask);
4234         }
4235
4236         offset += 2;
4237
4238         return offset;
4239 }
4240
4241 static const value_string filetype_vals[] = {
4242         { 0,            "Disk file or directory"},
4243         { 1,            "Named pipe in byte mode"},
4244         { 2,            "Named pipe in message mode"},
4245         { 3,            "Spooled printer"},
4246         {0, NULL}
4247 };
4248 static int
4249 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4250 {
4251         guint8  wc, cmd=0xff;
4252         guint16 andxoffset=0, bc;
4253         int fn_len;
4254         const char *fn;
4255
4256         WORD_COUNT;
4257
4258         /* next smb command */
4259         cmd = tvb_get_guint8(tvb, offset);
4260         if(cmd!=0xff){
4261                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4262         } else {
4263                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4264         }
4265         offset += 1;
4266
4267         /* reserved byte */
4268         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4269         offset += 1;
4270
4271         /* andxoffset */
4272         andxoffset = tvb_get_letohs(tvb, offset);
4273         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4274         offset += 2;
4275
4276         /* open flags */
4277         offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x0007);
4278
4279         /* desired access */
4280         offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
4281
4282         /* Search Attributes */
4283         offset = dissect_search_attributes(tvb, pinfo, tree, offset);
4284
4285         /* File Attributes */
4286         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4287
4288         /* creation time */
4289         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_create_time);
4290         
4291         /* open function */
4292         offset = dissect_open_function(tvb, pinfo, tree, offset);
4293
4294         /* allocation size */
4295         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
4296         offset += 4;
4297
4298         /* 8 reserved bytes */
4299         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
4300         offset += 8;
4301
4302         BYTE_COUNT;
4303
4304         /* file name */
4305         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
4306                 FALSE, FALSE, &bc);
4307         if (fn == NULL)
4308                 goto endofcommand;
4309         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4310                 fn);
4311         COUNT_BYTES(fn_len);
4312
4313         if (check_col(pinfo->fd, COL_INFO)) {
4314                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
4315         }
4316
4317         END_OF_SMB
4318
4319         /* call AndXCommand (if there are any) */
4320         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4321
4322         return offset;
4323 }
4324
4325 static const true_false_string tfs_ipc_state_nonblocking = {
4326         "Reads/writes return immediately if no data available",
4327         "Reads/writes block if no data available"
4328 };
4329 static const value_string ipc_state_endpoint_vals[] = {
4330         { 0,            "Consumer end of pipe"},
4331         { 1,            "Server end of pipe"},
4332         {0,     NULL}
4333 };
4334 static const value_string ipc_state_pipe_type_vals[] = {
4335         { 0,            "Byte stream pipe"},
4336         { 1,            "Message pipe"},
4337         {0,     NULL}
4338 };
4339 static const value_string ipc_state_read_mode_vals[] = {
4340         { 0,            "Read pipe as a byte stream"},
4341         { 1,            "Read messages from pipe"},
4342         {0,     NULL}
4343 };
4344
4345 static int
4346 dissect_ipc_state(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4347 {
4348         guint16 mask;
4349         proto_item *item = NULL;
4350         proto_tree *tree = NULL;
4351
4352         mask = tvb_get_letohs(tvb, offset);
4353
4354         if(parent_tree){
4355                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4356                         "IPC State: 0x%04x", mask);
4357                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
4358         }
4359
4360         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
4361                 tvb, offset, 2, mask);
4362         proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
4363                 tvb, offset, 2, mask);
4364         proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
4365                 tvb, offset, 2, mask);
4366         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
4367                 tvb, offset, 2, mask);
4368         proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
4369                 tvb, offset, 2, mask);
4370
4371         offset += 2;
4372
4373         return offset;
4374 }
4375
4376 static int
4377 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4378 {
4379         guint8  wc, cmd=0xff;
4380         guint16 andxoffset=0, bc;
4381         guint16 fid;
4382
4383         WORD_COUNT;
4384
4385         /* next smb command */
4386         cmd = tvb_get_guint8(tvb, offset);
4387         if(cmd!=0xff){
4388                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4389         } else {
4390                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4391         }
4392         offset += 1;
4393
4394         /* reserved byte */
4395         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4396         offset += 1;
4397
4398         /* andxoffset */
4399         andxoffset = tvb_get_letohs(tvb, offset);
4400         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4401         offset += 2;
4402
4403         /* fid */
4404         fid = tvb_get_letohs(tvb, offset);
4405         add_fid(tvb, pinfo, tree, offset, fid);
4406         offset += 2;
4407
4408         /* File Attributes */
4409         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
4410
4411         /* last write time */
4412         offset = dissect_smb_UTIME(tvb, pinfo, tree, offset, hf_smb_last_write_time);
4413         
4414         /* File Size */
4415         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4416         offset += 4;
4417
4418         /* granted access */
4419         offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
4420
4421         /* File Type */
4422         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
4423         offset += 2;
4424
4425         /* IPC State */
4426         offset = dissect_ipc_state(tvb, pinfo, tree, offset);
4427
4428         /* open_action */
4429         offset = dissect_open_action(tvb, pinfo, tree, offset);
4430
4431         /* server fid */
4432         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
4433         offset += 4;
4434
4435         /* 2 reserved bytes */
4436         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4437         offset += 2;
4438
4439         BYTE_COUNT;
4440
4441         END_OF_SMB
4442
4443         /* call AndXCommand (if there are any) */
4444         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4445
4446         return offset;
4447 }
4448
4449 static int
4450 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4451 {
4452         guint8  wc, cmd=0xff;
4453         guint16 andxoffset=0, bc;
4454
4455         WORD_COUNT;
4456
4457         /* next smb command */
4458         cmd = tvb_get_guint8(tvb, offset);
4459         if(cmd!=0xff){
4460                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4461         } else {
4462                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4463         }
4464         offset += 1;
4465
4466         /* reserved byte */
4467         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4468         offset += 1;
4469
4470         /* andxoffset */
4471         andxoffset = tvb_get_letohs(tvb, offset);
4472         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4473         offset += 2;
4474
4475         /* fid */
4476         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
4477         offset += 2;
4478
4479         /* offset */
4480         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4481         offset += 4;
4482
4483         /* max count */
4484         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4485         offset += 2;
4486
4487         /* min count */
4488         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4489         offset += 2;
4490
4491         /* XXX - max count high */
4492         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4493         offset += 4;
4494
4495         /* remaining */
4496         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4497         offset += 2;
4498
4499         if(wc==12){
4500                 /* high offset */
4501                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4502                 offset += 4;
4503         }
4504
4505         BYTE_COUNT;
4506
4507         END_OF_SMB
4508
4509         /* call AndXCommand (if there are any) */
4510         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4511
4512         return offset;
4513 }
4514
4515 static int
4516 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4517 {
4518         guint8  wc, cmd=0xff;
4519         guint16 andxoffset=0, bc, datalen=0;
4520         int len;
4521
4522         WORD_COUNT;
4523
4524         /* next smb command */
4525         cmd = tvb_get_guint8(tvb, offset);
4526         if(cmd!=0xff){
4527                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4528         } else {
4529                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4530         }
4531         offset += 1;
4532  
4533         /* reserved byte */
4534         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4535         offset += 1;
4536
4537         /* andxoffset */
4538         andxoffset = tvb_get_letohs(tvb, offset);
4539         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4540         offset += 2;
4541
4542         /* remaining */
4543         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4544         offset += 2;
4545
4546         /* data compaction mode */
4547         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4548         offset += 2;
4549
4550         /* 2 reserved bytes */
4551         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4552         offset += 2;
4553
4554         /* data len */
4555         datalen = tvb_get_letohs(tvb, offset);
4556         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4557         offset += 2;
4558
4559         /* data offset */
4560         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4561         offset += 2;
4562
4563         /* 10 reserved bytes */
4564         /* XXX - first 2 bytes are data length high, not reserved */
4565         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
4566         offset += 10;
4567
4568         BYTE_COUNT;
4569
4570         /* file data */
4571         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
4572         bc = 0;
4573
4574         END_OF_SMB
4575
4576         /* call AndXCommand (if there are any) */
4577         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4578
4579         return offset;
4580 }
4581
4582 static int
4583 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4584 {
4585         guint8  wc, cmd=0xff;
4586         guint16 andxoffset=0, bc, datalen=0;
4587
4588         WORD_COUNT;
4589
4590         /* next smb command */
4591         cmd = tvb_get_guint8(tvb, offset);
4592         if(cmd!=0xff){
4593                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4594         } else {
4595                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4596         }
4597         offset += 1;
4598
4599         /* reserved byte */
4600         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4601         offset += 1;
4602
4603         /* andxoffset */
4604         andxoffset = tvb_get_letohs(tvb, offset);
4605         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4606         offset += 2;
4607
4608         /* fid */
4609         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
4610         offset += 2;
4611
4612         /* offset */
4613         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4614         offset += 4;
4615
4616         /* reserved */
4617         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4618         offset += 4;
4619
4620         /* mode */
4621         offset = dissect_write_mode(tvb, pinfo, tree, offset, 0x000f);
4622
4623         /* remaining */
4624         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4625         offset += 2;
4626
4627         /* XXX - data length high */
4628         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4629         offset += 2;
4630
4631         /* data len */
4632         datalen = tvb_get_letohs(tvb, offset);
4633         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4634         offset += 2;
4635
4636         /* data offset */
4637         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4638         offset += 2;
4639
4640         if(wc==14){
4641                 /* high offset */
4642                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
4643                 offset += 4;
4644         }
4645
4646         BYTE_COUNT;
4647
4648         /* file data */
4649         offset = dissect_file_data(tvb, pinfo, tree, offset, bc, datalen);
4650         bc = 0;
4651
4652         END_OF_SMB
4653
4654         /* call AndXCommand (if there are any) */
4655         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4656
4657         return offset;
4658 }
4659
4660 static int
4661 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4662 {
4663         guint8  wc, cmd=0xff;
4664         guint16 andxoffset=0, bc, datalen=0;
4665         int len;
4666
4667         WORD_COUNT;
4668
4669         /* next smb command */
4670         cmd = tvb_get_guint8(tvb, offset);
4671         if(cmd!=0xff){
4672                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4673         } else {
4674                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4675         }
4676         offset += 1;
4677  
4678         /* reserved byte */
4679         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4680         offset += 1;
4681
4682         /* andxoffset */
4683         andxoffset = tvb_get_letohs(tvb, offset);
4684         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4685         offset += 2;
4686
4687         /* write count */
4688         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4689         offset += 2;
4690
4691         /* remaining */
4692         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4693         offset += 2;
4694
4695         /* 4 reserved bytes */
4696         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4697         offset += 4;
4698
4699         BYTE_COUNT;
4700
4701         END_OF_SMB
4702
4703         /* call AndXCommand (if there are any) */
4704         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4705
4706         return offset;
4707 }
4708
4709
4710 static const true_false_string tfs_setup_action_guest = {
4711         "Logged in as GUEST",
4712         "Not logged in as GUEST"
4713 };
4714 static int
4715 dissect_setup_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
4716 {
4717         guint16 mask;
4718         proto_item *item = NULL;
4719         proto_tree *tree = NULL;
4720
4721         mask = tvb_get_letohs(tvb, offset);
4722
4723         if(parent_tree){
4724                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4725                         "Action: 0x%04x", mask);
4726                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
4727         }
4728
4729         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
4730                 tvb, offset, 2, mask);
4731
4732         offset += 2;
4733
4734         return offset;
4735 }
4736  
4737
4738 static int
4739 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4740 {
4741         guint8  wc, cmd=0xff;
4742         guint16 bc;
4743         guint16 andxoffset=0;
4744         int an_len;
4745         const char *an;
4746         int dn_len;
4747         const char *dn;
4748         guint16 pwlen=0;
4749         guint16 sbloblen=0;
4750         guint16 apwlen=0, upwlen=0;
4751
4752         WORD_COUNT;
4753
4754         /* next smb command */
4755         cmd = tvb_get_guint8(tvb, offset);
4756         if(cmd!=0xff){
4757                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4758         } else {
4759                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
4760         }
4761         offset += 1;
4762
4763         /* reserved byte */
4764         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4765         offset += 1;
4766
4767         /* andxoffset */
4768         andxoffset = tvb_get_letohs(tvb, offset);
4769         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4770         offset += 2;
4771
4772         /* Maximum Buffer Size */
4773         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
4774         offset += 2;
4775
4776         /* Maximum Multiplex Count */
4777         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
4778         offset += 2;
4779
4780         /* VC Number */
4781         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
4782         offset += 2;
4783
4784         /* session key */
4785         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
4786         offset += 4;
4787
4788         switch (wc) {
4789         case 10:
4790                 /* password length, ASCII*/
4791                 pwlen = tvb_get_letohs(tvb, offset);
4792                 proto_tree_add_uint(tree, hf_smb_password_len,
4793                         tvb, offset, 2, pwlen);
4794                 offset += 2;
4795
4796                 /* 4 reserved bytes */
4797                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4798                 offset += 4;
4799
4800                 break;
4801
4802         case 12:
4803                 /* security blob length */
4804                 sbloblen = tvb_get_letohs(tvb, offset);
4805                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
4806                 offset += 2;
4807
4808                 /* 4 reserved bytes */
4809                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4810                 offset += 4;
4811
4812                 /* capabilities */
4813                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
4814                 offset += 4;
4815
4816                 break;
4817
4818         case 13:
4819                 /* password length, ANSI*/
4820                 apwlen = tvb_get_letohs(tvb, offset);
4821                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
4822                         tvb, offset, 2, apwlen);
4823                 offset += 2;
4824
4825                 /* password length, Unicode*/
4826                 upwlen = tvb_get_letohs(tvb, offset);
4827                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
4828                         tvb, offset, 2, upwlen);
4829                 offset += 2;
4830
4831                 /* 4 reserved bytes */
4832                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4833                 offset += 4;
4834
4835                 /* capabilities */
4836                 dissect_negprot_capabilities(tvb, pinfo, tree, offset);
4837                 offset += 4;
4838
4839                 break;
4840         }
4841
4842         BYTE_COUNT;
4843
4844         if (wc==12) {
4845                 /* security blob */
4846                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
4847                    data structure, at least in NT 5.0-and-later
4848                    server replies? */
4849                 if(sbloblen){
4850                         CHECK_BYTE_COUNT(sbloblen);
4851                         proto_tree_add_item(tree, hf_smb_security_blob,
4852                                 tvb, offset, sbloblen, TRUE);
4853                         COUNT_BYTES(sbloblen);
4854                 }
4855
4856                 /* OS */
4857                 an = get_unicode_or_ascii_string(tvb, &offset,
4858                         pinfo, &an_len, FALSE, FALSE, &bc);
4859                 if (an == NULL)
4860                         goto endofcommand;
4861                 proto_tree_add_string(tree, hf_smb_os, tvb,
4862                         offset, an_len, an);
4863                 COUNT_BYTES(an_len);
4864
4865                 /* LANMAN */
4866                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
4867                  * padding/null string/whatever in front of this. W2K doesn't
4868                  * appear to. I suspect that's a bug that got fixed; I also
4869                  * suspect that, in practice, nobody ever looks at that field
4870                  * because the bug didn't appear to get fixed until NT 5.0....
4871                  */
4872                 an = get_unicode_or_ascii_string(tvb, &offset,
4873                         pinfo, &an_len, FALSE, FALSE, &bc);
4874                 if (an == NULL)
4875                         goto endofcommand;
4876                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
4877                         offset, an_len, an);
4878                 COUNT_BYTES(an_len);
4879
4880                 /* Primary domain */
4881                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
4882                  * byte in front of this, at least if all the strings are
4883                  * ASCII and the account name is empty. Another bug?
4884                  */
4885                 dn = get_unicode_or_ascii_string(tvb, &offset,
4886                         pinfo, &dn_len, FALSE, FALSE, &bc);
4887                 if (dn == NULL)
4888                         goto endofcommand;
4889                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
4890                         offset, dn_len, dn);
4891                 COUNT_BYTES(dn_len);
4892         } else {
4893                 switch (wc) {
4894
4895                 case 10:
4896                         if(pwlen){
4897                                 /* password, ASCII */
4898                                 CHECK_BYTE_COUNT(pwlen);
4899                                 proto_tree_add_item(tree, hf_smb_password, 
4900                                         tvb, offset, pwlen, TRUE);
4901                                 COUNT_BYTES(pwlen);
4902                         }
4903
4904                         break;
4905
4906                 case 13:
4907                         if(apwlen){
4908                                 /* password, ANSI */
4909                                 CHECK_BYTE_COUNT(apwlen);
4910                                 proto_tree_add_item(tree, hf_smb_ansi_password, 
4911                                         tvb, offset, apwlen, TRUE);
4912                                 COUNT_BYTES(apwlen);
4913                         }
4914
4915                         if(upwlen){
4916                                 /* password, Unicode */
4917                                 CHECK_BYTE_COUNT(upwlen);
4918                                 proto_tree_add_item(tree, hf_smb_unicode_password, 
4919                                         tvb, offset, upwlen, TRUE);
4920                                 COUNT_BYTES(upwlen);
4921                         }
4922
4923                         break;
4924                 }
4925
4926                 /* Account Name */
4927                 an = get_unicode_or_ascii_string(tvb, &offset,
4928                         pinfo, &an_len, FALSE, FALSE, &bc);
4929                 if (an == NULL)
4930                         goto endofcommand;
4931                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
4932                         an);
4933                 COUNT_BYTES(an_len);
4934
4935                 /* Primary domain */
4936                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
4937                  * byte in front of this, at least if all the strings are
4938                  * ASCII and the account name is empty. Another bug?
4939                  */
4940                 dn = get_unicode_or_ascii_string(tvb, &offset,
4941                         pinfo, &dn_len, FALSE, FALSE, &bc);
4942                 if (dn == NULL)
4943                         goto endofcommand;
4944                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
4945                         offset, dn_len, dn);
4946                 COUNT_BYTES(dn_len);
4947
4948                 if (check_col(pinfo->fd, COL_INFO)) {
4949                         col_append_fstr(pinfo->fd, COL_INFO, ", User: %s@%s",
4950                         an,dn);
4951                 }
4952
4953                 /* OS */
4954                 an = get_unicode_or_ascii_string(tvb, &offset,
4955                         pinfo, &an_len, FALSE, FALSE, &bc);
4956                 if (an == NULL)
4957                         goto endofcommand;
4958                 proto_tree_add_string(tree, hf_smb_os, tvb,
4959                         offset, an_len, an);
4960                 COUNT_BYTES(an_len);
4961
4962                 /* LANMAN */
4963                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
4964                  * padding/null string/whatever in front of this. W2K doesn't
4965                  * appear to. I suspect that's a bug that got fixed; I also
4966                  * suspect that, in practice, nobody ever looks at that field
4967                  * because the bug didn't appear to get fixed until NT 5.0....
4968                  */
4969                 an = get_unicode_or_ascii_string(tvb, &offset,
4970                         pinfo, &an_len, FALSE, FALSE, &bc);
4971                 if (an == NULL)
4972                         goto endofcommand;
4973                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
4974                         offset, an_len, an);
4975                 COUNT_BYTES(an_len);
4976         }
4977
4978         END_OF_SMB
4979
4980         /* call AndXCommand (if there are any) */
4981         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
4982
4983         return offset;
4984 }
4985
4986 static int
4987 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
4988 {
4989         guint8  wc, cmd=0xff;
4990         guint16 andxoffset=0, bc;
4991         guint16 sbloblen=0;
4992         int an_len;
4993         const char *an;
4994
4995         WORD_COUNT;
4996
4997         /* next smb command */
4998         cmd = tvb_get_guint8(tvb, offset);
4999         if(cmd!=0xff){
5000                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5001         } else {
5002                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5003         }
5004         offset += 1;
5005
5006         /* reserved byte */
5007         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5008         offset += 1;
5009
5010         /* andxoffset */
5011         andxoffset = tvb_get_letohs(tvb, offset);
5012         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5013         offset += 2;
5014
5015         /* flags */
5016         offset = dissect_setup_action(tvb, pinfo, tree, offset);
5017
5018         if(wc==4){
5019                 /* security blob length */
5020                 sbloblen = tvb_get_letohs(tvb, offset);
5021                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5022                 offset += 2;
5023         }
5024
5025         BYTE_COUNT;
5026
5027         if(wc==4) {
5028                 /* security blob */
5029                 /* XXX - is this ASN.1-encoded?  Is it a Kerberos
5030                    data structure, at least in NT 5.0-and-later
5031                    server replies? */
5032                 if(sbloblen){
5033                         CHECK_BYTE_COUNT(sbloblen);
5034                         proto_tree_add_item(tree, hf_smb_security_blob,
5035                                 tvb, offset, sbloblen, TRUE);
5036                         COUNT_BYTES(sbloblen);
5037                 }
5038         }
5039
5040         /* OS */
5041         an = get_unicode_or_ascii_string(tvb, &offset,
5042                 pinfo, &an_len, FALSE, FALSE, &bc);
5043         if (an == NULL)
5044                 goto endofcommand;
5045         proto_tree_add_string(tree, hf_smb_os, tvb,
5046                 offset, an_len, an);
5047         COUNT_BYTES(an_len);
5048
5049         /* LANMAN */
5050         an = get_unicode_or_ascii_string(tvb, &offset,
5051                 pinfo, &an_len, FALSE, FALSE, &bc);
5052         if (an == NULL)
5053                 goto endofcommand;
5054         proto_tree_add_string(tree, hf_smb_lanman, tvb,
5055                 offset, an_len, an);
5056         COUNT_BYTES(an_len);
5057
5058         if(wc==3) {
5059                 /* Primary domain */
5060                 an = get_unicode_or_ascii_string(tvb, &offset,
5061                         pinfo, &an_len, FALSE, FALSE, &bc);
5062                 if (an == NULL)
5063                         goto endofcommand;
5064                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5065                         offset, an_len, an);
5066                 COUNT_BYTES(an_len);
5067         }
5068
5069         END_OF_SMB
5070
5071         /* call AndXCommand (if there are any) */
5072         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5073
5074         return offset;
5075 }
5076
5077  
5078 static int
5079 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5080 {
5081         guint8  wc, cmd=0xff;
5082         guint16 andxoffset=0;
5083         guint16 bc;
5084
5085         WORD_COUNT;
5086
5087         /* next smb command */
5088         cmd = tvb_get_guint8(tvb, offset);
5089         if(cmd!=0xff){
5090                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5091         } else {
5092                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
5093         }
5094         offset += 1;
5095
5096         /* reserved byte */
5097         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5098         offset += 1;
5099
5100         /* andxoffset */
5101         andxoffset = tvb_get_letohs(tvb, offset);
5102         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5103         offset += 2;
5104
5105         BYTE_COUNT;
5106
5107         END_OF_SMB
5108
5109         /* call AndXCommand (if there are any) */
5110         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5111
5112         return offset;
5113 }
5114
5115  
5116 static const true_false_string tfs_connect_support_search = {
5117         "Exclusive search bits supported",
5118         "Exclusive search bits not supported"
5119 };
5120 static const true_false_string tfs_connect_support_in_dfs = {
5121         "Share is in Dfs",
5122         "Share isn't in Dfs"
5123 };
5124
5125 static int
5126 dissect_connect_support_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5127 {
5128         guint16 mask;
5129         proto_item *item = NULL;
5130         proto_tree *tree = NULL;
5131
5132         mask = tvb_get_letohs(tvb, offset);
5133
5134         if(parent_tree){
5135                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5136                         "Optional Support: 0x%04x", mask);
5137                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
5138         }
5139
5140         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
5141                 tvb, offset, 2, mask);
5142         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
5143                 tvb, offset, 2, mask);
5144
5145         offset += 2;
5146
5147         return offset;
5148 }
5149
5150 static const true_false_string tfs_disconnect_tid = {
5151         "DISCONNECT TID",
5152         "Do NOT disconnect TID"
5153 };
5154
5155 static int
5156 dissect_connect_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5157 {
5158         guint16 mask;
5159         proto_item *item = NULL;
5160         proto_tree *tree = NULL;
5161
5162         mask = tvb_get_letohs(tvb, offset);
5163
5164         if(parent_tree){
5165                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5166                         "Flags: 0x%04x", mask);
5167                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
5168         }
5169
5170         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
5171                 tvb, offset, 2, mask);
5172
5173         offset += 2;
5174
5175         return offset;
5176 }
5177
5178 static int
5179 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5180 {
5181         guint8  wc, cmd=0xff;
5182         guint16 bc;
5183         guint16 andxoffset=0, pwlen=0;
5184         int an_len;
5185         const char *an;
5186
5187         WORD_COUNT;
5188
5189         /* next smb command */
5190         cmd = tvb_get_guint8(tvb, offset);
5191         if(cmd!=0xff){
5192                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5193         } else {
5194                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5195         }
5196         offset += 1;
5197
5198         /* reserved byte */
5199         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5200         offset += 1;
5201
5202         /* andxoffset */
5203         andxoffset = tvb_get_letohs(tvb, offset);
5204         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5205         offset += 2;
5206
5207         /* flags */
5208         offset = dissect_connect_flags(tvb, pinfo, tree, offset);
5209
5210         /* password length*/
5211         pwlen = tvb_get_letohs(tvb, offset);
5212         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
5213         offset += 2;
5214
5215         BYTE_COUNT;
5216
5217         /* password */
5218         CHECK_BYTE_COUNT(pwlen);
5219         proto_tree_add_item(tree, hf_smb_password, 
5220                 tvb, offset, pwlen, TRUE);
5221         COUNT_BYTES(pwlen);
5222
5223         /* Path */
5224         an = get_unicode_or_ascii_string(tvb, &offset,
5225                 pinfo, &an_len, FALSE, FALSE, &bc);
5226         if (an == NULL)
5227                 goto endofcommand;
5228         proto_tree_add_string(tree, hf_smb_path, tvb,
5229                 offset, an_len, an);
5230         COUNT_BYTES(an_len);
5231
5232         if (check_col(pinfo->fd, COL_INFO)) {
5233                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", an);
5234         }
5235
5236         /*
5237          * NOTE: the Service string is always ASCII, even if the
5238          * "strings are Unicode" bit is set in the flags2 field
5239          * of the SMB.
5240          */
5241
5242         /* Service */
5243         /* XXX - what if this runs past bc? */
5244         an_len = tvb_strsize(tvb, offset);
5245         CHECK_BYTE_COUNT(an_len);
5246         an = tvb_get_ptr(tvb, offset, an_len);
5247         proto_tree_add_string(tree, hf_smb_service, tvb,
5248                 offset, an_len, an);
5249         COUNT_BYTES(an_len);
5250
5251         END_OF_SMB
5252
5253         /* call AndXCommand (if there are any) */
5254         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5255
5256         return offset;
5257 }
5258
5259
5260 static int
5261 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5262 {
5263         guint8  wc, wleft, cmd=0xff;
5264         guint16 andxoffset=0;
5265         guint16 bc;
5266         int an_len;
5267         const char *an;
5268
5269         WORD_COUNT;
5270
5271         wleft = wc;     /* this is at least 1 */
5272
5273         /* next smb command */
5274         cmd = tvb_get_guint8(tvb, offset);
5275         if(cmd!=0xff){
5276                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5277         } else {
5278                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
5279         }
5280         offset += 1;
5281
5282         /* reserved byte */
5283         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5284         offset += 1;
5285
5286         wleft--;
5287         if (wleft == 0)
5288                 goto bytecount;
5289
5290         /* andxoffset */
5291         andxoffset = tvb_get_letohs(tvb, offset);
5292         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5293         offset += 2;
5294         wleft--;
5295         if (wleft == 0)
5296                 goto bytecount;
5297
5298         /* flags */
5299         offset = dissect_connect_support_bits(tvb, pinfo, tree, offset);
5300         wleft--;
5301
5302         /* XXX - I've seen captures where this is 7, but I have no
5303            idea how to dissect it.  I'm guessing the third word
5304            contains connect support bits, which looks plausible
5305            from the values I've seen. */
5306
5307         while (wleft != 0) {
5308                 proto_tree_add_text(tree, tvb, offset, 2,
5309                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
5310                 offset += 2;
5311                 wleft--;
5312         }
5313
5314         BYTE_COUNT;
5315
5316         /*
5317          * NOTE: even though the SNIA CIFS spec doesn't say there's
5318          * a "Service" string if there's a word count of 2, the
5319          * document at
5320          *
5321          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
5322          *
5323          * (it's in an ugly format - text intended to be sent to a
5324          * printer, with backspaces and overstrikes used for boldfacing
5325          * and underlining; UNIX "col -b" can be used to strip the
5326          * overstrikes out) says there's a "Service" string there, and
5327          * some network traffic has it.
5328          */
5329
5330         /*
5331          * NOTE: the Service string is always ASCII, even if the
5332          * "strings are Unicode" bit is set in the flags2 field
5333          * of the SMB.
5334          */
5335
5336         /* Service */
5337         /* XXX - what if this runs past bc? */
5338         an_len = tvb_strsize(tvb, offset);
5339         CHECK_BYTE_COUNT(an_len);
5340         an = tvb_get_ptr(tvb, offset, an_len);
5341         proto_tree_add_string(tree, hf_smb_service, tvb,
5342                 offset, an_len, an);
5343         COUNT_BYTES(an_len);
5344
5345         if(wc==3){
5346                 if (bc != 0) {
5347                         /*
5348                          * Sometimes this isn't present.
5349                          */
5350
5351                         /* Native FS */
5352                         an = get_unicode_or_ascii_string(tvb, &offset,
5353                                 pinfo, &an_len, /*TRUE*/FALSE, FALSE, &bc);
5354                         if (an == NULL)
5355                                 goto endofcommand;
5356                         proto_tree_add_string(tree, hf_smb_fs, tvb,
5357                                 offset, an_len, an);
5358                         COUNT_BYTES(an_len);
5359                 }
5360         }
5361
5362         END_OF_SMB
5363
5364         /* call AndXCommand (if there are any) */
5365         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
5366
5367         return offset;
5368 }
5369
5370
5371
5372 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5373    NT Transaction command  begins here
5374    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
5375 #define NT_TRANS_CREATE         1
5376 #define NT_TRANS_IOCTL          2
5377 #define NT_TRANS_SSD            3
5378 #define NT_TRANS_NOTIFY         4
5379 #define NT_TRANS_RENAME         5
5380 #define NT_TRANS_QSD            6
5381 static const value_string nt_cmd_vals[] = {
5382         {NT_TRANS_CREATE,       "NT CREATE"},
5383         {NT_TRANS_IOCTL,        "NT IOCTL"},
5384         {NT_TRANS_SSD,          "NT SET SECURITY DESC"},
5385         {NT_TRANS_NOTIFY,       "NT NOTIFY"},
5386         {NT_TRANS_RENAME,       "NT RENAME"},
5387         {NT_TRANS_QSD,          "NT QUERY SECURITY DESC"},
5388         {0, NULL}
5389 };
5390
5391 static const value_string nt_ioctl_isfsctl_vals[] = {
5392         {0,     "Device IOCTL"},
5393         {1,     "FS control : FSCTL"},
5394         {0, NULL}
5395 };
5396
5397 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
5398 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
5399         "Apply the command to share root handle (MUST BE Dfs)",
5400         "Apply to this share",
5401 };
5402
5403 static const value_string nt_notify_action_vals[] = {
5404         {1,     "ADDED (object was added"},
5405         {2,     "REMOVED (object was removed)"},
5406         {3,     "MODIFIED (object was modified)"},
5407         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
5408         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
5409         {6,     "ADDED_STREAM (a stream was added)"},
5410         {7,     "REMOVED_STREAM (a stream was removed)"},
5411         {8,     "MODIFIED_STREAM (a stream was modified)"},
5412         {0, NULL}
5413 };
5414
5415 static const value_string watch_tree_vals[] = {
5416         {0,     "Current directory only"},
5417         {1,     "Subdirectories also"},
5418         {0, NULL}
5419 };
5420
5421 #define NT_NOTIFY_STREAM_WRITE  0x00000800
5422 #define NT_NOTIFY_STREAM_SIZE   0x00000400
5423 #define NT_NOTIFY_STREAM_NAME   0x00000200
5424 #define NT_NOTIFY_SECURITY      0x00000100
5425 #define NT_NOTIFY_EA            0x00000080
5426 #define NT_NOTIFY_CREATION      0x00000040
5427 #define NT_NOTIFY_LAST_ACCESS   0x00000020
5428 #define NT_NOTIFY_LAST_WRITE    0x00000010
5429 #define NT_NOTIFY_SIZE          0x00000008
5430 #define NT_NOTIFY_ATTRIBUTES    0x00000004
5431 #define NT_NOTIFY_DIR_NAME      0x00000002
5432 #define NT_NOTIFY_FILE_NAME     0x00000001
5433 static const true_false_string tfs_nt_notify_stream_write = {
5434         "Notify on changes to STREAM WRITE",
5435         "Do NOT notify on changes to stream write",
5436 };
5437 static const true_false_string tfs_nt_notify_stream_size = {
5438         "Notify on changes to STREAM SIZE",
5439         "Do NOT notify on changes to stream size",
5440 };
5441 static const true_false_string tfs_nt_notify_stream_name = {
5442         "Notify on changes to STREAM NAME",
5443         "Do NOT notify on changes to stream name",
5444 };
5445 static const true_false_string tfs_nt_notify_security = {
5446         "Notify on changes to SECURITY",
5447         "Do NOT notify on changes to security",
5448 };
5449 static const true_false_string tfs_nt_notify_ea = {
5450         "Notify on changes to EA",
5451         "Do NOT notify on changes to EA",
5452 };
5453 static const true_false_string tfs_nt_notify_creation = {
5454         "Notify on changes to CREATION TIME",
5455         "Do NOT notify on changes to creation time",
5456 };
5457 static const true_false_string tfs_nt_notify_last_access = {
5458         "Notify on changes to LAST ACCESS TIME",
5459         "Do NOT notify on changes to last access time",
5460 };
5461 static const true_false_string tfs_nt_notify_last_write = {
5462         "Notify on changes to LAST WRITE TIME",
5463         "Do NOT notify on changes to last write time",
5464 };
5465 static const true_false_string tfs_nt_notify_size = {
5466         "Notify on changes to SIZE",
5467         "Do NOT notify on changes to size",
5468 };
5469 static const true_false_string tfs_nt_notify_attributes = {
5470         "Notify on changes to ATTRIBUTES",
5471         "Do NOT notify on changes to attributes",
5472 };
5473 static const true_false_string tfs_nt_notify_dir_name = {
5474         "Notify on changes to DIR NAME",
5475         "Do NOT notify on changes to dir name",
5476 };
5477 static const true_false_string tfs_nt_notify_file_name = {
5478         "Notify on changes to FILE NAME",
5479         "Do NOT notify on changes to file name",
5480 };
5481
5482 static const value_string create_disposition_vals[] = {
5483         {0,     "Supersede (supersede existing file (if it exists))"},
5484         {1,     "Open (if file exists open it, else fail)"},
5485         {2,     "Create (if file exists fail, else create it)"},
5486         {3,     "Open If (if file exists open it, else create it)"},
5487         {4,     "Overwrite (if file exists overwrite, else fail)"},
5488         {5,     "Overwrite If (if file exists overwrite, else create it)"},
5489         {0, NULL}
5490 };
5491
5492 static const value_string impersonation_level_vals[] = {
5493         {0,     "Anonymous"},
5494         {1,     "Identification"},
5495         {2,     "Impersonation"},
5496         {3,     "Delegation"},
5497         {0, NULL}
5498 };
5499
5500 static const true_false_string tfs_nt_security_flags_context_tracking = {
5501         "Security tracking mode is DYNAMIC",
5502         "Security tracking mode is STATIC",
5503 };
5504
5505 static const true_false_string tfs_nt_security_flags_effective_only = {
5506         "ONLY ENABLED aspects of the client's security context are available",
5507         "ALL aspects of the client's security context are available",
5508 };
5509
5510 static const true_false_string tfs_nt_create_bits_oplock = {
5511         "Requesting OPLOCK",
5512         "Does NOT request oplock"
5513 };
5514
5515 static const true_false_string tfs_nt_create_bits_boplock = {
5516         "Requesting BATCH OPLOCK",
5517         "Does NOT request batch oplock"
5518 };
5519
5520 /*
5521  * XXX - must be a directory, and can be a file, or can be a directory,
5522  * and must be a file?
5523  */
5524 static const true_false_string tfs_nt_create_bits_dir = {
5525         "Target of open MUST be a DIRECTORY",
5526         "Target of open can be a file"
5527 };
5528
5529 static const true_false_string tfs_nt_access_mask_generic_read = {
5530         "GENERIC READ is set",
5531         "Generic read is NOT set"
5532 };
5533 static const true_false_string tfs_nt_access_mask_generic_write = {
5534         "GENERIC WRITE is set",
5535         "Generic write is NOT set"
5536 };
5537 static const true_false_string tfs_nt_access_mask_generic_execute = {
5538         "GENERIC EXECUTE is set",
5539         "Generic execute is NOT set"
5540 };
5541 static const true_false_string tfs_nt_access_mask_generic_all = {
5542         "GENERIC ALL is set",
5543         "Generic all is NOT set"
5544 };
5545 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
5546         "MAXIMUM ALLOWED is set",
5547         "Maximum allowed is NOT set"
5548 };
5549 static const true_false_string tfs_nt_access_mask_system_security = {
5550         "SYSTEM SECURITY is set",
5551         "System security is NOT set"
5552 };
5553 static const true_false_string tfs_nt_access_mask_synchronize = {
5554         "Can wait on handle to SYNCHRONIZE on completion of I/O",
5555         "Can NOT wait on handle to synchronize on completion of I/O"
5556 };
5557 static const true_false_string tfs_nt_access_mask_write_owner = {
5558         "Can WRITE OWNER (take ownership)",
5559         "Can NOT write owner (take ownership)"
5560 };
5561 static const true_false_string tfs_nt_access_mask_write_dac = {
5562         "OWNER may WRITE the DAC",
5563         "Owner may NOT write to the DAC"
5564 };
5565 static const true_false_string tfs_nt_access_mask_read_control = {
5566         "READ ACCESS to owner, group and ACL of the SID",
5567         "Read access is NOT granted to owner, group and ACL of the SID"
5568 };
5569 static const true_false_string tfs_nt_access_mask_delete = {
5570         "DELETE access",
5571         "NO delete access"
5572 };
5573 static const true_false_string tfs_nt_access_mask_write_attributes = {
5574         "WRITE ATTRIBUTES access",
5575         "NO write attributes access"
5576 };
5577 static const true_false_string tfs_nt_access_mask_read_attributes = {
5578         "READ ATTRIBUTES access",
5579         "NO read attributes access"
5580 };
5581 static const true_false_string tfs_nt_access_mask_delete_child = {
5582         "DELETE CHILD access",
5583         "NO delete child access"
5584 };
5585 static const true_false_string tfs_nt_access_mask_execute = {
5586         "EXECUTE access",
5587         "NO execute access"
5588 };
5589 static const true_false_string tfs_nt_access_mask_write_ea = {
5590         "WRITE EXTENDED ATTRIBUTES access",
5591         "NO write extended attributes access"
5592 };
5593 static const true_false_string tfs_nt_access_mask_read_ea = {
5594         "READ EXTENDED ATTRIBUTES access",
5595         "NO read extended attributes access"
5596 };
5597 static const true_false_string tfs_nt_access_mask_append = {
5598         "APPEND access",
5599         "NO append access"
5600 };
5601 static const true_false_string tfs_nt_access_mask_write = {
5602         "WRITE access",
5603         "NO write access"
5604 };
5605 static const true_false_string tfs_nt_access_mask_read = {
5606         "READ access",
5607         "NO read access"
5608 };
5609
5610 static const true_false_string tfs_nt_share_access_delete = {
5611         "Object can be shared for DELETE",
5612         "Object can NOT be shared for delete"
5613 };
5614 static const true_false_string tfs_nt_share_access_write = {
5615         "Object can be shared for WRITE",
5616         "Object can NOT be shared for write"
5617 };
5618 static const true_false_string tfs_nt_share_access_read = {
5619         "Object can be shared for READ",
5620         "Object can NOT be shared for delete"
5621 };
5622
5623 static const value_string oplock_level_vals[] = {
5624         {0,     "No oplock granted"},
5625         {1,     "Exclusive oplock granted"},
5626         {2,     "Batch oplock granted"},
5627         {3,     "Level II oplock granted"},
5628         {0, NULL}
5629 };
5630
5631 static const value_string device_type_vals[] = {
5632         {0x00000001,    "Beep"},
5633         {0x00000002,    "CDROM"},
5634         {0x00000003,    "CDROM Filesystem"},
5635         {0x00000004,    "Controller"},
5636         {0x00000005,    "Datalink"},
5637         {0x00000006,    "Dfs"},
5638         {0x00000007,    "Disk"},
5639         {0x00000008,    "Disk Filesystem"},
5640         {0x00000009,    "Filesystem"},
5641         {0x0000000a,    "Inport Port"},
5642         {0x0000000b,    "Keyboard"},
5643         {0x0000000c,    "Mailslot"},
5644         {0x0000000d,    "MIDI-In"},
5645         {0x0000000e,    "MIDI-Out"},
5646         {0x0000000f,    "Mouse"},
5647         {0x00000010,    "Multi UNC Provider"},
5648         {0x00000011,    "Named Pipe"},
5649         {0x00000012,    "Network"},
5650         {0x00000013,    "Network Browser"},
5651         {0x00000014,    "Network Filesystem"},
5652         {0x00000015,    "NULL"},
5653         {0x00000016,    "Parallel Port"},
5654         {0x00000017,    "Physical card"},
5655         {0x00000018,    "Printer"},
5656         {0x00000019,    "Scanner"},
5657         {0x0000001a,    "Serial Mouse port"},
5658         {0x0000001b,    "Serial port"},
5659         {0x0000001c,    "Screen"},
5660         {0x0000001d,    "Sound"},
5661         {0x0000001e,    "Streams"},
5662         {0x0000001f,    "Tape"},
5663         {0x00000020,    "Tape Filesystem"},
5664         {0x00000021,    "Transport"},
5665         {0x00000022,    "Unknown"},
5666         {0x00000023,    "Video"},
5667         {0x00000024,    "Virtual Disk"},
5668         {0x00000025,    "WAVE-In"},
5669         {0x00000026,    "WAVE-Out"},
5670         {0x00000027,    "8042 Port"},
5671         {0x00000028,    "Network Redirector"},
5672         {0x00000029,    "Battery"},
5673         {0x0000002a,    "Bus Extender"},
5674         {0x0000002b,    "Modem"},
5675         {0x0000002c,    "VDM"},
5676         {0,     NULL}
5677 };
5678
5679 static const value_string is_directory_vals[] = {
5680         {0,     "This is NOT a directory"},
5681         {1,     "This is a DIRECTORY"},
5682         {0, NULL}
5683 };
5684
5685 typedef struct _nt_trans_data {
5686         guint32 sd_len;
5687         guint32 ea_len;
5688 } nt_trans_data;
5689
5690
5691
5692 static int
5693 dissect_nt_security_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5694 {
5695         guint8 mask;
5696         proto_item *item = NULL;
5697         proto_tree *tree = NULL;
5698
5699         mask = tvb_get_guint8(tvb, offset);
5700
5701         if(parent_tree){
5702                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
5703                         "Security Flags: 0x%02x", mask);
5704                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
5705         }
5706
5707         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
5708                 tvb, offset, 1, mask);
5709         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
5710                 tvb, offset, 1, mask);
5711
5712         offset += 1;
5713
5714         return offset;
5715 }
5716
5717 static int
5718 dissect_nt_share_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5719 {
5720         guint32 mask;
5721         proto_item *item = NULL;
5722         proto_tree *tree = NULL;
5723
5724         mask = tvb_get_letohl(tvb, offset);
5725
5726         if(parent_tree){
5727                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
5728                         "Share Access: 0x%08x", mask);
5729                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
5730         }
5731
5732         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
5733                 tvb, offset, 4, mask);
5734         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
5735                 tvb, offset, 4, mask);
5736         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
5737                 tvb, offset, 4, mask);
5738
5739         offset += 4;
5740
5741         return offset;
5742 }
5743
5744
5745 static int
5746 dissect_nt_access_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5747 {
5748         guint32 mask;
5749         proto_item *item = NULL;
5750         proto_tree *tree = NULL;
5751
5752         mask = tvb_get_letohl(tvb, offset);
5753
5754         if(parent_tree){
5755                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
5756                         "Access Mask: 0x%08x", mask);
5757                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
5758         }
5759
5760         /*
5761          * Some of these bits come from 
5762          *
5763          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
5764          *
5765          * and others come from the section on ZwOpenFile in "Windows(R)
5766          * NT(R)/2000 Native API Reference".
5767          */
5768         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
5769                 tvb, offset, 4, mask);
5770         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
5771                 tvb, offset, 4, mask);
5772         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
5773                 tvb, offset, 4, mask);
5774         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
5775                 tvb, offset, 4, mask);
5776         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
5777                 tvb, offset, 4, mask);
5778         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
5779                 tvb, offset, 4, mask);
5780         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
5781                 tvb, offset, 4, mask);
5782         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
5783                 tvb, offset, 4, mask);
5784         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
5785                 tvb, offset, 4, mask);
5786         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
5787                 tvb, offset, 4, mask);
5788         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
5789                 tvb, offset, 4, mask);
5790         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
5791                 tvb, offset, 4, mask);
5792         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
5793                 tvb, offset, 4, mask);
5794         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
5795                 tvb, offset, 4, mask);
5796         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
5797                 tvb, offset, 4, mask);
5798         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
5799                 tvb, offset, 4, mask);
5800         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
5801                 tvb, offset, 4, mask);
5802         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
5803                 tvb, offset, 4, mask);
5804         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
5805                 tvb, offset, 4, mask);
5806         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
5807                 tvb, offset, 4, mask);
5808
5809         offset += 4;
5810
5811         return offset;
5812 }
5813
5814 static int
5815 dissect_nt_create_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5816 {
5817         guint32 mask;
5818         proto_item *item = NULL;
5819         proto_tree *tree = NULL;
5820
5821         mask = tvb_get_letohl(tvb, offset);
5822
5823         if(parent_tree){
5824                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
5825                         "Create Flags: 0x%08x", mask);
5826                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
5827         }
5828
5829         /*
5830          * XXX - it's 0x00000016 in at least one capture, but
5831          * Network Monitor doesn't say what the 0x00000010 bit is.
5832          * Does the Win32 API documentation, or NT Native API book,
5833          * suggest anything?
5834          */
5835         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
5836                 tvb, offset, 4, mask);
5837         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
5838                 tvb, offset, 4, mask);
5839         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
5840                 tvb, offset, 4, mask);
5841
5842         offset += 4;
5843
5844         return offset;
5845 }
5846
5847 /*
5848  * XXX - there are some more flags in the description of "ZwOpenFile()"
5849  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
5850  * the wire as well?  (The spec at
5851  *
5852  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
5853  *
5854  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
5855  * via the SMB protocol.  The NT redirector should convert this option
5856  * to FILE_WRITE_THROUGH."
5857  *
5858  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
5859  * values one would infer from their position in the list of flags for
5860  * "ZwOpenFile()".  Most of the others probably have those values
5861  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
5862  * which might go over the wire (for the benefit of backup/restore software).
5863  */
5864 static const true_false_string tfs_nt_create_options_directory = {
5865         "File being created/opened must be a directory",
5866         "File being created/opened must not be a directory"
5867 };
5868 static const true_false_string tfs_nt_create_options_write_through = {
5869         "Writes should flush buffered data before completing",
5870         "Writes need not flush buffered data before completing"
5871 };
5872 static const true_false_string tfs_nt_create_options_sequential_only = {
5873         "The file will only be accessed sequentially",
5874         "The file might not only be accessed sequentially"
5875 };
5876 static const true_false_string tfs_nt_create_options_sync_io_alert = {
5877         "All operations SYNCHRONOUS, waits subject to termination from alert",
5878         "Operations NOT necessarily synchronous"
5879 };
5880 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
5881         "All operations SYNCHRONOUS, waits not subject to alert",
5882         "Operations NOT necessarily synchronous"
5883 };
5884 static const true_false_string tfs_nt_create_options_non_directory = {
5885         "File being created/opened must not be a directory",
5886         "File being created/opened must be a directory"
5887 };
5888 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
5889         "The client does not understand extended attributes",
5890         "The client understands extended attributes"
5891 };
5892 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
5893         "The client understands only 8.3 file names",
5894         "The client understands long file names"
5895 };
5896 static const true_false_string tfs_nt_create_options_random_access = {
5897         "The file will be accessed randomly",
5898         "The file will not be accessed randomly"
5899 };
5900 static const true_false_string tfs_nt_create_options_delete_on_close = {
5901         "The file should be deleted when it is closed",
5902         "The file should not be deleted when it is closed"
5903 };
5904
5905 static int
5906 dissect_nt_create_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5907 {
5908         guint32 mask;
5909         proto_item *item = NULL;
5910         proto_tree *tree = NULL;
5911
5912         mask = tvb_get_letohl(tvb, offset);
5913
5914         if(parent_tree){
5915                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
5916                         "Create Options: 0x%08x", mask);
5917                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
5918         }
5919
5920         /*
5921          * From
5922          *
5923          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
5924          */
5925         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
5926                 tvb, offset, 4, mask);
5927         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
5928                 tvb, offset, 4, mask);
5929         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
5930                 tvb, offset, 4, mask);
5931         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
5932                 tvb, offset, 4, mask);
5933         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
5934                 tvb, offset, 4, mask);
5935         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
5936                 tvb, offset, 4, mask);
5937         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
5938                 tvb, offset, 4, mask);
5939         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
5940                 tvb, offset, 4, mask);
5941         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
5942                 tvb, offset, 4, mask);
5943         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
5944                 tvb, offset, 4, mask);
5945
5946         offset += 4;
5947
5948         return offset;
5949 }
5950  
5951 static int
5952 dissect_nt_notify_completion_filter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5953 {
5954         guint32 mask;
5955         proto_item *item = NULL;
5956         proto_tree *tree = NULL;
5957
5958         mask = tvb_get_letohl(tvb, offset);
5959
5960         if(parent_tree){
5961                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
5962                         "Completion Filter: 0x%08x", mask);
5963                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
5964         }
5965  
5966         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
5967                 tvb, offset, 4, mask);
5968         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
5969                 tvb, offset, 4, mask);
5970         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
5971                 tvb, offset, 4, mask);
5972         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
5973                 tvb, offset, 4, mask);
5974         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
5975                 tvb, offset, 4, mask);
5976         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
5977                 tvb, offset, 4, mask);
5978         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
5979                 tvb, offset, 4, mask);
5980         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
5981                 tvb, offset, 4, mask);
5982         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
5983                 tvb, offset, 4, mask);
5984         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
5985                 tvb, offset, 4, mask);
5986         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
5987                 tvb, offset, 4, mask);
5988         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
5989                 tvb, offset, 4, mask);
5990
5991         offset += 4;
5992         return offset;
5993 }
5994  
5995 static int
5996 dissect_nt_ioctl_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
5997 {
5998         guint8 mask;
5999         proto_item *item = NULL;
6000         proto_tree *tree = NULL;
6001
6002         mask = tvb_get_guint8(tvb, offset);
6003
6004         if(parent_tree){
6005                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6006                         "Completion Filter: 0x%02x", mask);
6007                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
6008         }
6009
6010         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
6011                 tvb, offset, 1, mask);
6012
6013         offset += 1;
6014         return offset;
6015 }
6016
6017 /*
6018  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
6019  * Native API Reference".
6020  */
6021 static const true_false_string tfs_nt_qsd_owner = {
6022         "Requesting OWNER security information",
6023         "NOT requesting owner security information",
6024 };
6025
6026 static const true_false_string tfs_nt_qsd_group = {
6027         "Requesting GROUP security information",
6028         "NOT requesting group security information",
6029 };
6030
6031 static const true_false_string tfs_nt_qsd_dacl = {
6032         "Requesting DACL security information",
6033         "NOT requesting DACL security information",
6034 };
6035
6036 static const true_false_string tfs_nt_qsd_sacl = {
6037         "Requesting SACL security information",
6038         "NOT requesting SACL security information",
6039 };
6040
6041 #define NT_QSD_OWNER    0x00000001
6042 #define NT_QSD_GROUP    0x00000002
6043 #define NT_QSD_DACL     0x00000004
6044 #define NT_QSD_SACL     0x00000008
6045
6046 static int
6047 dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
6048 {
6049         guint32 mask;
6050         proto_item *item = NULL;
6051         proto_tree *tree = NULL;
6052
6053         mask = tvb_get_letohl(tvb, offset);
6054
6055         if(parent_tree){
6056                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6057                         "Security Information: 0x%08x", mask);
6058                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
6059         }
6060
6061         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
6062                 tvb, offset, 4, mask);
6063         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
6064                 tvb, offset, 4, mask);
6065         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
6066                 tvb, offset, 4, mask);
6067         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
6068                 tvb, offset, 4, mask);
6069
6070         offset += 4;
6071
6072         return offset;
6073 }
6074
6075
6076 static int
6077 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
6078 {
6079         proto_item *item = NULL;
6080         proto_tree *tree = NULL;
6081         smb_info_t *si;
6082         smb_nt_transact_info_t *nti;
6083
6084         si = (smb_info_t *)pinfo->private_data;
6085         nti = si->sip->extra_info;
6086
6087         if(parent_tree){
6088                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6089                                 "%s Data",
6090                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
6091                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6092         }
6093
6094         switch(nti->subcmd){
6095         case NT_TRANS_CREATE:
6096                 /* security descriptor */
6097                 if(ntd->sd_len){
6098                         proto_tree_add_item(tree, hf_smb_security_descriptor, tvb, offset, ntd->sd_len, TRUE);
6099                         offset += ntd->sd_len;
6100                 }
6101
6102                 /* extended attributes */
6103                 if(ntd->ea_len){
6104                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
6105                         offset += ntd->ea_len;
6106                 }
6107
6108                 break;
6109         case NT_TRANS_IOCTL:
6110                 /* ioctl data */
6111                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
6112                 offset += len;
6113
6114                 break;
6115         case NT_TRANS_SSD:
6116                 proto_tree_add_item(tree, hf_smb_security_descriptor, tvb, offset, len, TRUE);
6117                 offset += len;
6118                 break;
6119         case NT_TRANS_NOTIFY:
6120                 break;
6121         case NT_TRANS_RENAME:
6122                 /* XXX not documented */
6123                 break;
6124         case NT_TRANS_QSD:
6125                 break;
6126         }
6127
6128         return offset;
6129 }
6130
6131 static int
6132 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)
6133 {
6134         proto_item *item = NULL;
6135         proto_tree *tree = NULL;
6136         smb_info_t *si;
6137         smb_nt_transact_info_t *nti;
6138         guint32 fn_len;
6139         const char *fn;
6140
6141         si = (smb_info_t *)pinfo->private_data;
6142         nti = si->sip->extra_info;
6143
6144         if(parent_tree){
6145                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6146                                 "%s Parameters",
6147                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
6148                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6149         }
6150
6151         switch(nti->subcmd){
6152         case NT_TRANS_CREATE:
6153                 /* Create flags */
6154                 offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
6155                 bc -= 4;
6156
6157                 /* root directory fid */
6158                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
6159                 COUNT_BYTES(4);
6160
6161                 /* nt access mask */
6162                 offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
6163                 bc -= 4;
6164         
6165                 /* allocation size */
6166                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
6167                 COUNT_BYTES(8);
6168         
6169                 /* Extended File Attributes */
6170                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
6171                 bc -= 4;
6172
6173                 /* share access */
6174                 offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
6175                 bc -= 4;
6176         
6177                 /* create disposition */
6178                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
6179                 COUNT_BYTES(4);
6180
6181                 /* create options */
6182                 offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
6183                 bc -= 4;
6184
6185                 /* sd length */
6186                 ntd->sd_len = tvb_get_letohl(tvb, offset);
6187                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
6188                 COUNT_BYTES(4);
6189
6190                 /* ea length */
6191                 ntd->ea_len = tvb_get_letohl(tvb, offset);
6192                 proto_tree_add_uint(tree, hf_smb_ea_length, tvb, offset, 4, ntd->ea_len);
6193                 COUNT_BYTES(4);
6194
6195                 /* file name len */
6196                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
6197                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
6198                 COUNT_BYTES(4);
6199
6200                 /* impersonation level */
6201                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
6202                 COUNT_BYTES(4);
6203         
6204                 /* security flags */
6205                 offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
6206                 bc -= 1;
6207
6208                 /* file name */
6209                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
6210                 if (fn != NULL) {
6211                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6212                                 fn);
6213                         COUNT_BYTES(fn_len);
6214                 }
6215
6216                 break;
6217         case NT_TRANS_IOCTL:
6218                 break;
6219         case NT_TRANS_SSD:
6220                 /* fid */
6221                 proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
6222                 offset += 2;
6223
6224                 /* 2 reserved bytes */
6225                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6226                 offset += 2;
6227
6228                 /* security information */
6229                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
6230                 break;
6231         case NT_TRANS_NOTIFY:
6232                 break;
6233         case NT_TRANS_RENAME:
6234                 /* XXX not documented */
6235                 break;
6236         case NT_TRANS_QSD:
6237                 /* fid */
6238                 proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
6239                 offset += 2;
6240
6241                 /* 2 reserved bytes */
6242                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6243                 offset += 2;
6244
6245                 /* security information */
6246                 offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
6247                 break;
6248         }
6249
6250         return offset;
6251 }
6252
6253 static int
6254 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
6255 {
6256         proto_item *item = NULL;
6257         proto_tree *tree = NULL;
6258         smb_info_t *si;
6259         smb_nt_transact_info_t *nti;
6260         int old_offset = offset;
6261
6262         si = (smb_info_t *)pinfo->private_data;
6263         nti = si->sip->extra_info;
6264
6265         if(parent_tree){
6266                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
6267                                 "%s Setup",
6268                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
6269                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6270         }
6271  
6272         switch(nti->subcmd){
6273         case NT_TRANS_CREATE:
6274                 break;
6275         case NT_TRANS_IOCTL:
6276                 /* function code */
6277                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
6278                 offset += 4;
6279
6280                 /* fid */
6281                 proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
6282                 offset += 2;
6283
6284                 /* isfsctl */
6285                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
6286                 offset += 1;
6287
6288                 /* isflags */
6289                 offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
6290
6291                 break;
6292         case NT_TRANS_SSD:
6293                 break;
6294         case NT_TRANS_NOTIFY:
6295                 /* completion filter */
6296                 offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
6297
6298                 /* fid */
6299                 proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
6300                 offset += 2;
6301
6302                 /* watch tree */
6303                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
6304                 offset += 1;
6305
6306                 /* reserved byte */
6307                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6308                 offset += 1;
6309
6310                 break;
6311         case NT_TRANS_RENAME:
6312                 /* XXX not documented */
6313                 break;
6314         case NT_TRANS_QSD:
6315                 break;
6316         }
6317  
6318         return old_offset+len;
6319 }
6320
6321
6322 static int
6323 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6324 {
6325         guint8 wc, sc;
6326         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
6327         smb_info_t *si;
6328         smb_saved_info_t *sip;
6329         nt_trans_data ntd;
6330         guint16 bc;
6331         int padcnt;
6332         smb_nt_transact_info_t *nti;
6333
6334         si = (smb_info_t *)pinfo->private_data;
6335         sip = si->sip;
6336
6337         WORD_COUNT;
6338
6339         if(wc>=19){
6340                 /* primary request */
6341                 /* max setup count */
6342                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
6343                 offset += 1;
6344
6345                 /* 2 reserved bytes */
6346                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
6347                 offset += 2;
6348         } else {
6349                 /* secondary request */
6350                 /* 3 reserved bytes */
6351                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
6352                 offset += 3;
6353         }
6354
6355
6356         /* total param count */
6357         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
6358         offset += 4;
6359         
6360         /* total data count */
6361         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
6362         offset += 4;
6363
6364         if(wc>=19){
6365                 /* primary request */
6366                 /* max param count */
6367                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
6368                 offset += 4;
6369
6370                 /* max data count */
6371                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
6372                 offset += 4;
6373         }
6374
6375         /* param count */
6376         pc = tvb_get_letohl(tvb, offset);
6377         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
6378         offset += 4;
6379         
6380         /* param offset */
6381         po = tvb_get_letohl(tvb, offset);
6382         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
6383         offset += 4;
6384
6385         /* param displacement */
6386         if(wc>=19){
6387                 /* primary request*/
6388                 pd = 0;
6389         } else {
6390                 /* secondary request */
6391                 pd = tvb_get_letohl(tvb, offset);
6392                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
6393                 offset += 4;
6394         }
6395
6396         /* data count */
6397         dc = tvb_get_letohl(tvb, offset);
6398         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
6399         offset += 4;
6400
6401         /* data offset */
6402         od = tvb_get_letohl(tvb, offset);
6403         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
6404         offset += 4;
6405
6406         /* data displacement */
6407         if(wc>=19){
6408                 /* primary request */
6409                 dd = 0;
6410         } else {
6411                 /* secondary request */
6412                 dd = tvb_get_letohl(tvb, offset);
6413                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
6414                 offset += 4;
6415         }
6416
6417         /* setup count */
6418         if(wc>=19){
6419                 /* primary request */
6420                 sc = tvb_get_guint8(tvb, offset);
6421                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
6422                 offset += 1;
6423         } else {
6424                 /* secondary request */
6425                 sc = 0;
6426         }
6427
6428         /* function */
6429         if(wc>=19){
6430                 /* primary request */
6431                 if (!si->unidir) {
6432                         if(!pinfo->fd->flags.visited){
6433                                 /* 
6434                                  * Allocate a new smb_nt_transact_info_t
6435                                  * structure.
6436                                  */
6437                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
6438                                 nti->subcmd = -1;
6439                                 sip->extra_info = nti;
6440                         } else
6441                                 nti = sip->extra_info;
6442                 } else {
6443                         /*
6444                          * This is a unidirectional message, for
6445                          * which there will be no reply; don't
6446                          * bother allocating an "smb_nt_transact_info_t"
6447                          * structure for it.
6448                          */
6449                         nti = NULL;
6450                 }
6451                 nti->subcmd = tvb_get_letohs(tvb, offset);
6452                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, nti->subcmd);
6453                 if(check_col(pinfo->fd, COL_INFO)){
6454                         col_append_fstr(pinfo->fd, COL_INFO, ", %s",
6455                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown>"));
6456                 }
6457         } else {
6458                 /* secondary request */
6459                 if(check_col(pinfo->fd, COL_INFO)){
6460                         col_append_fstr(pinfo->fd, COL_INFO, " (secondary request)");
6461                 }
6462         }
6463         offset += 2;
6464
6465         /* this is a padding byte */
6466         if(offset%1){
6467                 /* pad byte */
6468                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
6469                 offset += 1;
6470         }
6471
6472         /* if there were any setup bytes, decode them */
6473         if(sc){
6474                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
6475                 offset += sc*2;
6476         }
6477
6478         BYTE_COUNT;
6479         
6480         /* parameters */
6481         if(po>(guint32)offset){
6482                 /* We have some initial padding bytes.
6483                 */
6484                 padcnt = po-offset;
6485                 if (padcnt > bc)
6486                         padcnt = bc;
6487                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
6488                 COUNT_BYTES(padcnt);
6489         }
6490         if(pc){
6491                 CHECK_BYTE_COUNT(pc);
6492                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
6493                 COUNT_BYTES(pc);
6494         }
6495
6496         /* data */
6497         if(od>(guint32)offset){
6498                 /* We have some initial padding bytes.
6499                 */
6500                 padcnt = od-offset;
6501                 if (padcnt > bc)
6502                         padcnt = bc;
6503                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
6504                 COUNT_BYTES(padcnt);
6505         }
6506         if(dc){
6507                 CHECK_BYTE_COUNT(dc);
6508                 dissect_nt_trans_data_request(tvb, pinfo, offset, tree, dc, &ntd);
6509                 COUNT_BYTES(dc);
6510         }
6511
6512         END_OF_SMB
6513
6514         return offset;
6515 }
6516
6517
6518
6519 static int
6520 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
6521 {
6522         proto_item *item = NULL;
6523         proto_tree *tree = NULL;
6524         smb_info_t *si;
6525         smb_nt_transact_info_t *nti;
6526
6527         si = (smb_info_t *)pinfo->private_data;
6528         if (si->sip != NULL)
6529                 nti = si->sip->extra_info;
6530         else
6531                 nti = NULL;
6532
6533         if(parent_tree){
6534                 if(nti != NULL){
6535                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
6536                                 "%s Data",
6537                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
6538                 } else {
6539                         /*
6540                          * We never saw the request to which this is a
6541                          * response.
6542                          */
6543                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
6544                                 "Unknown NT Transaction Data (matching request not seen)");
6545                 }
6546                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6547         }
6548
6549         if (nti == NULL) {
6550                 offset += len;
6551                 return offset;
6552         }
6553         switch(nti->subcmd){
6554         case NT_TRANS_CREATE:
6555                 break;
6556         case NT_TRANS_IOCTL:
6557                 /* ioctl data */
6558                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
6559                 offset += len;
6560
6561                 break;
6562         case NT_TRANS_SSD:
6563                 break;
6564         case NT_TRANS_NOTIFY:
6565                 break;
6566         case NT_TRANS_RENAME:
6567                 /* XXX not documented */
6568                 break;
6569         case NT_TRANS_QSD:
6570                 /*
6571                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
6572                  * which may be documented in the Win32 documentation
6573                  * somewhere.
6574                  */
6575                 proto_tree_add_item(tree, hf_smb_security_descriptor, tvb, offset, len, TRUE);
6576                 offset += len;
6577                 break;
6578         }
6579
6580         return offset;
6581 }
6582  
6583 static int
6584 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)
6585 {
6586         proto_item *item = NULL;
6587         proto_tree *tree = NULL;
6588         guint32 fn_len;
6589         const char *fn;
6590         smb_info_t *si;
6591         smb_nt_transact_info_t *nti;
6592         guint16 fid;
6593
6594         si = (smb_info_t *)pinfo->private_data;
6595         if (si->sip != NULL)
6596                 nti = si->sip->extra_info;
6597         else
6598                 nti = NULL;
6599
6600         if(parent_tree){
6601                 if(nti != NULL){
6602                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
6603                                 "%s Parameters",
6604                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
6605                 } else {
6606                         /*
6607                          * We never saw the request to which this is a
6608                          * response.
6609                          */
6610                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
6611                                 "Unknown NT Transaction Parameters (matching request not seen)");
6612                 }
6613                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6614         }
6615
6616         if (nti == NULL) {
6617                 offset += len;
6618                 return offset;
6619         }
6620         switch(nti->subcmd){
6621         case NT_TRANS_CREATE:
6622                 /* oplock level */
6623                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
6624                 offset += 1;
6625
6626                 /* reserved byte */
6627                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6628                 offset += 1;
6629                 
6630                 /* fid */
6631                 fid = tvb_get_letohs(tvb, offset);
6632                 add_fid(tvb, pinfo, tree, offset, fid);
6633                 offset += 2;
6634
6635                 /* create action */
6636                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
6637                 offset += 4;
6638
6639                 /* ea error offset */
6640                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
6641                 offset += 4;
6642
6643                 /* create time */
6644                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
6645                         "Create Time", hf_smb_create_time);
6646         
6647                 /* access time */
6648                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
6649                         "Access Time", hf_smb_access_time);
6650         
6651                 /* last write time */
6652                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
6653                         "Write Time", hf_smb_last_write_time);
6654         
6655                 /* last change time */
6656                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
6657                         "Change Time", hf_smb_change_time);
6658         
6659                 /* Extended File Attributes */
6660                 offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
6661
6662                 /* allocation size */
6663                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
6664                 offset += 8;
6665
6666                 /* end of file */
6667                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
6668                 offset += 8;
6669
6670                 /* File Type */
6671                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
6672                 offset += 2;
6673
6674                 /* device state */
6675                 offset = dissect_ipc_state(tvb, pinfo, tree, offset);
6676
6677                 /* is directory */
6678                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
6679                 offset += 1;
6680                 break;
6681         case NT_TRANS_IOCTL:
6682                 break;
6683         case NT_TRANS_SSD:
6684                 break;
6685         case NT_TRANS_NOTIFY:
6686                 while(len){
6687                         /* next entry offset */
6688                         proto_tree_add_item(tree, hf_smb_next_entry_offset, tvb, offset, 4, TRUE);
6689                         COUNT_BYTES(4);
6690                         len -= 4;
6691                         /* broken implementations */
6692                         if(len<0)break;
6693         
6694                         /* action */
6695                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
6696                         COUNT_BYTES(4);
6697                         len -= 4;
6698                         /* broken implementations */
6699                         if(len<0)break;
6700
6701                         /* file name len */
6702                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
6703                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
6704                         COUNT_BYTES(4);
6705                         len -= 4;
6706                         /* broken implementations */
6707                         if(len<0)break;
6708
6709                         /* file name */
6710                         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, &bc);
6711                         if (fn == NULL)
6712                                 break;
6713                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
6714                                 fn);
6715                         COUNT_BYTES(fn_len);
6716                         len -= fn_len;
6717                         /* broken implementations */
6718                         if(len<0)break;
6719
6720                 }
6721                 break;
6722         case NT_TRANS_RENAME:
6723                 /* XXX not documented */
6724                 break;
6725         case NT_TRANS_QSD:
6726                 /*
6727                  * This appears to be the size of the security
6728                  * descriptor; the calling sequence of
6729                  * "ZwQuerySecurityObject()" suggests that it would
6730                  * be.  The actual security descriptor wouldn't
6731                  * follow if the max data count in the request
6732                  * was smaller; this lets the client know how
6733                  * big a buffer it needs to provide.
6734                  */
6735                 proto_tree_add_item(tree, hf_smb_security_descriptor_len, tvb, offset, 4, TRUE);
6736                 offset += 4;
6737                 break;
6738         }
6739
6740         return offset;
6741 }
6742  
6743 static int
6744 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
6745 {
6746         proto_item *item = NULL;
6747         proto_tree *tree = NULL;
6748         smb_info_t *si;
6749         smb_nt_transact_info_t *nti;
6750
6751         si = (smb_info_t *)pinfo->private_data;
6752         if (si->sip != NULL)
6753                 nti = si->sip->extra_info;
6754         else
6755                 nti = NULL;
6756
6757         if(parent_tree){
6758                 if(nti != NULL){
6759                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
6760                                 "%s Setup",
6761                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
6762                 } else {
6763                         /*
6764                          * We never saw the request to which this is a
6765                          * response.
6766                          */
6767                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
6768                                 "Unknown NT Transaction Setup (matching request not seen)");
6769                 }
6770                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
6771         }
6772
6773         if (nti == NULL) {
6774                 offset += len;
6775                 return offset;
6776         }
6777         switch(nti->subcmd){
6778         case NT_TRANS_CREATE:
6779                 break;
6780         case NT_TRANS_IOCTL:
6781                 break;
6782         case NT_TRANS_SSD:
6783                 break;
6784         case NT_TRANS_NOTIFY:
6785                 break;
6786         case NT_TRANS_RENAME:
6787                 /* XXX not documented */
6788                 break;
6789         case NT_TRANS_QSD:
6790                 break;
6791         }
6792
6793         return offset;
6794 }
6795
6796 static int
6797 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6798 {
6799         guint8 wc, sc;
6800         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
6801         smb_info_t *si;
6802         smb_nt_transact_info_t *nti;
6803         static nt_trans_data ntd;
6804         guint16 bc;
6805         int padcnt;
6806
6807         si = (smb_info_t *)pinfo->private_data;
6808         if (si->sip != NULL)
6809                 nti = si->sip->extra_info;
6810         else
6811                 nti = NULL;
6812
6813         /* primary request */
6814         if(nti != NULL){
6815                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
6816                 if(check_col(pinfo->fd, COL_INFO)){
6817                         col_append_fstr(pinfo->fd, COL_INFO, ", %s",
6818                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
6819                 }
6820         } else {
6821                 proto_tree_add_text(tree, tvb, offset, 0,
6822                         "Function: <unknown function - could not find matching request>");
6823                 if(check_col(pinfo->fd, COL_INFO)){
6824                         col_append_fstr(pinfo->fd, COL_INFO, ", <unknown>");
6825                 }
6826         }
6827
6828         WORD_COUNT;
6829
6830         /* 3 reserved bytes */
6831         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
6832         offset += 3;
6833
6834         /* total param count */
6835         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
6836         offset += 4;
6837         
6838         /* total data count */
6839         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
6840         offset += 4;
6841
6842         /* param count */
6843         pc = tvb_get_letohl(tvb, offset);
6844         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
6845         offset += 4;
6846         
6847         /* param offset */
6848         po = tvb_get_letohl(tvb, offset);
6849         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
6850         offset += 4;
6851
6852         /* param displacement */
6853         pd = tvb_get_letohl(tvb, offset);
6854         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
6855         offset += 4;
6856
6857         /* data count */
6858         dc = tvb_get_letohl(tvb, offset);
6859         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
6860         offset += 4;
6861
6862         /* data offset */
6863         od = tvb_get_letohl(tvb, offset);
6864         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
6865         offset += 4;
6866
6867         /* data displacement */
6868         dd = tvb_get_letohl(tvb, offset);
6869         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
6870         offset += 4;
6871
6872         /* setup count */
6873         sc = tvb_get_guint8(tvb, offset);
6874         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
6875         offset += 1;
6876
6877         /* setup data */        
6878         if(sc){
6879                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
6880                 offset += sc*2;
6881         }
6882
6883         BYTE_COUNT;
6884         
6885         /* parameters */
6886         if(po>(guint32)offset){
6887                 /* We have some initial padding bytes.
6888                 */
6889                 padcnt = po-offset;
6890                 if (padcnt > bc)
6891                         padcnt = bc;
6892                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
6893                 COUNT_BYTES(padcnt);
6894         }
6895         if(pc){
6896                 CHECK_BYTE_COUNT(pc);
6897                 dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
6898                 COUNT_BYTES(pc);
6899         }
6900
6901         /* data */
6902         if(od>(guint32)offset){
6903                 /* We have some initial padding bytes.
6904                 */
6905                 padcnt = od-offset;
6906                 if (padcnt > bc)
6907                         padcnt = bc;
6908                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
6909                 COUNT_BYTES(padcnt);
6910         }
6911         if(dc){
6912                 CHECK_BYTE_COUNT(dc);
6913                 dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
6914                 COUNT_BYTES(dc);
6915         }
6916
6917         END_OF_SMB
6918
6919         return offset;
6920 }
6921
6922 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6923    NT Transaction command  ends here
6924    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6925
6926 static const value_string print_mode_vals[] = {
6927         {0,     "Text Mode"},
6928         {1,     "Graphics Mode"},
6929         {0, NULL}
6930 };
6931  
6932 static int
6933 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6934 {
6935         int fn_len;
6936         const char *fn;
6937         guint8 wc;
6938         guint16 bc;
6939
6940         WORD_COUNT;
6941
6942         /* setup len */
6943         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
6944         offset += 2;
6945
6946         /* print mode */
6947         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
6948         offset += 2;
6949
6950         BYTE_COUNT;
6951
6952         /* buffer format */
6953         CHECK_BYTE_COUNT(1);
6954         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
6955         COUNT_BYTES(1);
6956
6957         /* print identifier */
6958         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, FALSE, &bc);
6959         if (fn == NULL)
6960                 goto endofcommand;
6961         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
6962                 fn);
6963         COUNT_BYTES(fn_len);
6964
6965         END_OF_SMB
6966
6967         return offset;
6968 }
6969
6970
6971 static int
6972 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6973 {
6974         int cnt;
6975         guint8 wc;
6976         guint16 bc;
6977
6978         WORD_COUNT;
6979
6980         /* fid */
6981         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
6982         offset += 2;
6983
6984         BYTE_COUNT;
6985
6986         /* buffer format */
6987         CHECK_BYTE_COUNT(1);
6988         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
6989         COUNT_BYTES(1);
6990
6991         /* data len */
6992         CHECK_BYTE_COUNT(2);
6993         cnt = tvb_get_letohs(tvb, offset);
6994         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
6995         COUNT_BYTES(2);
6996
6997         /* file data */
6998         offset = dissect_file_data(tvb, pinfo, tree, offset, cnt, cnt);
6999
7000         END_OF_SMB
7001
7002         return offset;
7003 }
7004
7005
7006 static const value_string print_status_vals[] = {
7007         {1,     "Held or Stopped"},
7008         {2,     "Printing"},
7009         {3,     "Awaiting print"},
7010         {4,     "In intercept"},
7011         {5,     "File had error"},
7012         {6,     "Printer error"},
7013         {0, NULL}
7014 };
7015  
7016 static int
7017 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7018 {
7019         guint8 wc;
7020         guint16 bc;
7021
7022         WORD_COUNT;
7023
7024         /* max count */
7025         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
7026         offset += 2;
7027
7028         /* start index */
7029         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
7030         offset += 2;
7031
7032         BYTE_COUNT;
7033
7034         END_OF_SMB
7035
7036         return offset;
7037 }
7038
7039 static int
7040 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
7041     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
7042 {
7043         proto_item *item = NULL;
7044         proto_tree *tree = NULL;
7045         int fn_len;
7046         const char *fn;
7047
7048         if(parent_tree){
7049                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
7050                         "Queue entry");
7051                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
7052         }
7053
7054         /* queued time */
7055         CHECK_BYTE_COUNT_SUBR(4);
7056         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
7057                 hf_smb_print_queue_date,
7058                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
7059         *bcp -= 4;
7060
7061         /* status */
7062         CHECK_BYTE_COUNT_SUBR(1);
7063         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
7064         COUNT_BYTES_SUBR(1);
7065
7066         /* spool file number */
7067         CHECK_BYTE_COUNT_SUBR(2);
7068         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
7069         COUNT_BYTES_SUBR(2);
7070
7071         /* spool file size */
7072         CHECK_BYTE_COUNT_SUBR(4);
7073         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
7074         COUNT_BYTES_SUBR(4);
7075
7076         /* reserved byte */
7077         CHECK_BYTE_COUNT_SUBR(1);
7078         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7079         COUNT_BYTES_SUBR(1);
7080
7081         /* file name */
7082         fn_len = 16;
7083         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, TRUE, TRUE, bcp);
7084         CHECK_STRING_SUBR(fn);
7085         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
7086                 fn);
7087         COUNT_BYTES_SUBR(fn_len);
7088
7089         *trunc = FALSE;
7090         return offset;
7091 }
7092
7093 static int
7094 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7095 {
7096         guint16 cnt=0, len;
7097         guint8 wc;
7098         guint16 bc;
7099         gboolean trunc;
7100
7101         WORD_COUNT;
7102
7103         /* count */
7104         cnt = tvb_get_letohs(tvb, offset);
7105         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
7106         offset += 2;
7107
7108         /* restart index */
7109         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
7110         offset += 2;
7111
7112         BYTE_COUNT;
7113
7114         /* buffer format */
7115         CHECK_BYTE_COUNT(1);
7116         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
7117         COUNT_BYTES(1);
7118
7119         /* data len */
7120         CHECK_BYTE_COUNT(2);
7121         len = tvb_get_letohs(tvb, offset);
7122         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
7123         COUNT_BYTES(2);
7124
7125         /* queue elements */
7126         while(cnt--){
7127                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
7128                     &bc, &trunc);
7129                 if (trunc)
7130                         goto endofcommand;
7131         }
7132
7133         END_OF_SMB
7134
7135         return offset;
7136 }
7137
7138
7139 static int
7140 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7141 {
7142         guint8  wc, cmd=0xff;
7143         guint16 andxoffset=0;
7144         guint16 bc;
7145         int fn_len;
7146         const char *fn;
7147
7148         WORD_COUNT;
7149
7150         /* next smb command */
7151         cmd = tvb_get_guint8(tvb, offset);
7152         if(cmd!=0xff){
7153                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7154         } else {
7155                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands (0xff)");
7156         }
7157         offset += 1;
7158
7159         /* reserved byte */
7160         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7161         offset += 1;
7162
7163         /* andxoffset */
7164         andxoffset = tvb_get_letohs(tvb, offset);
7165         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7166         offset += 2;
7167
7168         /* reserved byte */
7169         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7170         offset += 1;
7171
7172         /* file name len */
7173         fn_len = tvb_get_letohs(tvb, offset);
7174         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
7175         offset += 2;
7176
7177         /* Create flags */
7178         offset = dissect_nt_create_bits(tvb, pinfo, tree, offset);
7179
7180         /* root directory fid */
7181         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
7182         offset += 4;
7183
7184         /* nt access mask */
7185         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
7186
7187         /* allocation size */
7188         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7189         offset += 8;
7190
7191         /* Extended File Attributes */
7192         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7193
7194         /* share access */
7195         offset = dissect_nt_share_access(tvb, pinfo, tree, offset);
7196
7197         /* create disposition */
7198         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
7199         offset += 4;
7200
7201         /* create options */
7202         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
7203
7204         /* impersonation level */
7205         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
7206         offset += 4;
7207
7208         /* security flags */
7209         offset = dissect_nt_security_flags(tvb, pinfo, tree, offset);
7210
7211         BYTE_COUNT;
7212
7213         /* file name */
7214         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7215         if (fn == NULL)
7216                 goto endofcommand;
7217         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7218                 fn);
7219         COUNT_BYTES(fn_len);
7220
7221         if (check_col(pinfo->fd, COL_INFO)) {
7222                 col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s", fn);
7223         }
7224
7225         END_OF_SMB
7226
7227         /* call AndXCommand (if there are any) */
7228         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
7229
7230         return offset;
7231 }
7232  
7233
7234 static int
7235 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7236 {
7237         guint8  wc, cmd=0xff;
7238         guint16 andxoffset=0;
7239         guint16 bc;
7240         guint16 fid;
7241
7242         WORD_COUNT;
7243
7244         /* next smb command */
7245         cmd = tvb_get_guint8(tvb, offset);
7246         if(cmd!=0xff){
7247                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
7248         } else {
7249                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: No further commands");
7250         }
7251         offset += 1;
7252
7253         /* reserved byte */
7254         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
7255         offset += 1;
7256
7257         /* andxoffset */
7258         andxoffset = tvb_get_letohs(tvb, offset);
7259         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
7260         offset += 2;
7261
7262         /* oplock level */
7263         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
7264         offset += 1;
7265
7266         /* fid */
7267         fid = tvb_get_letohs(tvb, offset);
7268         add_fid(tvb, pinfo, tree, offset, fid);
7269         offset += 2;
7270
7271         /* create action */
7272         /*XXX is this really the same as create disposition in the request? it looks so*/
7273         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
7274         offset += 4;
7275
7276         /* create time */
7277         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7278                 "Create Time", hf_smb_create_time);
7279         
7280         /* access time */
7281         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7282                 "Access Time", hf_smb_access_time);
7283         
7284         /* last write time */
7285         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7286                 "Write Time", hf_smb_last_write_time);
7287         
7288         /* last change time */
7289         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
7290                 "Change Time", hf_smb_change_time);
7291         
7292         /* Extended File Attributes */
7293         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
7294
7295         /* allocation size */
7296         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
7297         offset += 8;
7298
7299         /* end of file */
7300         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
7301         offset += 8;
7302
7303         /* File Type */
7304         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
7305         offset += 2;
7306
7307         /* IPC State */
7308         offset = dissect_ipc_state(tvb, pinfo, tree, offset);
7309
7310         /* is directory */
7311         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
7312         offset += 1;
7313
7314         BYTE_COUNT;
7315
7316         END_OF_SMB
7317
7318         /* call AndXCommand (if there are any) */
7319         dissect_smb_command(tvb, pinfo, tree, andxoffset, smb_tree, cmd);
7320
7321         return offset;
7322 }
7323
7324
7325 static int
7326 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
7327 {
7328         smb_info_t *si;
7329         guint8 wc;
7330         guint16 bc;
7331         conversation_t *conversation;
7332         conv_tables_t *ct;
7333         smb_saved_info_t *old_si;
7334
7335         si = pinfo->private_data;
7336         conversation = find_conversation(&pinfo->src, &pinfo->dst,
7337                           pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
7338         if(conversation){
7339                 ct=conversation_get_proto_data(conversation, proto_smb);
7340                 if(ct){
7341                         old_si=g_hash_table_lookup(ct->unmatched, (void *)si->mid);
7342                         if(old_si){
7343                                 proto_tree_add_uint(tree, hf_smb_cancel_to, tvb, 0, 0, old_si->frame_req);
7344                         } else {
7345                                 proto_tree_add_text(tree, tvb, 0, 0,
7346                                                     "Cancellation to: <unknown frame>");
7347                         }
7348                 }
7349         }
7350
7351         WORD_COUNT;
7352  
7353         BYTE_COUNT;
7354
7355         END_OF_SMB
7356
7357         return offset;
7358 }
7359
7360 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7361    BEGIN Transaction/Transaction2 Primary and secondary requests
7362    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
7363
7364
7365 static const value_string trans2_cmd_vals[] = {
7366         { 0x00,         "OPEN2" },
7367         { 0x01,         "FIND_FIRST2" },
7368         { 0x02,         "FIND_NEXT2" },
7369         { 0x03,         "QUERY_FS_INFORMATION" },
7370         { 0x05,         "QUERY_PATH_INFORMATION" },
7371         { 0x06,         "SET_PATH_INFORMATION" },
7372         { 0x07,         "QUERY_FILE_INFORMATION" },
7373         { 0x08,         "SET_FILE_INFORMATION" },
7374         { 0x09,         "FSCTL" },
7375         { 0x0A,         "IOCTL2" },
7376         { 0x0B,         "FIND_NOTIFY_FIRST" },
7377         { 0x0C,         "FIND_NOTIFY_NEXT" },
7378         { 0x0D,         "CREATE_DIRECTORY" },
7379         { 0x0E,         "SESSION_SETUP" },
7380         { 0x10,         "GET_DFS_REFERRAL" },
7381         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
7382         { 0,    NULL }
7383 };
7384
7385 static const true_false_string tfs_tf_dtid = {
7386         "Also DISCONNECT TID",
7387         "Do NOT disconnect TID"
7388 };
7389 static const true_false_string tfs_tf_owt = {
7390         "One Way Transaction (NO RESPONSE)",
7391         "Two way transaction"
7392 };
7393
7394 static const true_false_string tfs_ff2_backup = {
7395         "Find WITH backup intent",
7396         "No backup intent"
7397 };
7398 static const true_false_string tfs_ff2_continue = {
7399         "CONTINUE search from previous position",
7400         "New search, do NOT continue from previous position"
7401 };
7402 static const true_false_string tfs_ff2_resume = {
7403         "Return RESUME keys",
7404         "Do NOT return resume keys"
7405 };
7406 static const true_false_string tfs_ff2_close_eos = {
7407         "CLOSE search if END OF SEARCH is reached",
7408         "Do NOT close search if end of search reached"
7409 };
7410 static const true_false_string tfs_ff2_close = {
7411         "CLOSE search after this request",
7412         "Do NOT close search after this request"
7413 };
7414
7415 /* used by
7416    TRANS2_FIND_FIRST2
7417 */
7418 static const value_string ff2_il_vals[] = {
7419         { 1,            "Info Standard  (4.3.4.1)"},
7420         { 2,            "Info Query EA Size  (4.3.4.2)"},
7421         { 3,            "Info Query EAs From List  (4.3.4.2)"},
7422         { 0x0101,       "Find File Directory Info  (4.3.4.4)"},
7423         { 0x0102,       "Find File Full Directory Info  (4.3.4.5)"},
7424         { 0x0103,       "Find File Names Info  (4.3.4.7)"},
7425         { 0x0104,       "Find File Both Directory Info  (4.3.4.6)"},
7426         { 0x0202,       "Find File UNIX  (4.3.4.8)"},
7427         {0, NULL}
7428 };
7429
7430 /* values used by :
7431         TRANS2_QUERY_PATH_INFORMATION
7432         TRANS2_SET_PATH_INFORMATION
7433 */
7434 static const value_string qpi_loi_vals[] = {
7435         { 1,            "Info Standard  (4.2.14.1)"},
7436         { 2,            "Info Query EA Size  (4.2.14.1)"},
7437         { 3,            "Info Query EAs From List  (4.2.14.2)"},
7438         { 4,            "Info Query All EAs  (4.2.14.2)"},
7439         { 6,            "Info Is Name Valid  (4.2.14.3)"},
7440         { 0x0101,       "Query File Basic Info  (4.2.14.4)"},
7441         { 0x0102,       "Query File Standard Info  (4.2.14.5)"},
7442         { 0x0103,       "Query File EA Info  (4.2.14.6)"},
7443         { 0x0104,       "Query File Name Info  (4.2.14.7)"},
7444         { 0x0107,       "Query File All Info  (4.2.14.8)"},
7445         { 0x0108,       "Query File Alt File Info  (4.2.14.7)"},
7446         { 0x0109,       "Query File Stream Info  (4.2.14.10)"},
7447         { 0x010b,       "Query File Compression Info  (4.2.14.11)"},
7448         { 0x0200,       "Set File Unix Basic"},
7449         { 0x0201,       "Set File Unix Link"},
7450         { 0x0202,       "Set File Unix HardLink"},
7451         {0, NULL}
7452 };
7453
7454 static const value_string qfsi_vals[] = {
7455         { 1,            "Info Allocation"},
7456         { 2,            "Info Volume"},
7457         { 0x0102,       "Query FS Volume Info"},
7458         { 0x0103,       "Query FS Size Info"},
7459         { 0x0104,       "Query FS Device Info"},
7460         { 0x0105,       "Query FS Attribute Info"},
7461         {0, NULL}
7462 };
7463
7464 static const value_string delete_pending_vals[] = {
7465         {0,     "Normal, no pending delete"},
7466         {1,     "This object has DELETE PENDING"},
7467         {0, NULL}
7468 };
7469
7470 static const value_string alignment_vals[] = {
7471         {0,     "Byte alignment"},
7472         {1,     "Word (16bit) alignment"},
7473         {3,     "Long (32bit) alignment"},
7474         {7,     "8 byte boundary alignment"},
7475         {0x0f,  "16 byte boundary alignment"},
7476         {0x1f,  "32 byte boundary alignment"},
7477         {0x3f,  "64 byte boundary alignment"},
7478         {0x7f,  "128 byte boundary alignment"},
7479         {0xff,  "256 byte boundary alignment"},
7480         {0x1ff, "512 byte boundary alignment"},
7481         {0, NULL}
7482 };
7483
7484
7485 static const true_false_string tfs_get_dfs_server_hold_storage = {
7486         "Referral SERVER HOLDS STORAGE for the file",
7487         "Referral server does NOT hold storage for the file"
7488 };
7489 static const true_false_string tfs_get_dfs_fielding = {
7490         "The server in referral is FIELDING CAPABLE",
7491         "The server in referrals is NOT fielding capable"
7492 };
7493
7494 static const true_false_string tfs_dfs_referral_flags_strip = {
7495         "STRIP off pathconsumed characters before submitting",
7496         "Do NOT strip off any characters"
7497 };
7498
7499 static const value_string dfs_referral_server_type_vals[] = {
7500         {0,     "Don't know"},
7501         {1,     "SMB Server"},
7502         {2,     "Netware Server"},
7503         {3,     "Domain Server"},
7504         {0, NULL}
7505 };
7506
7507
7508 static const true_false_string tfs_device_char_removable = {
7509         "This is a REMOVABLE device",
7510         "This is NOT a removable device"
7511 };
7512 static const true_false_string tfs_device_char_read_only = {
7513         "This is a READ-ONLY device",
7514         "This is NOT a read-only device"
7515 };
7516 static const true_false_string tfs_device_char_floppy = {
7517         "This is a FLOPPY DISK device",
7518         "This is NOT a floppy disk device"
7519 };
7520 static const true_false_string tfs_device_char_write_once = {
7521         "This is a WRITE-ONCE device",
7522         "This is NOT a write-once device"
7523 };
7524 static const true_false_string tfs_device_char_remote = {
7525         "This is a REMOTE device",
7526         "This is NOT a remote device"
7527 };
7528 static const true_false_string tfs_device_char_mounted = {
7529         "This device is MOUNTED",
7530         "This device is NOT mounted"
7531 };
7532 static const true_false_string tfs_device_char_virtual = {
7533         "This is a VIRTUAL device",
7534         "This is NOT a virtual device"
7535 };
7536
7537
7538 static const true_false_string tfs_fs_attr_css = {
7539         "This FS supports CASE SENSITIVE SEARCHes",
7540         "This FS does NOT support case sensitive searches"
7541 };
7542 static const true_false_string tfs_fs_attr_cpn = {
7543         "This FS supports CASE PRESERVED NAMES",
7544         "This FS does NOT support case preserved names"
7545 };
7546 static const true_false_string tfs_fs_attr_pacls = {
7547         "This FS supports PERSISTENT ACLs",
7548         "This FS does NOT support persistent acls"
7549 };
7550 static const true_false_string tfs_fs_attr_fc = {
7551         "This FS supports COMPRESSED FILES",
7552         "This FS does NOT support compressed files"
7553 };
7554 static const true_false_string tfs_fs_attr_vq = {
7555         "This FS supports VOLUME QUOTAS",
7556         "This FS does NOT support volume quotas"
7557 };
7558 static const true_false_string tfs_fs_attr_dim = {
7559         "This FS is on a MOUNTED DEVICE",
7560         "This FS is NOT on a mounted device"
7561 };
7562 static const true_false_string tfs_fs_attr_vic = {
7563         "This FS is on a COMPRESSED VOLUME",
7564         "This FS is NOT on a compressed volume"
7565 };
7566
7567
7568
7569 static int
7570 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
7571 {
7572         guint16 mask;
7573         proto_item *item = NULL;
7574         proto_tree *tree = NULL;
7575
7576         mask = tvb_get_letohs(tvb, offset);
7577
7578         if(parent_tree){
7579                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7580                         "Flags: 0x%04x", mask);
7581                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
7582         }
7583
7584         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
7585                 tvb, offset, 2, mask);
7586         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
7587                 tvb, offset, 2, mask);
7588         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
7589                 tvb, offset, 2, mask);
7590         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
7591                 tvb, offset, 2, mask);
7592         proto_tree_add_boolean(tree, hf_smb_ff2_close,
7593                 tvb, offset, 2, mask);
7594
7595         offset += 2;
7596
7597         return offset;
7598 }
7599
7600 static int
7601 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
7602     proto_tree *parent_tree, int offset, guint16 bc)
7603 {
7604         proto_item *item = NULL;
7605         proto_tree *tree = NULL;
7606         smb_info_t *si;
7607         smb_transact2_info_t *t2i;
7608         int fn_len;
7609         const char *fn;
7610         int old_offset = offset;
7611
7612         si = (smb_info_t *)pinfo->private_data;
7613         t2i = si->sip->extra_info;
7614
7615         if(parent_tree){
7616                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
7617                                 "%s Parameters",
7618                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
7619                                            "Unknown (0x%02x)"));
7620                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
7621         }
7622
7623         switch(t2i->subcmd){
7624         case 0x00:      /*TRANS2_OPEN2*/
7625                 /* open flags */
7626                 CHECK_BYTE_COUNT_TRANS(2);
7627                 offset = dissect_open_flags(tvb, pinfo, tree, offset, 0x000f);
7628                 bc -= 2;
7629
7630                 /* desired access */
7631                 CHECK_BYTE_COUNT_TRANS(2);
7632                 offset = dissect_access(tvb, pinfo, tree, offset, "Desired");
7633                 bc -= 2;
7634
7635                 /* 2 reserved bytes */
7636                 CHECK_BYTE_COUNT_TRANS(2);
7637                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7638                 COUNT_BYTES_TRANS(2);
7639
7640                 /* File Attributes */
7641                 CHECK_BYTE_COUNT_TRANS(2);
7642                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
7643                 bc -= 2;
7644
7645                 /* create time */
7646                 CHECK_BYTE_COUNT_TRANS(4);
7647                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
7648                         hf_smb_create_time,
7649                         hf_smb_create_dos_date, hf_smb_create_dos_time,
7650                         TRUE);
7651                 bc -= 4;
7652
7653                 /* open function */
7654                 CHECK_BYTE_COUNT_TRANS(2);
7655                 offset = dissect_open_function(tvb, pinfo, tree, offset);
7656                 bc -= 2;
7657
7658                 /* allocation size */
7659                 CHECK_BYTE_COUNT_TRANS(4);
7660                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
7661                 COUNT_BYTES_TRANS(4);
7662
7663                 /* 10 reserved bytes */
7664                 CHECK_BYTE_COUNT_TRANS(10);
7665                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
7666                 COUNT_BYTES_TRANS(10);
7667
7668                 /* file name */
7669                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7670                 CHECK_STRING_TRANS(fn);
7671                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7672                         fn);
7673                 COUNT_BYTES_TRANS(fn_len);
7674
7675                 if (check_col(pinfo->fd, COL_INFO)) {
7676                         col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s",
7677                         fn);
7678                 }
7679
7680                 /* XXX dont know how to decode FEAList */
7681                 break;
7682         case 0x01:      /*TRANS2_FIND_FIRST2*/
7683                 /* Search Attributes */
7684                 CHECK_BYTE_COUNT_TRANS(2);
7685                 offset = dissect_search_attributes(tvb, pinfo, tree, offset);
7686                 bc -= 2;
7687
7688                 /* search count */
7689                 CHECK_BYTE_COUNT_TRANS(2);
7690                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
7691                 COUNT_BYTES_TRANS(2);
7692
7693                 /* Find First2 flags */
7694                 CHECK_BYTE_COUNT_TRANS(2);
7695                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
7696                 bc -= 2;
7697
7698                 /* Find First2 information level */
7699                 CHECK_BYTE_COUNT_TRANS(2);
7700                 t2i->info_level = tvb_get_letohs(tvb, offset);
7701                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, t2i->info_level);
7702                 COUNT_BYTES_TRANS(2);
7703
7704                 /* storage type */
7705                 CHECK_BYTE_COUNT_TRANS(4);
7706                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
7707                 COUNT_BYTES_TRANS(4);
7708
7709                 /* search pattern */
7710                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7711                 CHECK_STRING_TRANS(fn);
7712                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
7713                         fn);
7714                 COUNT_BYTES_TRANS(fn_len);
7715
7716                 if (check_col(pinfo->fd, COL_INFO)) {
7717                         col_append_fstr(pinfo->fd, COL_INFO, ", Pattern: %s",
7718                         fn);
7719                 }
7720
7721                 /* XXX dont know how to decode FEAList */
7722
7723                 break;
7724         case 0x02:      /*TRANS2_FIND_NEXT2*/
7725                 /* sid */
7726                 CHECK_BYTE_COUNT_TRANS(2);
7727                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
7728                 COUNT_BYTES_TRANS(2);
7729
7730                 /* search count */
7731                 CHECK_BYTE_COUNT_TRANS(2);
7732                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
7733                 COUNT_BYTES_TRANS(2);
7734
7735                 /* Find First2 information level */
7736                 CHECK_BYTE_COUNT_TRANS(2);
7737                 t2i->info_level = tvb_get_letohs(tvb, offset);
7738                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, t2i->info_level);
7739                 COUNT_BYTES_TRANS(2);
7740
7741                 /* resume key */
7742                 CHECK_BYTE_COUNT_TRANS(4);
7743                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
7744                 COUNT_BYTES_TRANS(4);
7745
7746                 /* Find First2 flags */
7747                 CHECK_BYTE_COUNT_TRANS(2);
7748                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
7749                 bc -= 2;
7750
7751                 /* file name */
7752                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7753                 CHECK_STRING_TRANS(fn);
7754                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7755                         fn);
7756                 COUNT_BYTES_TRANS(fn_len);
7757
7758                 if (check_col(pinfo->fd, COL_INFO)) {
7759                         col_append_fstr(pinfo->fd, COL_INFO, ", Continue: %s",
7760                         fn);
7761                 }
7762
7763                 break;
7764         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
7765                 /* level of interest */
7766                 CHECK_BYTE_COUNT_TRANS(2);
7767                 t2i->info_level = tvb_get_letohs(tvb, offset);
7768                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, t2i->info_level);
7769                 COUNT_BYTES_TRANS(2);
7770
7771                 break;
7772         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
7773                 /* level of interest */
7774                 CHECK_BYTE_COUNT_TRANS(2);
7775                 t2i->info_level = tvb_get_letohs(tvb, offset);
7776                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, t2i->info_level);
7777                 COUNT_BYTES_TRANS(2);
7778                 
7779                 /* 4 reserved bytes */
7780                 CHECK_BYTE_COUNT_TRANS(4);
7781                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
7782                 COUNT_BYTES_TRANS(4);
7783
7784                 /* file name */
7785                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7786                 CHECK_STRING_TRANS(fn);
7787                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7788                         fn);
7789                 COUNT_BYTES_TRANS(fn_len);
7790
7791                 if (check_col(pinfo->fd, COL_INFO)) {
7792                         col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s",
7793                         fn);
7794                 }
7795
7796                 break;
7797         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
7798                 /* level of interest */
7799                 CHECK_BYTE_COUNT_TRANS(2);
7800                 t2i->info_level = tvb_get_letohs(tvb, offset);
7801                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, t2i->info_level);
7802                 COUNT_BYTES_TRANS(2);
7803                 
7804                 /* 4 reserved bytes */
7805                 CHECK_BYTE_COUNT_TRANS(4);
7806                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
7807                 COUNT_BYTES_TRANS(4);
7808
7809                 /* file name */
7810                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7811                 CHECK_STRING_TRANS(fn);
7812                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7813                         fn);
7814                 COUNT_BYTES_TRANS(fn_len);
7815
7816                 if (check_col(pinfo->fd, COL_INFO)) {
7817                         col_append_fstr(pinfo->fd, COL_INFO, ", Path: %s",
7818                         fn);
7819                 }
7820
7821                 break;
7822         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
7823                 /* fid */
7824                 CHECK_BYTE_COUNT_TRANS(2);
7825                 proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
7826                 COUNT_BYTES_TRANS(2);
7827
7828                 /* level of interest */
7829                 CHECK_BYTE_COUNT_TRANS(2);
7830                 t2i->info_level = tvb_get_letohs(tvb, offset);
7831                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, t2i->info_level);
7832                 COUNT_BYTES_TRANS(2);
7833                 
7834                 break;
7835         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
7836                 /* fid */
7837                 CHECK_BYTE_COUNT_TRANS(2);
7838                 proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
7839                 COUNT_BYTES_TRANS(2);
7840
7841                 /* level of interest */
7842                 CHECK_BYTE_COUNT_TRANS(2);
7843                 t2i->info_level = tvb_get_letohs(tvb, offset);
7844                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, t2i->info_level);
7845                 COUNT_BYTES_TRANS(2);
7846                 
7847                 /* 2 reserved bytes */
7848                 CHECK_BYTE_COUNT_TRANS(2);
7849                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
7850                 COUNT_BYTES_TRANS(2);
7851
7852                 break;
7853         case 0x09:      /*TRANS2_FSCTL*/
7854         case 0x0a:      /*TRANS2_IOCTL2*/
7855                 /* these calls have no parameter block in the request */
7856                 break;
7857         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
7858         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
7859                 /* XXX unknown structure*/
7860                 break;
7861         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
7862                 /* 4 reserved bytes */
7863                 CHECK_BYTE_COUNT_TRANS(4);
7864                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
7865                 COUNT_BYTES_TRANS(4);
7866
7867                 /* dir name */
7868                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len,
7869                         FALSE, FALSE, &bc);
7870                 CHECK_STRING_TRANS(fn);
7871                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
7872                         fn);
7873                 COUNT_BYTES_TRANS(fn_len);
7874
7875                 if (check_col(pinfo->fd, COL_INFO)) {
7876                         col_append_fstr(pinfo->fd, COL_INFO, ", Dir: %s",
7877                         fn);
7878                 }
7879
7880                 /* XXX optional FEAList, unknown what FEAList looks like*/
7881                 break;
7882         case 0x0e:      /*TRANS2_SESSION_SETUP*/
7883                 /* XXX unknown structure*/
7884                 break;
7885         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
7886                 /* referral level */
7887                 CHECK_BYTE_COUNT_TRANS(2);
7888                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
7889                 COUNT_BYTES_TRANS(2);
7890                 
7891                 /* file name */
7892                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7893                 CHECK_STRING_TRANS(fn);
7894                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7895                         fn);
7896                 COUNT_BYTES_TRANS(fn_len);
7897
7898                 if (check_col(pinfo->fd, COL_INFO)) {
7899                         col_append_fstr(pinfo->fd, COL_INFO, ", File: %s",
7900                         fn);
7901                 }
7902
7903                 break;
7904         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
7905                 /* file name */
7906                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, &bc);
7907                 CHECK_STRING_TRANS(fn);
7908                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
7909                         fn);
7910                 COUNT_BYTES_TRANS(fn_len);
7911
7912                 if (check_col(pinfo->fd, COL_INFO)) {
7913                         col_append_fstr(pinfo->fd, COL_INFO, ", File: %s",
7914                         fn);
7915                 }
7916
7917                 break;
7918         }
7919
7920         /* ooops there were data we didnt know how to process */
7921         if((offset-old_offset) < bc){
7922                 proto_tree_add_bytes(tree, hf_smb_unknown, tvb, offset, bc - (offset-old_offset), tvb_get_ptr(tvb, offset, 1));
7923                 offset += bc - (offset-old_offset);
7924         }
7925
7926         return offset;
7927 }
7928
7929 /*
7930  * XXX - just use "dissect_connect_flags()" here?
7931  */
7932 static guint16
7933 dissect_transaction_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
7934 {
7935         guint16 mask;
7936         proto_item *item = NULL;
7937         proto_tree *tree = NULL;
7938
7939         mask = tvb_get_letohs(tvb, offset);
7940
7941         if(parent_tree){
7942                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7943                         "Flags: 0x%04x", mask);
7944                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
7945         }
7946
7947         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
7948                 tvb, offset, 2, mask);
7949         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
7950                 tvb, offset, 2, mask);
7951
7952         return mask;
7953 }
7954  
7955
7956 static int
7957 dissect_get_dfs_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
7958 {
7959         guint16 mask;
7960         proto_item *item = NULL;
7961         proto_tree *tree = NULL;
7962
7963         mask = tvb_get_letohs(tvb, offset);
7964
7965         if(parent_tree){
7966                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7967                         "Flags: 0x%04x", mask);
7968                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
7969         }
7970
7971         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
7972                 tvb, offset, 2, mask);
7973         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
7974                 tvb, offset, 2, mask);
7975
7976         offset += 2;
7977         return offset;
7978 }
7979
7980 static int
7981 dissect_dfs_referral_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
7982 {
7983         guint16 mask;
7984         proto_item *item = NULL;
7985         proto_tree *tree = NULL;
7986
7987         mask = tvb_get_letohs(tvb, offset);
7988
7989         if(parent_tree){
7990                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7991                         "Flags: 0x%04x", mask);
7992                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
7993         }
7994
7995         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
7996                 tvb, offset, 2, mask);
7997
7998         offset += 2;
7999
8000         return offset;
8001 }
8002
8003
8004 /* dfs inconsistency data  (4.4.2)
8005 */
8006 static int
8007 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
8008     proto_tree *tree, int offset, guint16 *bcp)
8009 {
8010         int fn_len;
8011         const char *fn;
8012
8013         /*XXX shouldn this data hold version and size? unclear from doc*/
8014         /* referral version */
8015         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8016         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
8017         COUNT_BYTES_TRANS_SUBR(2);
8018
8019         /* referral size */
8020         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8021         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
8022         COUNT_BYTES_TRANS_SUBR(2);
8023
8024         /* referral server type */
8025         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8026         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
8027         COUNT_BYTES_TRANS_SUBR(2);
8028
8029         /* referral flags */
8030         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8031         offset = dissect_dfs_referral_flags(tvb, pinfo, tree, offset);
8032         *bcp -= 2;
8033
8034         /* node name */
8035         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
8036         CHECK_STRING_TRANS_SUBR(fn);
8037         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
8038                 fn);
8039         COUNT_BYTES_TRANS_SUBR(fn_len);
8040
8041         return offset;
8042 }
8043
8044 /* get dfs referral data  (4.4.1)
8045 */
8046 static int
8047 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
8048     proto_tree *tree, int offset, guint16 *bcp)
8049 {
8050         guint16 numref;
8051         guint16 refsize;
8052         guint16 pathoffset;
8053         guint16 altpathoffset;
8054         guint16 nodeoffset;
8055         int fn_len;
8056         int stroffset;
8057         int offsetoffset;
8058         guint16 save_bc;
8059         const char *fn;
8060         int unklen;
8061         int ucstring_end;
8062         int ucstring_len;
8063
8064         /* path consumed */
8065         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8066         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
8067         COUNT_BYTES_TRANS_SUBR(2);
8068
8069         /* num referrals */
8070         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8071         numref = tvb_get_letohs(tvb, offset);
8072         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
8073         COUNT_BYTES_TRANS_SUBR(2);
8074
8075         /* get dfs flags */
8076         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8077         offset = dissect_get_dfs_flags(tvb, pinfo, tree, offset);
8078         *bcp -= 2;
8079
8080         /* XXX - in at least one capture there appears to be 2 bytes
8081            of stuff after the Dfs flags, perhaps so that the header
8082            in front of the referral list is a multiple of 4 bytes long. */
8083         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8084         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
8085         COUNT_BYTES_TRANS_SUBR(2);
8086
8087         /* if there are any referrals */
8088         if(numref){
8089                 proto_item *ref_item = NULL;
8090                 proto_tree *ref_tree = NULL;
8091                 int old_offset=offset;
8092
8093                 if(tree){
8094                         ref_item = proto_tree_add_text(tree,
8095                                 tvb, offset, *bcp, "Referrals");
8096                         ref_tree = proto_item_add_subtree(ref_item,
8097                                 ett_smb_dfs_referrals);
8098                 }
8099                 ucstring_end = -1;
8100
8101                 while(numref--){
8102                         proto_item *ri = NULL;
8103                         proto_tree *rt = NULL;
8104                         int old_offset=offset;
8105                         guint16 version;
8106
8107                         if(tree){
8108                                 ri = proto_tree_add_text(ref_tree,
8109                                         tvb, offset, *bcp, "Referral");
8110                                 rt = proto_item_add_subtree(ri,
8111                                         ett_smb_dfs_referral);
8112                         }
8113                 
8114                         /* referral version */
8115                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8116                         version = tvb_get_letohs(tvb, offset);
8117                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
8118                                 tvb, offset, 2, version);
8119                         COUNT_BYTES_TRANS_SUBR(2);
8120
8121                         /* referral size */
8122                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8123                         refsize = tvb_get_letohs(tvb, offset);
8124                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
8125                         COUNT_BYTES_TRANS_SUBR(2);
8126
8127                         /* referral server type */
8128                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8129                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
8130                         COUNT_BYTES_TRANS_SUBR(2);
8131
8132                         /* referral flags */
8133                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
8134                         offset = dissect_dfs_referral_flags(tvb, pinfo, rt, offset);
8135                         *bcp -= 2;
8136
8137                         switch(version){
8138
8139                         case 1:
8140                                 /* node name */
8141                                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
8142                                 CHECK_STRING_TRANS_SUBR(fn);
8143                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
8144                                         fn);
8145                                 COUNT_BYTES_TRANS_SUBR(fn_len);
8146                                 break;
8147
8148                         case 2:
8149                         case 3: /* XXX - like version 2, but not identical;
8150                                    seen in a capture, but the format isn't
8151                                    documented */
8152                                 /* proximity */
8153                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
8154                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
8155                                 COUNT_BYTES_TRANS_SUBR(2);
8156
8157                                 /* ttl */
8158                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
8159                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
8160                                 COUNT_BYTES_TRANS_SUBR(2);
8161
8162                                 /* path offset */
8163                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
8164                                 pathoffset = tvb_get_letohs(tvb, offset);
8165                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
8166                                 COUNT_BYTES_TRANS_SUBR(2);
8167
8168                                 /* alt path offset */
8169                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
8170                                 altpathoffset = tvb_get_letohs(tvb, offset);
8171                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
8172                                 COUNT_BYTES_TRANS_SUBR(2);
8173
8174                                 /* node offset */
8175                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
8176                                 nodeoffset = tvb_get_letohs(tvb, offset);
8177                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
8178                                 COUNT_BYTES_TRANS_SUBR(2);
8179
8180                                 /* path */
8181                                 if (pathoffset != 0) {
8182                                         stroffset = old_offset + pathoffset;
8183                                         offsetoffset = stroffset - offset;
8184                                         if (offsetoffset > 0 &&
8185                                             *bcp > offsetoffset) {
8186                                                 save_bc = *bcp;
8187                                                 *bcp -= offsetoffset;
8188                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
8189                                                 CHECK_STRING_TRANS_SUBR(fn);
8190                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
8191                                                         fn);
8192                                                 stroffset += fn_len;
8193                                                 if (ucstring_end < stroffset)
8194                                                         ucstring_end = stroffset;
8195                                                 *bcp = save_bc;
8196                                         }
8197                                 }
8198                         
8199                                 /* alt path */
8200                                 if (altpathoffset != 0) {
8201                                         stroffset = old_offset + altpathoffset;
8202                                         offsetoffset = stroffset - offset;
8203                                         if (offsetoffset > 0 &&
8204                                             *bcp > offsetoffset) {
8205                                                 save_bc = *bcp;
8206                                                 *bcp -= offsetoffset;
8207                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
8208                                                 CHECK_STRING_TRANS_SUBR(fn);
8209                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
8210                                                         fn);
8211                                                 stroffset += fn_len;
8212                                                 if (ucstring_end < stroffset)
8213                                                         ucstring_end = stroffset;
8214                                                 *bcp = save_bc;
8215                                         }
8216                                 }
8217                         
8218                                 /* node */
8219                                 if (nodeoffset != 0) {
8220                                         stroffset = old_offset + nodeoffset;
8221                                         offsetoffset = stroffset - offset;
8222                                         if (offsetoffset > 0 &&
8223                                             *bcp > offsetoffset) {
8224                                                 save_bc = *bcp;
8225                                                 *bcp -= offsetoffset;
8226                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, pinfo, &fn_len, FALSE, FALSE, bcp);
8227                                                 CHECK_STRING_TRANS_SUBR(fn);
8228                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
8229                                                         fn);
8230                                                 stroffset += fn_len;
8231                                                 if (ucstring_end < stroffset)
8232                                                         ucstring_end = stroffset;
8233                                                 *bcp = save_bc;
8234                                         }
8235                                 }
8236                                 break;
8237                         }
8238
8239                         /*
8240                          * Show anything beyond the length of the referral
8241                          * as unknown data.
8242                          */
8243                         unklen = (old_offset + refsize) - offset;
8244                         if (unklen < 0) {
8245                                 /*
8246                                  * XXX - the length is bogus.
8247                                  */
8248                                 unklen = 0;
8249                         }
8250                         if (unklen != 0) {
8251                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
8252                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
8253                                     offset, unklen, TRUE);
8254                                 COUNT_BYTES_TRANS_SUBR(unklen);
8255                         }
8256
8257                         proto_item_set_len(ri, offset-old_offset);
8258                 }
8259
8260                 /*
8261                  * Treat the offset past the end of the last Unicode
8262                  * string after the referrals (if any) as the last
8263                  * offset.
8264                  */
8265                 if (ucstring_end > offset) {
8266                         ucstring_len = ucstring_end - offset;
8267                         if (*bcp < ucstring_len)
8268                                 ucstring_len = *bcp;
8269                         offset += ucstring_len;
8270                         *bcp -= ucstring_len;
8271                 }
8272                 proto_item_set_len(ref_item, offset-old_offset);
8273         }
8274
8275         return offset;
8276 }
8277
8278
8279 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
8280    as described in 4.2.14.1
8281 */
8282 static int
8283 dissect_4_2_14_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8284     int offset, guint16 *bcp, gboolean *trunc)
8285 {
8286         /* create time */
8287         CHECK_BYTE_COUNT_SUBR(4);
8288         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8289                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
8290                 FALSE);
8291         *bcp -= 4;
8292
8293         /* access time */
8294         CHECK_BYTE_COUNT_SUBR(4);
8295         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8296                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
8297                 FALSE);
8298         *bcp -= 4;
8299
8300         /* last write time */
8301         CHECK_BYTE_COUNT_SUBR(4);
8302         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
8303                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
8304                 FALSE);
8305         *bcp -= 4;
8306
8307         /* data size */
8308         CHECK_BYTE_COUNT_SUBR(4);
8309         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
8310         COUNT_BYTES_SUBR(4);
8311
8312         /* allocation size */
8313         CHECK_BYTE_COUNT_SUBR(4);
8314         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
8315         COUNT_BYTES_SUBR(4);
8316
8317         /* File Attributes */
8318         CHECK_BYTE_COUNT_SUBR(2);
8319         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
8320         *bcp -= 2;
8321
8322         /* ea size */
8323         CHECK_BYTE_COUNT_SUBR(4);
8324         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
8325         COUNT_BYTES_SUBR(4);
8326
8327         *trunc = FALSE;
8328         return offset;
8329 }
8330
8331 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
8332    as described in 4.2.14.2
8333 */
8334 static int
8335 dissect_4_2_14_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8336     int offset, guint16 *bcp, gboolean *trunc)
8337 {
8338         /* list length */
8339         CHECK_BYTE_COUNT_SUBR(4);
8340         proto_tree_add_item(tree, hf_smb_list_length, tvb, offset, 4, TRUE);
8341         COUNT_BYTES_SUBR(4);
8342
8343         *trunc = FALSE;
8344         return offset;
8345 }
8346
8347 /* this dissects the SMB_INFO_IS_NAME_VALID
8348    as described in 4.2.14.3
8349 */
8350 static int
8351 dissect_4_2_14_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8352     int offset, guint16 *bcp, gboolean *trunc)
8353 {
8354         int fn_len;
8355         const char *fn;
8356
8357         /* file name */
8358         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
8359         CHECK_STRING_SUBR(fn);
8360         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8361                 fn);
8362         COUNT_BYTES_SUBR(fn_len);
8363
8364         *trunc = FALSE;
8365         return offset;
8366 }
8367
8368 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
8369    as described in 4.2.14.4
8370 */
8371 static int
8372 dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8373     int offset, guint16 *bcp, gboolean *trunc)
8374 {
8375         /* create time */
8376         CHECK_BYTE_COUNT_SUBR(8);
8377         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8378                 "Create", hf_smb_create_time);
8379         *bcp -= 8;
8380         
8381         /* access time */
8382         CHECK_BYTE_COUNT_SUBR(8);
8383         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8384                 "Access Time", hf_smb_access_time);
8385         *bcp -= 8;
8386         
8387         /* last write time */
8388         CHECK_BYTE_COUNT_SUBR(8);
8389         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8390                 "Write Time", hf_smb_last_write_time);
8391         *bcp -= 8;
8392         
8393         /* last change time */
8394         CHECK_BYTE_COUNT_SUBR(8);
8395         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
8396                 "Change Time", hf_smb_change_time);
8397         *bcp -= 8;
8398         
8399         /* File Attributes */
8400         CHECK_BYTE_COUNT_SUBR(2);
8401         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
8402         *bcp -= 2;
8403
8404         *trunc = FALSE;
8405         return offset;
8406 }
8407
8408 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
8409    as described in 4.2.14.5
8410 */
8411 static int
8412 dissect_4_2_14_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8413     int offset, guint16 *bcp, gboolean *trunc)
8414 {
8415         /* allocation size */
8416         CHECK_BYTE_COUNT_SUBR(8);
8417         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8418         COUNT_BYTES_SUBR(8);
8419
8420         /* end of file */
8421         CHECK_BYTE_COUNT_SUBR(8);
8422         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8423         COUNT_BYTES_SUBR(8);
8424
8425         /* number of links */
8426         CHECK_BYTE_COUNT_SUBR(4);
8427         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
8428         COUNT_BYTES_SUBR(4);
8429
8430         /* delete pending */
8431         CHECK_BYTE_COUNT_SUBR(2);
8432         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 2, TRUE);
8433         COUNT_BYTES_SUBR(2);
8434
8435         /* is directory */
8436         CHECK_BYTE_COUNT_SUBR(1);
8437         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8438         COUNT_BYTES_SUBR(1);
8439
8440         *trunc = FALSE;
8441         return offset;
8442 }
8443
8444 /* this dissects the SMB_QUERY_FILE_EA_INFO
8445    as described in 4.2.14.6
8446 */
8447 static int
8448 dissect_4_2_14_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8449     int offset, guint16 *bcp, gboolean *trunc)
8450 {
8451         /* ea size */
8452         CHECK_BYTE_COUNT_SUBR(4);
8453         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
8454         COUNT_BYTES_SUBR(4);
8455
8456         *trunc = FALSE;
8457         return offset;
8458 }
8459
8460 /* this dissects the SMB_QUERY_FILE_NAME_INFO
8461    as described in 4.2.14.7
8462    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
8463    as described in 4.2.14.9
8464 */
8465 static int
8466 dissect_4_2_14_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8467     int offset, guint16 *bcp, gboolean *trunc)
8468 {
8469         int fn_len;
8470         const char *fn;
8471
8472         /* file name len */
8473         CHECK_BYTE_COUNT_SUBR(4);
8474         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
8475         COUNT_BYTES_SUBR(4);
8476
8477         /* file name */
8478         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
8479         CHECK_STRING_SUBR(fn);
8480         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8481                 fn);
8482         COUNT_BYTES_SUBR(fn_len);
8483
8484         *trunc = FALSE;
8485         return offset;
8486 }
8487
8488 /* this dissects the SMB_QUERY_FILE_ALL_INFO
8489    as described in 4.2.14.8
8490 */
8491 static int
8492 dissect_4_2_14_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8493     int offset, guint16 *bcp, gboolean *trunc)
8494 {
8495
8496         offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp, trunc);
8497         if (trunc)
8498                 return offset;
8499         offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp, trunc);
8500         if (trunc)
8501                 return offset;
8502
8503         /* index number */
8504         CHECK_BYTE_COUNT_SUBR(8);
8505         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
8506         COUNT_BYTES_SUBR(8);
8507
8508         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
8509         if (trunc)
8510                 return offset;
8511
8512         /* access flags */
8513         CHECK_BYTE_COUNT_SUBR(4);
8514         offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
8515         COUNT_BYTES_SUBR(4);
8516
8517         /* index number */
8518         CHECK_BYTE_COUNT_SUBR(8);
8519         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
8520         COUNT_BYTES_SUBR(8);
8521
8522         /* current offset */
8523         CHECK_BYTE_COUNT_SUBR(8);
8524         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
8525         COUNT_BYTES_SUBR(8);
8526
8527         /* mode */
8528         CHECK_BYTE_COUNT_SUBR(4);
8529         offset = dissect_nt_create_options(tvb, pinfo, tree, offset);
8530         *bcp -= 4;
8531
8532         /* alignment */
8533         CHECK_BYTE_COUNT_SUBR(4);
8534         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
8535         COUNT_BYTES_SUBR(4);
8536         
8537         offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp, trunc);
8538
8539         return offset;
8540 }
8541
8542 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
8543    as described in 4.2.14.10
8544 */
8545 static int
8546 dissect_4_2_14_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
8547     int offset, guint16 *bcp, gboolean *trunc)
8548 {
8549         proto_item *item;
8550         proto_tree *tree;
8551         int old_offset;
8552         guint32 neo;
8553         int fn_len;
8554         const char *fn;
8555         int padcnt;
8556
8557         for (;;) {
8558                 old_offset = offset;
8559
8560                 /* next entry offset */
8561                 CHECK_BYTE_COUNT_SUBR(4);
8562                 if(parent_tree){
8563                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
8564                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
8565                 } else {
8566                         item = NULL;
8567                         tree = NULL;
8568                 }
8569
8570                 neo = tvb_get_letohl(tvb, offset);
8571                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8572                 COUNT_BYTES_SUBR(4);
8573         
8574                 /* stream name len */
8575                 CHECK_BYTE_COUNT_SUBR(4);
8576                 fn_len = tvb_get_letohl(tvb, offset);
8577                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
8578                 COUNT_BYTES_SUBR(4);
8579         
8580                 /* stream size */
8581                 CHECK_BYTE_COUNT_SUBR(8);
8582                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
8583                 COUNT_BYTES_SUBR(8);
8584
8585                 /* allocation size */
8586                 CHECK_BYTE_COUNT_SUBR(8);
8587                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8588                 COUNT_BYTES_SUBR(8);
8589
8590                 /* stream name */
8591                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
8592                 CHECK_STRING_SUBR(fn);
8593                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
8594                         fn);
8595                 COUNT_BYTES_SUBR(fn_len);
8596  
8597                 proto_item_append_text(item, ": %s", fn);
8598                 proto_item_set_len(item, offset-old_offset);
8599
8600                 if (neo == 0)
8601                         break;  /* no more structures */
8602
8603                 /* skip to next structure */
8604                 padcnt = (old_offset + neo) - offset;
8605                 if (padcnt < 0) {
8606                         /*
8607                          * XXX - this is bogus; flag it?
8608                          */
8609                         padcnt = 0;
8610                 }
8611                 if (padcnt != 0) {
8612                         CHECK_BYTE_COUNT_SUBR(padcnt);
8613                         COUNT_BYTES_SUBR(padcnt);
8614                 }
8615         }
8616
8617         *trunc = FALSE;
8618         return offset;
8619 }
8620
8621 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
8622    as described in 4.2.14.11
8623 */
8624 static int
8625 dissect_4_2_14_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
8626     int offset, guint16 *bcp, gboolean *trunc)
8627 {
8628         /* compressed file size */
8629         CHECK_BYTE_COUNT_SUBR(8);
8630         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
8631         COUNT_BYTES_SUBR(8);
8632
8633         /* compression format */
8634         CHECK_BYTE_COUNT_SUBR(2);
8635         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
8636         COUNT_BYTES_SUBR(2);
8637         
8638         /* compression unit shift */
8639         CHECK_BYTE_COUNT_SUBR(1);
8640         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
8641         COUNT_BYTES_SUBR(1);
8642         
8643         /* compression chunk shift */
8644         CHECK_BYTE_COUNT_SUBR(1);
8645         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
8646         COUNT_BYTES_SUBR(1);
8647         
8648         /* compression cluster shift */
8649         CHECK_BYTE_COUNT_SUBR(1);
8650         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
8651         COUNT_BYTES_SUBR(1);
8652         
8653         /* 3 reserved bytes */
8654         CHECK_BYTE_COUNT_SUBR(3);
8655         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8656         COUNT_BYTES_SUBR(3);
8657
8658         *trunc = FALSE;
8659         return offset;
8660 }
8661
8662
8663
8664 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION*/
8665 static int
8666 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
8667     int offset, guint16 *bcp)
8668 {
8669         smb_info_t *si;
8670         smb_transact2_info_t *t2i;
8671         gboolean trunc;
8672
8673         if(!*bcp){
8674                 return offset;
8675         }
8676         
8677         si = (smb_info_t *)pinfo->private_data;
8678         t2i = si->sip->extra_info;
8679         switch(t2i->info_level){
8680         case 1:         /*Info Standard*/
8681         case 2:         /*Info Query EA Size*/
8682                 offset = dissect_4_2_14_1(tvb, pinfo, tree, offset, bcp,
8683                     &trunc);
8684                 break;
8685         case 3:         /*Info Query EAs From List*/
8686         case 4:         /*Info Query All EAs*/
8687                 offset = dissect_4_2_14_2(tvb, pinfo, tree, offset, bcp,
8688                     &trunc);
8689                 break;
8690         case 6:         /*Info Is Name Valid*/
8691                 offset = dissect_4_2_14_3(tvb, pinfo, tree, offset, bcp,
8692                     &trunc);
8693                 break;
8694         case 0x0101:    /*Query File Basic Info*/
8695                 offset = dissect_4_2_14_4(tvb, pinfo, tree, offset, bcp,
8696                     &trunc);
8697                 break;
8698         case 0x0102:    /*Query File Standard Info*/
8699                 offset = dissect_4_2_14_5(tvb, pinfo, tree, offset, bcp,
8700                     &trunc);
8701                 break;
8702         case 0x0103:    /*Query File EA Info*/
8703                 offset = dissect_4_2_14_6(tvb, pinfo, tree, offset, bcp,
8704                     &trunc);
8705                 break;
8706         case 0x0104:    /*Query File Name Info*/
8707                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
8708                     &trunc);
8709                 break;
8710         case 0x0107:    /*Query File All Info*/
8711                 offset = dissect_4_2_14_8(tvb, pinfo, tree, offset, bcp,
8712                     &trunc);
8713                 break;
8714         case 0x0108:    /*Query File Alt File Info*/
8715                 offset = dissect_4_2_14_7(tvb, pinfo, tree, offset, bcp,
8716                     &trunc);
8717                 break;
8718         case 0x0109:    /*Query File Stream Info*/
8719                 offset = dissect_4_2_14_10(tvb, pinfo, tree, offset, bcp,
8720                     &trunc);
8721                 break;
8722         case 0x010b:    /*Query File Compression Info*/
8723                 offset = dissect_4_2_14_11(tvb, pinfo, tree, offset, bcp,
8724                     &trunc);
8725                 break;
8726         case 0x0200:    /*Set File Unix Basic*/
8727                 /* XXX add this from the SNIA doc */
8728                 break;
8729         case 0x0201:    /*Set File Unix Link*/
8730                 /* XXX add this from the SNIA doc */
8731                 break;
8732         case 0x0202:    /*Set File Unix HardLink*/
8733                 /* XXX add this from the SNIA doc */
8734                 break;
8735         }
8736         
8737         return offset;
8738 }
8739
8740
8741 static int
8742 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
8743     proto_tree *parent_tree, int offset, guint16 dc)
8744 {
8745         proto_item *item = NULL;
8746         proto_tree *tree = NULL;
8747         smb_info_t *si;
8748         smb_transact2_info_t *t2i;
8749         int fn_len;
8750         const char *fn;
8751         int old_offset = offset;
8752
8753         si = (smb_info_t *)pinfo->private_data;
8754         t2i = si->sip->extra_info;
8755
8756         if(parent_tree){
8757                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
8758                                 "%s Data",
8759                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
8760                                                 "Unknown (0x%02x)"));
8761                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
8762         }
8763
8764         switch(t2i->subcmd){
8765         case 0x00:      /*TRANS2_OPEN2*/
8766                 /* XXX FAEList here?*/
8767                 break;
8768         case 0x01:      /*TRANS2_FIND_FIRST2*/
8769                 /* XXX FAEList here?*/
8770                 break;
8771         case 0x02:      /*TRANS2_FIND_NEXT2*/
8772                 /* no data field in this request */
8773                 break;
8774         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
8775                 /* no data field in this request */
8776                 break;
8777         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
8778                 /* no data field in this request */
8779                 break;
8780         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
8781                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
8782                 break;
8783         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
8784                 /* no data field in this request */
8785                 break;
8786         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
8787                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
8788                 break;
8789         case 0x09:      /*TRANS2_FSCTL*/
8790                 /*XXX dont know how to decode this yet */
8791                 break;
8792         case 0x0a:      /*TRANS2_IOCTL2*/
8793                 /*XXX dont know how to decode this yet */
8794                 break;
8795         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
8796                 /*XXX dont know how to decode this yet */
8797                 break;
8798         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
8799                 /*XXX dont know how to decode this yet */
8800                 break;
8801         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
8802                 /* no data block for this one */
8803                 break;
8804         case 0x0e:      /*TRANS2_SESSION_SETUP*/
8805                 /*XXX dont know how to decode this yet */
8806                 break;
8807         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
8808                 /* no data field in this request */
8809                 break;
8810         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
8811                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
8812                 break;
8813         }
8814
8815         /* ooops there were data we didnt know how to process */
8816         if(dc != 0){
8817                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
8818                 offset += dc;
8819         }
8820
8821         return offset;
8822 }
8823
8824
8825 static void
8826 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
8827     packet_info *pinfo, proto_tree *tree)
8828 {
8829         int i;
8830         int offset;
8831         guint length;
8832
8833         /*
8834          * Show the setup words.
8835          */
8836         if (s_tvb != NULL) {
8837                 length = tvb_length(s_tvb);
8838                 for (i = 0, offset = 0; length >= 2;
8839                     i++, offset += 2, length -= 2) {
8840                         /*
8841                          * XXX - add a setup word filterable field?
8842                          */
8843                         proto_tree_add_text(tree, s_tvb, offset, 2,
8844                             "Setup Word %d: 0x%04x", i,
8845                             tvb_get_letohs(s_tvb, offset));
8846                 }
8847         }
8848
8849         /*
8850          * Show the parameters, if any.
8851          */
8852         if (p_tvb != NULL) {
8853                 length = tvb_length(p_tvb);
8854                 if (length != 0) {
8855                         proto_tree_add_text(tree, p_tvb, 0, length,
8856                             "Parameters: %s",
8857                             tvb_bytes_to_str(p_tvb, 0, length));
8858                 }
8859         }
8860
8861         /*
8862          * Show the data, if any.
8863          */
8864         if (d_tvb != NULL) {
8865                 length = tvb_length(d_tvb);
8866                 if (length != 0) {
8867                         proto_tree_add_text(tree, d_tvb, 0, length,
8868                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
8869                 }
8870         }
8871 }
8872
8873 static int
8874 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
8875 {
8876         guint8 wc, sc=0;
8877         int so=offset;
8878         int sl=0;
8879         int spo=offset;
8880         int spc=0;
8881         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
8882         guint16 subcmd;
8883         guint32 to;
8884         int an_len;
8885         const char *an = NULL;
8886         smb_info_t *si;
8887         smb_transact2_info_t *t2i;
8888         smb_transact_info_t *tri;
8889         guint16 bc;
8890         int padcnt;
8891         gboolean dissected_trans;
8892
8893         si = (smb_info_t *)pinfo->private_data;
8894
8895         WORD_COUNT;
8896
8897         if(wc==8){
8898                 /*secondary client request*/
8899
8900                 /* total param count, only a 16bit integer here*/
8901                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
8902                 offset += 2;
8903         
8904                 /* total data count , only 16bit integer here*/
8905                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
8906                 offset += 2;
8907
8908                 /* param count */
8909                 pc = tvb_get_letohs(tvb, offset);
8910                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
8911                 offset += 2;
8912
8913                 /* param offset */
8914                 po = tvb_get_letohs(tvb, offset);
8915                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
8916                 offset += 2;
8917
8918                 /* param disp */
8919                 pd = tvb_get_letohs(tvb, offset);
8920                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
8921                 offset += 2;
8922         
8923                 /* data count */
8924                 dc = tvb_get_letohs(tvb, offset);
8925                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
8926                 offset += 2;
8927
8928                 /* data offset */
8929                 od = tvb_get_letohs(tvb, offset);
8930                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
8931                 offset += 2;
8932         
8933                 /* data disp */
8934                 dd = tvb_get_letohs(tvb, offset);
8935                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
8936                 offset += 2;
8937
8938                 if(si->cmd==0x32){
8939                         /* fid */
8940                         proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
8941                         offset += 2;
8942                 }
8943
8944                 /* There are no setup words. */
8945                 so = offset;
8946                 sc = 0;
8947                 sl = 0;
8948         } else {
8949                 /* it is not a secondary request */
8950
8951                 /* total param count , only a 16 bit integer here*/
8952                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
8953                 offset += 2;
8954
8955                 /* total data count , only 16bit integer here*/
8956                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
8957                 offset += 2;
8958
8959                 /* max param count , only 16bit integer here*/
8960                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
8961                 offset += 2;
8962
8963                 /* max data count, only 16bit integer here*/
8964                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
8965                 offset += 2;
8966
8967                 /* max setup count, only 16bit integer here*/
8968                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
8969                 offset += 1;
8970
8971                 /* reserved byte */
8972                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8973                 offset += 1;
8974
8975                 /* transaction flags */
8976                 tf = dissect_transaction_flags(tvb, pinfo, tree, offset);
8977                 offset += 2;
8978
8979                 /* timeout */
8980                 to = tvb_get_letohl(tvb, offset);
8981                 if (to == 0)
8982                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
8983                 else if (to == 0xffffffff)
8984                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
8985                 else
8986                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
8987                 offset += 4;
8988
8989                 /* 2 reserved bytes */
8990                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8991                 offset += 2;
8992
8993                 /* param count */
8994                 pc = tvb_get_letohs(tvb, offset);
8995                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
8996                 offset += 2;
8997         
8998                 /* param offset */
8999                 po = tvb_get_letohs(tvb, offset);
9000                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
9001                 offset += 2;
9002
9003                 /* data count */
9004                 dc = tvb_get_letohs(tvb, offset);
9005                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
9006                 offset += 2;
9007
9008                 /* data offset */
9009                 od = tvb_get_letohs(tvb, offset);
9010                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
9011                 offset += 2;
9012
9013                 /* data displacement is zero here */
9014                 dd = 0;
9015
9016                 /* setup count */
9017                 sc = tvb_get_guint8(tvb, offset);
9018                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
9019                 offset += 1;
9020
9021                 /* reserved byte */
9022                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9023                 offset += 1;
9024                 
9025                 /* this is where the setup bytes, if any start */       
9026                 so = offset;
9027                 sl = sc*2;
9028
9029                 /* if there were any setup bytes, decode them */
9030                 if(sc){
9031                         switch(si->cmd){
9032
9033                         case 0x32:
9034                                 if (!si->unidir) {
9035                                         if(!pinfo->fd->flags.visited){
9036                                                 /* 
9037                                                  * Allocate a new
9038                                                  * smb_transact2_info_t
9039                                                  * structure.
9040                                                  */
9041                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
9042                                                 t2i->subcmd = -1;
9043                                                 t2i->info_level = -1;
9044                                                 si->sip->extra_info = t2i;
9045                                         } else
9046                                                 t2i = si->sip->extra_info;
9047                                 } else {
9048                                         /*
9049                                          * This is a unidirectional message,
9050                                          * for which there will be no reply;
9051                                          * don't bother allocating an
9052                                          * "smb_transact2_info_t"
9053                                          * structure for it.
9054                                          */
9055                                         t2i = NULL;
9056                                 }
9057                                 /* TRANSACTION2 only has one setup word and
9058                                    that is the subcommand code. */
9059                                 subcmd = tvb_get_letohs(tvb, offset);
9060                                 if (!si->unidir)
9061                                         t2i->subcmd = subcmd;
9062                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
9063                                     tvb, offset, 2, subcmd);
9064
9065                                 if (check_col(pinfo->fd, COL_INFO)) {
9066                                         col_append_fstr(pinfo->fd, COL_INFO, " %s",
9067                                             val_to_str(subcmd, trans2_cmd_vals, 
9068                                                 "Unknown (0x%02x)"));
9069                                 }
9070                                 break;
9071
9072                         case 0x25:
9073                                 /* TRANSACTION setup words processed below */
9074                                 break;
9075                         }
9076
9077                         offset += sl;
9078                 }
9079         }
9080
9081         BYTE_COUNT;
9082         
9083         if(wc!=8){
9084                 /* primary request */
9085                 /* name is NULL if transaction2 */
9086                 if(si->cmd == 0x25){
9087                         /* Transaction Name */
9088                         an = get_unicode_or_ascii_string(tvb, &offset,
9089                                 pinfo, &an_len, FALSE, FALSE, &bc);
9090                         if (an == NULL)
9091                                 goto endofcommand;
9092                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
9093                                 offset, an_len, an);
9094                         COUNT_BYTES(an_len);
9095                 }
9096         }
9097
9098         /*
9099          * The pipe or mailslot arguments for Transaction start with
9100          * the first setup word (or where the first setup word would
9101          * be if there were any setup words), and run to the current
9102          * offset (which could mean that there aren't any).
9103          */
9104         spo = so;
9105         spc = offset - spo;
9106
9107         /* parameters */
9108         if(po>offset){
9109                 /* We have some initial padding bytes.
9110                 */
9111                 padcnt = po-offset;
9112                 if (padcnt > bc)
9113                         padcnt = bc;
9114                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9115                 COUNT_BYTES(padcnt);
9116         }
9117         if(pc){
9118                 CHECK_BYTE_COUNT(pc);
9119                 switch(si->cmd) {
9120
9121                 case 0x32:
9122                         /* TRANSACTION2 parameters*/
9123                         offset = dissect_transaction2_request_parameters(tvb,
9124                             pinfo, tree, offset, pc);
9125                         bc -= pc;
9126                         break;
9127
9128                 case 0x25:
9129                         /* TRANSACTION parameters processed below */
9130                         COUNT_BYTES(pc);
9131                         break;
9132                 }
9133         }
9134
9135         /* data */
9136         if(od>offset){
9137                 /* We have some initial padding bytes.
9138                 */
9139                 padcnt = od-offset;
9140                 if (padcnt > bc)
9141                         padcnt = bc;
9142                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9143                 COUNT_BYTES(padcnt);
9144         }
9145         if(dc){
9146                 CHECK_BYTE_COUNT(dc);
9147                 switch(si->cmd){
9148
9149                 case 0x32:
9150                         /* TRANSACTION2 data*/
9151                         offset = dissect_transaction2_request_data(tvb, pinfo,
9152                             tree, offset, dc);
9153                         bc -= dc;
9154                         break;
9155
9156                 case 0x25:
9157                         /* TRANSACTION data processed below */
9158                         COUNT_BYTES(dc);
9159                         break;
9160                 }
9161         }
9162
9163         /*TRANSACTION request parameters */
9164         if(si->cmd==0x25){
9165                 /*XXX replace this block with a function and use that one 
9166                      for both requests/responses*/
9167                 if(dd==0){
9168                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
9169                         tvbuff_t *sp_tvb, *pd_tvb;
9170
9171                         if(pc>0){
9172                                 if(pc>tvb_length_remaining(tvb, po)){
9173                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
9174                                 } else {
9175                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
9176                                 }
9177                         } else {
9178                                 p_tvb = NULL;
9179                         }
9180                         if(dc>0){
9181                                 if(dc>tvb_length_remaining(tvb, od)){
9182                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
9183                                 } else {
9184                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
9185                                 }
9186                         } else {
9187                                 d_tvb = NULL;
9188                         }
9189                         if(sl){
9190                                 if(sl>tvb_length_remaining(tvb, so)){
9191                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
9192                                 } else {
9193                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
9194                                 }
9195                         } else {
9196                                 s_tvb = NULL;
9197                         }
9198
9199                         if (!si->unidir) {
9200                                 if(!pinfo->fd->flags.visited){
9201                                         /* 
9202                                          * Allocate a new smb_transact_info_t
9203                                          * structure.
9204                                          */
9205                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
9206                                         tri->subcmd = -1;
9207                                         tri->lanman_cmd = 0;
9208                                         tri->param_descrip = NULL;
9209                                         tri->data_descrip = NULL;
9210                                         tri->aux_data_descrip = NULL;
9211                                         tri->info_level = -1;
9212                                         si->sip->extra_info = tri;
9213                                 } else
9214                                         tri = si->sip->extra_info;
9215                         } else {
9216                                 /*
9217                                  * This is a unidirectional message, for
9218                                  * which there will be no reply; don't
9219                                  * bother allocating an "smb_transact_info_t"
9220                                  * structure for it.
9221                                  */
9222                                 tri = NULL;
9223                         }
9224                         dissected_trans = FALSE;
9225                         if(strncmp("\\PIPE\\", an, 6) == 0){
9226                                 if (!si->unidir)
9227                                         tri->subcmd=TRANSACTION_PIPE;
9228
9229                                 /*
9230                                  * A tvbuff containing the setup words and
9231                                  * the pipe path.
9232                                  */
9233                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
9234
9235                                 /*
9236                                  * A tvbuff containing the parameters and the
9237                                  * data.
9238                                  */
9239                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
9240
9241                                 dissected_trans = dissect_pipe_smb(sp_tvb,
9242                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
9243                                     top_tree);
9244                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
9245                                 if (!si->unidir)
9246                                         tri->subcmd=TRANSACTION_MAILSLOT;
9247
9248                                 /*
9249                                  * A tvbuff containing the setup words and
9250                                  * the mailslot path.
9251                                  */
9252                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
9253                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
9254                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
9255                         }
9256                         if (!dissected_trans) {
9257                                 dissect_trans_data(s_tvb, p_tvb, d_tvb,
9258                                     pinfo, tree);
9259                         }
9260                 } else {
9261                         if(check_col(pinfo->fd, COL_INFO)){
9262                                 col_append_str(pinfo->fd, COL_INFO,
9263                                         "[transact continuation]");
9264                         }
9265                 }
9266         }
9267
9268         END_OF_SMB
9269
9270         return offset;
9271 }
9272
9273 /*qqq*/
9274
9275  
9276
9277 static int
9278 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9279     int offset, guint16 *bcp, gboolean *trunc)
9280 {
9281         int fn_len;
9282         const char *fn;
9283         int old_offset = offset;
9284         proto_item *item = NULL;
9285         proto_tree *tree = NULL;
9286         smb_info_t *si;
9287         smb_transact2_info_t *t2i;
9288
9289         si = (smb_info_t *)pinfo->private_data;
9290         t2i = si->sip->extra_info;
9291
9292         if(parent_tree){
9293                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
9294                     val_to_str(t2i->info_level, ff2_il_vals, "Unknown (0x%02x)"));
9295                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9296         }
9297
9298         /* create time */
9299         CHECK_BYTE_COUNT_SUBR(4);
9300         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9301                 hf_smb_create_time,
9302                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
9303         *bcp -= 4;
9304
9305         /* access time */
9306         CHECK_BYTE_COUNT_SUBR(4);
9307         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9308                 hf_smb_access_time,
9309                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
9310         *bcp -= 4;
9311
9312         /* last write time */
9313         CHECK_BYTE_COUNT_SUBR(4);
9314         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9315                 hf_smb_last_write_time,
9316                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
9317         *bcp -= 4;
9318
9319         /* data size */
9320         CHECK_BYTE_COUNT_SUBR(4);
9321         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
9322         COUNT_BYTES_SUBR(4);
9323
9324         /* allocation size */
9325         CHECK_BYTE_COUNT_SUBR(4);
9326         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9327         COUNT_BYTES_SUBR(4);
9328
9329         /* File Attributes */
9330         CHECK_BYTE_COUNT_SUBR(2);
9331         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9332         *bcp -= 2;
9333
9334         /* file name len */
9335         CHECK_BYTE_COUNT_SUBR(1);
9336         fn_len = tvb_get_guint8(tvb, offset);
9337         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
9338         COUNT_BYTES_SUBR(1);
9339
9340         /* file name */
9341         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9342         CHECK_STRING_SUBR(fn);
9343         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9344                 fn);
9345         COUNT_BYTES_SUBR(fn_len);
9346
9347         if (check_col(pinfo->fd, COL_INFO)) {
9348                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
9349                 fn);
9350         }
9351  
9352         proto_item_append_text(item, " File: %s", fn);
9353         proto_item_set_len(item, offset-old_offset);
9354
9355         *trunc = FALSE;
9356         return offset;
9357 }
9358
9359 static int
9360 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9361     int offset, guint16 *bcp, gboolean *trunc)
9362 {
9363         int fn_len;
9364         const char *fn;
9365         int old_offset = offset;
9366         proto_item *item = NULL;
9367         proto_tree *tree = NULL;
9368         smb_info_t *si;
9369         smb_transact2_info_t *t2i;
9370
9371         si = (smb_info_t *)pinfo->private_data;
9372         t2i = si->sip->extra_info;
9373
9374         if(parent_tree){
9375                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
9376                     val_to_str(t2i->info_level, ff2_il_vals, "Unknown (0x%02x)"));
9377                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9378         }
9379  
9380         /* create time */
9381         CHECK_BYTE_COUNT_SUBR(4);
9382         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9383                 hf_smb_create_time,
9384                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
9385         *bcp -= 4;
9386
9387         /* access time */
9388         CHECK_BYTE_COUNT_SUBR(4);
9389         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9390                 hf_smb_access_time,
9391                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
9392         *bcp -= 4;
9393
9394         /* last write time */
9395         CHECK_BYTE_COUNT_SUBR(4);
9396         offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
9397                 hf_smb_last_write_time,
9398                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
9399         *bcp -= 4;
9400
9401         /* data size */
9402         CHECK_BYTE_COUNT_SUBR(4);
9403         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
9404         COUNT_BYTES_SUBR(4);
9405
9406         /* allocation size */
9407         CHECK_BYTE_COUNT_SUBR(4);
9408         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
9409         COUNT_BYTES_SUBR(4);
9410
9411         /* File Attributes */
9412         CHECK_BYTE_COUNT_SUBR(2);
9413         offset = dissect_file_attributes(tvb, pinfo, tree, offset);
9414         *bcp -= 2;
9415
9416         /* ea size */
9417         CHECK_BYTE_COUNT_SUBR(4);
9418         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9419         COUNT_BYTES_SUBR(4);
9420
9421         /* file name len */
9422         CHECK_BYTE_COUNT_SUBR(1);
9423         fn_len = tvb_get_guint8(tvb, offset);
9424         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
9425         COUNT_BYTES_SUBR(1);
9426
9427         /* file name */
9428         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9429         CHECK_STRING_SUBR(fn);
9430         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9431                 fn);
9432         COUNT_BYTES_SUBR(fn_len);
9433
9434         if (check_col(pinfo->fd, COL_INFO)) {
9435                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
9436                 fn);
9437         }
9438
9439         proto_item_append_text(item, " File: %s", fn);
9440         proto_item_set_len(item, offset-old_offset);
9441
9442         *trunc = FALSE;
9443         return offset;
9444 }
9445
9446 static int
9447 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9448     int offset, guint16 *bcp, gboolean *trunc)
9449 {
9450         int fn_len;
9451         const char *fn;
9452         int old_offset = offset;
9453         proto_item *item = NULL;
9454         proto_tree *tree = NULL;
9455         smb_info_t *si;
9456         smb_transact2_info_t *t2i;
9457         guint32 neo;
9458         int padcnt;
9459
9460         si = (smb_info_t *)pinfo->private_data;
9461         t2i = si->sip->extra_info;
9462
9463         if(parent_tree){
9464                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
9465                     val_to_str(t2i->info_level, ff2_il_vals, "Unknown (0x%02x)"));
9466                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9467         }
9468
9469         /* next entry offset */
9470         CHECK_BYTE_COUNT_SUBR(4);
9471         neo = tvb_get_letohl(tvb, offset);
9472         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9473         COUNT_BYTES_SUBR(4);
9474         
9475         /* file index */
9476         CHECK_BYTE_COUNT_SUBR(4);
9477         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
9478         COUNT_BYTES_SUBR(4);
9479
9480         /* create time */
9481         CHECK_BYTE_COUNT_SUBR(8);
9482         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9483                 "Create Time", hf_smb_create_time);
9484         *bcp -= 8;
9485         
9486         /* access time */
9487         CHECK_BYTE_COUNT_SUBR(8);
9488         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9489                 "Access Time", hf_smb_access_time);
9490         *bcp -= 8;
9491         
9492         /* last write time */
9493         CHECK_BYTE_COUNT_SUBR(8);
9494         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9495                 "Write Time", hf_smb_last_write_time);
9496         *bcp -= 8;
9497         
9498         /* last change time */
9499         CHECK_BYTE_COUNT_SUBR(8);
9500         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9501                 "Change Time", hf_smb_change_time);
9502         *bcp -= 8;
9503         
9504         /* end of file */
9505         CHECK_BYTE_COUNT_SUBR(8);
9506         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9507         COUNT_BYTES_SUBR(8);
9508
9509         /* allocation size */
9510         CHECK_BYTE_COUNT_SUBR(8);
9511         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9512         COUNT_BYTES_SUBR(8);
9513
9514         /* Extended File Attributes */
9515         CHECK_BYTE_COUNT_SUBR(4);
9516         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
9517         *bcp -= 4;
9518
9519         /* file name len */
9520         CHECK_BYTE_COUNT_SUBR(4);
9521         fn_len = tvb_get_letohl(tvb, offset);
9522         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9523         COUNT_BYTES_SUBR(4);
9524
9525         /* file name */
9526         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9527         CHECK_STRING_SUBR(fn);
9528         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9529                 fn);
9530         COUNT_BYTES_SUBR(fn_len);
9531
9532         if (check_col(pinfo->fd, COL_INFO)) {
9533                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
9534                 fn);
9535         }
9536
9537         /* skip to next structure */
9538         if(neo){
9539                 padcnt = (old_offset + neo) - offset;
9540                 if (padcnt < 0) {
9541                         /*
9542                          * XXX - this is bogus; flag it?
9543                          */
9544                         padcnt = 0;
9545                 }
9546                 if (padcnt != 0) {
9547                         CHECK_BYTE_COUNT_SUBR(padcnt);
9548                         COUNT_BYTES_SUBR(padcnt);
9549                 }
9550         }
9551
9552         proto_item_append_text(item, " File: %s", fn);
9553         proto_item_set_len(item, offset-old_offset);
9554
9555         *trunc = FALSE;
9556         return offset;
9557 }
9558
9559 static int
9560 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9561     int offset, guint16 *bcp, gboolean *trunc)
9562 {
9563         int fn_len;
9564         const char *fn;
9565         int old_offset = offset;
9566         proto_item *item = NULL;
9567         proto_tree *tree = NULL;
9568         smb_info_t *si;
9569         smb_transact2_info_t *t2i;
9570         guint32 neo;
9571         int padcnt;
9572
9573         si = (smb_info_t *)pinfo->private_data;
9574         t2i = si->sip->extra_info;
9575
9576         if(parent_tree){
9577                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
9578                     val_to_str(t2i->info_level, ff2_il_vals, "Unknown (0x%02x)"));
9579                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9580         }
9581
9582         /* next entry offset */
9583         CHECK_BYTE_COUNT_SUBR(4);
9584         neo = tvb_get_letohl(tvb, offset);
9585         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9586         COUNT_BYTES_SUBR(4);
9587         
9588         /* file index */
9589         CHECK_BYTE_COUNT_SUBR(4);
9590         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
9591         COUNT_BYTES_SUBR(4);
9592
9593         /* create time */
9594         CHECK_BYTE_COUNT_SUBR(8);
9595         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9596                 "Create Time", hf_smb_create_time);
9597         *bcp -= 8;
9598         
9599         /* access time */
9600         CHECK_BYTE_COUNT_SUBR(8);
9601         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9602                 "Access Time", hf_smb_access_time);
9603         *bcp -= 8;
9604         
9605         /* last write time */
9606         CHECK_BYTE_COUNT_SUBR(8);
9607         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9608                 "Write Time", hf_smb_last_write_time);
9609         *bcp -= 8;
9610         
9611         /* last change time */
9612         CHECK_BYTE_COUNT_SUBR(8);
9613         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9614                 "Change Time", hf_smb_change_time);
9615         *bcp -= 8;
9616         
9617         /* end of file */
9618         CHECK_BYTE_COUNT_SUBR(8);
9619         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9620         COUNT_BYTES_SUBR(8);
9621
9622         /* allocation size */
9623         CHECK_BYTE_COUNT_SUBR(8);
9624         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9625         COUNT_BYTES_SUBR(8);
9626
9627         /* Extended File Attributes */
9628         CHECK_BYTE_COUNT_SUBR(4);
9629         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
9630         *bcp -= 4;
9631
9632         /* file name len */
9633         CHECK_BYTE_COUNT_SUBR(4);
9634         fn_len = tvb_get_letohl(tvb, offset);
9635         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9636         COUNT_BYTES_SUBR(4);
9637
9638         /* ea size */
9639         CHECK_BYTE_COUNT_SUBR(4);
9640         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9641         COUNT_BYTES_SUBR(4);
9642
9643         /* file name */
9644         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9645         CHECK_STRING_SUBR(fn);
9646         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9647                 fn);
9648         COUNT_BYTES_SUBR(fn_len);
9649
9650         if (check_col(pinfo->fd, COL_INFO)) {
9651                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
9652                 fn);
9653         }
9654
9655         /* skip to next structure */
9656         if(neo){
9657                 padcnt = (old_offset + neo) - offset;
9658                 if (padcnt < 0) {
9659                         /*
9660                          * XXX - this is bogus; flag it?
9661                          */
9662                         padcnt = 0;
9663                 }
9664                 if (padcnt != 0) {
9665                         CHECK_BYTE_COUNT_SUBR(padcnt);
9666                         COUNT_BYTES_SUBR(padcnt);
9667                 }
9668         }
9669
9670         proto_item_append_text(item, " File: %s", fn);
9671         proto_item_set_len(item, offset-old_offset);
9672
9673         *trunc = FALSE;
9674         return offset;
9675 }
9676
9677 static int
9678 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9679     int offset, guint16 *bcp, gboolean *trunc)
9680 {
9681         int fn_len, sfn_len;
9682         const char *fn, *sfn;
9683         int old_offset = offset;
9684         proto_item *item = NULL;
9685         proto_tree *tree = NULL;
9686         smb_info_t *si;
9687         smb_transact2_info_t *t2i;
9688         guint32 neo;
9689         int padcnt;
9690
9691         si = (smb_info_t *)pinfo->private_data;
9692         t2i = si->sip->extra_info;
9693
9694         if(parent_tree){
9695                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
9696                     val_to_str(t2i->info_level, ff2_il_vals, "Unknown (0x%02x)"));
9697                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9698         }
9699
9700         /* next entry offset */
9701         CHECK_BYTE_COUNT_SUBR(4);
9702         neo = tvb_get_letohl(tvb, offset);
9703         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9704         COUNT_BYTES_SUBR(4);
9705         
9706         /* file index */
9707         CHECK_BYTE_COUNT_SUBR(4);
9708         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
9709         COUNT_BYTES_SUBR(4);
9710
9711         /* create time */
9712         CHECK_BYTE_COUNT_SUBR(8);
9713         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9714                 "Create Time", hf_smb_create_time);
9715         *bcp -= 8;
9716         
9717         /* access time */
9718         CHECK_BYTE_COUNT_SUBR(8);
9719         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9720                 "Access Time", hf_smb_access_time);
9721         *bcp -= 8;
9722         
9723         /* last write time */
9724         CHECK_BYTE_COUNT_SUBR(8);
9725         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9726                 "Write Time", hf_smb_last_write_time);
9727         *bcp -= 8;
9728         
9729         /* last change time */
9730         CHECK_BYTE_COUNT_SUBR(8);
9731         offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
9732                 "Change Time", hf_smb_change_time);
9733         *bcp -= 8;
9734         
9735         /* end of file */
9736         CHECK_BYTE_COUNT_SUBR(8);
9737         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9738         COUNT_BYTES_SUBR(8);
9739
9740         /* allocation size */
9741         CHECK_BYTE_COUNT_SUBR(8);
9742         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9743         COUNT_BYTES_SUBR(8);
9744
9745         /* Extended File Attributes */
9746         CHECK_BYTE_COUNT_SUBR(4);
9747         offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
9748         *bcp -= 4;
9749
9750         /* file name len */
9751         CHECK_BYTE_COUNT_SUBR(4);
9752         fn_len = tvb_get_letohl(tvb, offset);
9753         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9754         COUNT_BYTES_SUBR(4);
9755
9756         /* ea size */
9757         CHECK_BYTE_COUNT_SUBR(4);
9758         proto_tree_add_item(tree, hf_smb_ea_size, tvb, offset, 4, TRUE);
9759         COUNT_BYTES_SUBR(4);
9760
9761         /* short file name len */
9762         CHECK_BYTE_COUNT_SUBR(1);
9763         sfn_len = tvb_get_guint8(tvb, offset);
9764         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
9765         COUNT_BYTES_SUBR(1);
9766
9767         /* reserved byte */
9768         CHECK_BYTE_COUNT_SUBR(1);
9769         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9770         COUNT_BYTES_SUBR(1);
9771  
9772         /* short file name */
9773         sfn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &sfn_len, FALSE, TRUE, bcp);
9774         CHECK_STRING_SUBR(sfn);
9775         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
9776                 sfn);
9777         COUNT_BYTES_SUBR(24);
9778
9779         /* file name */
9780         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9781         CHECK_STRING_SUBR(fn);
9782         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9783                 fn);
9784         COUNT_BYTES_SUBR(fn_len);
9785
9786         if (check_col(pinfo->fd, COL_INFO)) {
9787                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
9788                 fn);
9789         }
9790
9791         /* skip to next structure */
9792         if(neo){
9793                 padcnt = (old_offset + neo) - offset;
9794                 if (padcnt < 0) {
9795                         /*
9796                          * XXX - this is bogus; flag it?
9797                          */
9798                         padcnt = 0;
9799                 }
9800                 if (padcnt != 0) {
9801                         CHECK_BYTE_COUNT_SUBR(padcnt);
9802                         COUNT_BYTES_SUBR(padcnt);
9803                 }
9804         }
9805
9806         proto_item_append_text(item, " File: %s", fn);
9807         proto_item_set_len(item, offset-old_offset);
9808
9809         *trunc = FALSE;
9810         return offset;
9811 }
9812
9813 static int
9814 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9815     int offset, guint16 *bcp, gboolean *trunc)
9816 {
9817         int fn_len, sfn_len;
9818         const char *fn, *sfn;
9819         int old_offset = offset;
9820         proto_item *item = NULL;
9821         proto_tree *tree = NULL;
9822         smb_info_t *si;
9823         smb_transact2_info_t *t2i;
9824         guint32 neo;
9825         int padcnt;
9826
9827         si = (smb_info_t *)pinfo->private_data;
9828         t2i = si->sip->extra_info;
9829
9830         if(parent_tree){
9831                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
9832                     val_to_str(t2i->info_level, ff2_il_vals, "Unknown (0x%02x)"));
9833                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
9834         }
9835  
9836         /* next entry offset */
9837         CHECK_BYTE_COUNT_SUBR(4);
9838         neo = tvb_get_letohl(tvb, offset);
9839         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
9840         COUNT_BYTES_SUBR(4);
9841         
9842         /* file index */
9843         CHECK_BYTE_COUNT_SUBR(4);
9844         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
9845         COUNT_BYTES_SUBR(4);
9846
9847         /* file name len */
9848         CHECK_BYTE_COUNT_SUBR(4);
9849         fn_len = tvb_get_letohl(tvb, offset);
9850         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
9851         COUNT_BYTES_SUBR(4);
9852
9853         /* file name */
9854         fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
9855         CHECK_STRING_SUBR(fn);
9856         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9857                 fn);
9858         COUNT_BYTES_SUBR(fn_len);
9859
9860         if (check_col(pinfo->fd, COL_INFO)) {
9861                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
9862                 fn);
9863         }
9864
9865         /* skip to next structure */
9866         if(neo){
9867                 padcnt = (old_offset + neo) - offset;
9868                 if (padcnt < 0) {
9869                         /*
9870                          * XXX - this is bogus; flag it?
9871                          */
9872                         padcnt = 0;
9873                 }
9874                 if (padcnt != 0) {
9875                         CHECK_BYTE_COUNT_SUBR(padcnt);
9876                         COUNT_BYTES_SUBR(padcnt);
9877                 }
9878         }
9879
9880         proto_item_append_text(item, " File: %s", fn);
9881         proto_item_set_len(item, offset-old_offset);
9882
9883         *trunc = FALSE;
9884         return offset;
9885 }
9886  
9887 static int
9888 dissect_4_3_4_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
9889     int offset, guint16 *bcp, gboolean *trunc)
9890 {
9891 /*XXX im lazy. i havnt implemented this */
9892         offset += *bcp;
9893         *bcp = 0;
9894         *trunc = FALSE;
9895         return offset;
9896 }
9897
9898 /*dissect the data block for TRANS2_FIND_FIRST2*/
9899 static int
9900 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
9901     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
9902 {
9903         smb_info_t *si;
9904         smb_transact2_info_t *t2i;
9905
9906         if(!*bcp){
9907                 return offset;
9908         }
9909         
9910         si = (smb_info_t *)pinfo->private_data;
9911         t2i = si->sip->extra_info;
9912         switch(t2i->info_level){
9913         case 1:         /*Info Standard*/
9914                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
9915                     trunc);
9916                 break;
9917         case 2:         /*Info Query EA Size*/
9918                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
9919                     trunc);
9920                 break;
9921         case 3:         /*Info Query EAs From List same as 
9922                                 InfoQueryEASize*/
9923                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
9924                     trunc);
9925                 break;
9926         case 0x0101:    /*Find File Directory Info*/
9927                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
9928                     trunc);
9929                 break;
9930         case 0x0102:    /*Find File Full Directory Info*/
9931                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
9932                     trunc);
9933                 break;
9934         case 0x0103:    /*Find File Names Info*/
9935                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
9936                     trunc);
9937                 break;
9938         case 0x0104:    /*Find File Both Directory Info*/
9939                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
9940                     trunc);
9941                 break;
9942         case 0x0202:    /*Find File UNIX*/
9943                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
9944                     trunc);
9945                 break;
9946         default:        /* unknown info level */
9947                 *trunc = FALSE;
9948                 break;
9949         }
9950         return offset;
9951 }
9952
9953
9954 static int
9955 dissect_fs_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9956 {
9957         guint32 mask;
9958         proto_item *item = NULL;
9959         proto_tree *tree = NULL;
9960
9961         mask = tvb_get_letohl(tvb, offset);
9962
9963         if(parent_tree){
9964                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
9965                         "FS Attributes: 0x%08x", mask);
9966                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
9967         }
9968
9969         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
9970                 tvb, offset, 4, mask);
9971         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
9972                 tvb, offset, 4, mask);
9973         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
9974                 tvb, offset, 4, mask);
9975         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
9976                 tvb, offset, 4, mask);
9977         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
9978                 tvb, offset, 4, mask);
9979         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
9980                 tvb, offset, 4, mask);
9981         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
9982                 tvb, offset, 4, mask);
9983
9984         offset += 4;
9985         return offset;
9986 }
9987  
9988
9989 static int
9990 dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9991 {
9992         guint32 mask;
9993         proto_item *item = NULL;
9994         proto_tree *tree = NULL;
9995
9996         mask = tvb_get_letohl(tvb, offset);
9997
9998         if(parent_tree){
9999                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
10000                         "Device Characteristics: 0x%08x", mask);
10001                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
10002         }
10003
10004         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
10005                 tvb, offset, 4, mask);
10006         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
10007                 tvb, offset, 4, mask);
10008         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
10009                 tvb, offset, 4, mask);
10010         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
10011                 tvb, offset, 4, mask);
10012         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
10013                 tvb, offset, 4, mask);
10014         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
10015                 tvb, offset, 4, mask);
10016         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
10017                 tvb, offset, 4, mask);
10018
10019         offset += 4;
10020         return offset;
10021 }
10022
10023
10024 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
10025 static int
10026 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
10027     int offset, guint16 *bcp)
10028 {
10029         smb_info_t *si;
10030         smb_transact2_info_t *t2i;
10031         int fn_len, vll, fnl;
10032         const char *fn;
10033
10034         if(!*bcp){
10035                 return offset;
10036         }
10037         
10038         si = (smb_info_t *)pinfo->private_data;
10039         t2i = si->sip->extra_info;
10040         switch(t2i->info_level){
10041         case 1:         /* SMB_INFO_ALLOCATION */
10042                 /* filesystem id */
10043                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10044                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
10045                 COUNT_BYTES_TRANS_SUBR(4);
10046
10047                 /* sectors per unit */
10048                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10049                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
10050                 COUNT_BYTES_TRANS_SUBR(4);
10051
10052                 /* units */
10053                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10054                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
10055                 COUNT_BYTES_TRANS_SUBR(4);
10056
10057                 /* avail units */
10058                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10059                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
10060                 COUNT_BYTES_TRANS_SUBR(4);
10061
10062                 /* bytes per sector, only 16bit integer here */
10063                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10064                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10065                 COUNT_BYTES_TRANS_SUBR(2);
10066
10067                 break;
10068         case 2:         /* SMB_INFO_VOLUME */
10069                 /* volume serial number */
10070                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10071                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
10072                 COUNT_BYTES_TRANS_SUBR(4);
10073
10074                 /* volume label length, only one byte here */
10075                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
10076                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
10077                 COUNT_BYTES_TRANS_SUBR(1);
10078
10079                 /* label */
10080                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, FALSE, bcp);
10081                 CHECK_STRING_TRANS_SUBR(fn);
10082                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
10083                         fn);
10084                 COUNT_BYTES_TRANS_SUBR(fn_len);
10085
10086                 break;
10087         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
10088                 /* create time */
10089                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
10090                 offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
10091                         "Create Time", hf_smb_create_time);
10092                 *bcp -= 8;
10093         
10094                 /* volume serial number */
10095                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10096                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
10097                 COUNT_BYTES_TRANS_SUBR(4);
10098
10099                 /* volume label length */
10100                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10101                 vll = tvb_get_letohl(tvb, offset);
10102                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
10103                 COUNT_BYTES_TRANS_SUBR(4);
10104
10105                 /* 2 reserved bytes */
10106                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10107                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10108                 COUNT_BYTES_TRANS_SUBR(2);
10109
10110                 /* label */
10111                 fn_len = vll;
10112                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10113                 CHECK_STRING_TRANS_SUBR(fn);
10114                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
10115                         fn);
10116                 COUNT_BYTES_TRANS_SUBR(fn_len);
10117
10118                 break;
10119         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
10120                 /* allocation size */
10121                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
10122                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
10123                 COUNT_BYTES_TRANS_SUBR(8);
10124
10125                 /* free allocation units */
10126                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
10127                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
10128                 COUNT_BYTES_TRANS_SUBR(8);
10129
10130                 /* sectors per unit */
10131                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10132                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
10133                 COUNT_BYTES_TRANS_SUBR(4);
10134
10135                 /* bytes per sector */
10136                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10137                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
10138                 COUNT_BYTES_TRANS_SUBR(4);
10139
10140                 break;
10141         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
10142                 /* device type */
10143                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10144                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
10145                 COUNT_BYTES_TRANS_SUBR(4);
10146  
10147                 /* device characteristics */
10148                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10149                 offset = dissect_device_characteristics(tvb, pinfo, tree, offset);
10150                 *bcp -= 4;
10151         
10152                 break;
10153         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
10154                 /* FS attributes */
10155                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10156                 offset = dissect_fs_attributes(tvb, pinfo, tree, offset);
10157                 *bcp -= 4;
10158         
10159                 /* max name len */
10160                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10161                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
10162                 COUNT_BYTES_TRANS_SUBR(4);
10163
10164                 /* fs name length */
10165                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
10166                 fnl = tvb_get_letohl(tvb, offset);
10167                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
10168                 COUNT_BYTES_TRANS_SUBR(4);
10169
10170                 /* label */
10171                 fn_len = fnl;
10172                 fn = get_unicode_or_ascii_string(tvb, &offset, pinfo, &fn_len, FALSE, TRUE, bcp);
10173                 CHECK_STRING_TRANS_SUBR(fn);
10174                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
10175                         fn);
10176                 COUNT_BYTES_TRANS_SUBR(fn_len);
10177
10178                 break;
10179         }
10180  
10181         return offset;
10182 }
10183  
10184 static int
10185 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
10186     proto_tree *parent_tree, int offset, guint16 dc)
10187 {
10188         proto_item *item = NULL;
10189         proto_tree *tree = NULL;
10190         smb_info_t *si;
10191         smb_transact2_info_t *t2i;
10192         int fn_len;
10193         const char *fn;
10194         int count;
10195         gboolean trunc;
10196
10197         si = (smb_info_t *)pinfo->private_data;
10198         if (si->sip != NULL)
10199                 t2i = si->sip->extra_info;
10200         else
10201                 t2i = NULL;
10202
10203         if(parent_tree){
10204                 if (t2i != NULL && t2i->subcmd != -1) {
10205                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10206                                 "%s Data",
10207                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
10208                                         "Unknown (0x%02x)"));
10209                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
10210                 } else {
10211                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
10212                                 "Unknown Transaction2 Data");
10213                 }
10214         }
10215
10216         if (t2i == NULL) {
10217                 offset += dc;
10218                 return offset;
10219         }
10220         switch(t2i->subcmd){
10221         case 0x00:      /*TRANS2_OPEN2*/
10222                 /* XXX not implemented yet. See SNIA doc */
10223                 break;
10224         case 0x01:      /*TRANS2_FIND_FIRST2*/
10225                 /* returned data */
10226                 count = si->info_count;
10227
10228                 if (count && check_col(pinfo->fd, COL_INFO)) {
10229                         col_append_fstr(pinfo->fd, COL_INFO,
10230                         ", Files:");
10231                 }
10232
10233                 while(count--){
10234                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
10235                                 offset, &dc, &trunc);
10236                         if (trunc)
10237                                 break;
10238                 }
10239                 break;
10240         case 0x02:      /*TRANS2_FIND_NEXT2*/
10241                 /* returned data */
10242                 count = si->info_count;
10243
10244                 if (count && check_col(pinfo->fd, COL_INFO)) {
10245                         col_append_fstr(pinfo->fd, COL_INFO,
10246                         ", Files:");
10247                 }
10248
10249                 while(count--){
10250                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
10251                                 offset, &dc, &trunc);
10252                         if (trunc)
10253                                 break;
10254                 }
10255                 break;
10256         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10257                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
10258                 break;
10259         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10260                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10261                 break;
10262         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10263                 /* no data in this response */
10264                 break;
10265         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10266                 /* identical to QUERY_PATH_INFO */
10267                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
10268                 break;
10269         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10270                 /* no data in this response */
10271                 break;
10272         case 0x09:      /*TRANS2_FSCTL*/
10273                 /* XXX dont know how to dissect this one (yet)*/
10274                 break;
10275         case 0x0a:      /*TRANS2_IOCTL2*/
10276                 /* XXX dont know how to dissect this one (yet)*/
10277                 break;
10278         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10279                 /* XXX dont know how to dissect this one (yet)*/
10280                 break;
10281         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10282                 /* XXX dont know how to dissect this one (yet)*/
10283                 break;
10284         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10285                 /* no data in this response */
10286                 break;
10287         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10288                 /* XXX dont know how to dissect this one (yet)*/
10289                 break;
10290         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10291                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
10292                 break;
10293         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10294                 /* the SNIA spec appears to say the response has no data */
10295                 break;
10296         case -1:
10297                 /*
10298                  * We don't know what the matching request was; don't
10299                  * bother putting anything else into the tree for the data.
10300                  */
10301                 offset += dc;
10302                 dc = 0;
10303                 break;
10304         }
10305
10306         /* ooops there were data we didnt know how to process */
10307         if(dc != 0){
10308                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
10309                 offset += dc;
10310         }
10311
10312         return offset;
10313 }
10314
10315
10316 static int
10317 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, int pc, int od)
10318 {
10319         proto_item *item = NULL;
10320         proto_tree *tree = NULL;
10321         smb_info_t *si;
10322         smb_transact2_info_t *t2i;
10323         guint16 fid;
10324         int fn_len, lno;
10325         const char *fn;
10326         int old_offset = offset;
10327
10328         si = (smb_info_t *)pinfo->private_data;
10329         if (si->sip != NULL)
10330                 t2i = si->sip->extra_info;
10331         else
10332                 t2i = NULL;
10333
10334         if(parent_tree){
10335                 if (t2i != NULL && t2i->subcmd != -1) {
10336                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
10337                                 "%s Parameters",
10338                                 val_to_str(t2i->subcmd, trans2_cmd_vals, 
10339                                                 "Unknown (0x%02x)"));
10340                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10341                 } else {
10342                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
10343                                 "Unknown Transaction2 Parameters");
10344                 }
10345         }
10346
10347         if (t2i == NULL) {
10348                 offset += pc;
10349                 return offset;
10350         }
10351         switch(t2i->subcmd){
10352         case 0x00:      /*TRANS2_OPEN2*/
10353                 /* fid */
10354                 fid = tvb_get_letohs(tvb, offset);
10355                 add_fid(tvb, pinfo, tree, offset, fid);
10356                 offset += 2;
10357
10358                 /* File Attributes */
10359                 offset = dissect_file_attributes(tvb, pinfo, tree, offset);
10360
10361                 /* create time */
10362                 offset = dissect_smb_datetime(tvb, pinfo, tree, offset,
10363                         hf_smb_create_time, 
10364                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
10365
10366                 /* data size */
10367                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10368                 offset += 4;
10369
10370                 /* granted access */
10371                 offset = dissect_access(tvb, pinfo, tree, offset, "Granted");
10372
10373                 /* File Type */
10374                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
10375                 offset += 2;
10376
10377                 /* IPC State */
10378                 offset = dissect_ipc_state(tvb, pinfo, tree, offset);
10379
10380                 /* open_action */
10381                 offset = dissect_open_action(tvb, pinfo, tree, offset);
10382
10383                 /* 4 reserved bytes */
10384                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10385                 offset += 4;
10386
10387                 /* ea error offset, only a 16 bit integer here */
10388                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10389                 offset += 2;
10390
10391                 /* ea length */
10392                 proto_tree_add_item(tree, hf_smb_ea_length, tvb, offset, 4, TRUE);
10393                 offset += 4;
10394
10395                 break;
10396         case 0x01:      /*TRANS2_FIND_FIRST2*/
10397                 /* Find First2 information level */
10398                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, t2i->info_level);
10399
10400                 /* sid */
10401                 proto_tree_add_item(tree, hf_smb_sid, tvb, offset, 2, TRUE);
10402                 offset += 2;
10403
10404                 /* search count */
10405                 si->info_count = tvb_get_letohs(tvb, offset);
10406                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
10407                 offset += 2;
10408
10409                 /* end of search */
10410                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
10411                 offset += 2;
10412
10413                 /* ea error offset, only a 16 bit integer here */
10414                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10415                 offset += 2;
10416
10417                 /* last name offset */
10418                 lno = tvb_get_letohs(tvb, offset);
10419                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
10420                 offset += 2;
10421
10422                 break;
10423         case 0x02:      /*TRANS2_FIND_NEXT2*/
10424                 /* search count */
10425                 si->info_count = tvb_get_letohs(tvb, offset);
10426                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
10427                 offset += 2;
10428
10429                 /* end of search */
10430                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
10431                 offset += 2;
10432
10433                 /* ea error offset , only a 16 bit integer here*/
10434                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10435                 offset += 2;
10436
10437                 /* last name offset */
10438                 lno = tvb_get_letohs(tvb, offset);
10439                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
10440                 offset += 2;
10441
10442                 break;
10443         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10444                 /* no parameter block here */
10445                 break;
10446         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10447                 /* no parameter block here */
10448                 break;
10449         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10450                 /* no parameter block here */
10451                 break;
10452         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
10453                 /* no parameter block here */
10454                 break;
10455         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
10456                 /* no parameter block here */
10457                 break;
10458         case 0x09:      /*TRANS2_FSCTL*/
10459                 /* XXX dont know how to dissect this one (yet)*/
10460                 break;
10461         case 0x0a:      /*TRANS2_IOCTL2*/
10462                 /* XXX dont know how to dissect this one (yet)*/
10463                 break;
10464         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
10465                 /* XXX dont know how to dissect this one (yet)*/
10466                 break;
10467         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
10468                 /* XXX dont know how to dissect this one (yet)*/
10469                 break;
10470         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10471                 /* ea error offset, only a 16 bit integer here */
10472                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10473                 offset += 2;
10474
10475                 break;
10476         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10477                 /* XXX dont know how to dissect this one (yet)*/
10478                 break;
10479         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10480                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
10481                 break;
10482         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10483                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
10484                 break;
10485         case -1:
10486                 /*
10487                  * We don't know what the matching request was; don't
10488                  * bother putting anything else into the tree for the data.
10489                  */
10490                 offset += pc;
10491                 break;
10492         }
10493
10494         /* ooops there were data we didnt know how to process */
10495         if((offset-old_offset)<pc){
10496                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-(offset-old_offset), TRUE);
10497                 offset += pc-(offset-old_offset);
10498         }
10499
10500         return offset;
10501 }
10502
10503
10504 static int
10505 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
10506 {
10507         guint8 sc, wc;
10508         guint16 od=0, tf, po=0, pc=0, pd, dc=0, dd=0;
10509         int so=offset;
10510         int sl=0;
10511         int spo=offset;
10512         int spc=0;
10513         guint32 to;
10514         smb_info_t *si;
10515         smb_transact2_info_t *t2i = NULL;
10516         guint16 bc;
10517         int padcnt;
10518         gboolean dissected_trans;
10519
10520         si = (smb_info_t *)pinfo->private_data;
10521
10522         switch(si->cmd){
10523         case 0x32:
10524                 /* transaction2 */
10525                 if (si->sip != NULL)
10526                         t2i = si->sip->extra_info;
10527                 else
10528                         t2i = NULL;
10529                 if (t2i == NULL) {
10530                         /*
10531                          * We didn't see the matching request, so we don't
10532                          * know what type of transaction this is.
10533                          */
10534                         proto_tree_add_text(tree, tvb, 0, 0,
10535                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
10536                         if (check_col(pinfo->fd, COL_INFO)) {
10537                                 col_append_fstr(pinfo->fd, COL_INFO, "<unknown>");
10538                         }
10539                 } else if (t2i->subcmd == -1) {
10540                         /*
10541                          * We didn't manage to extract the subcommand
10542                          * from the matching request (perhaps because
10543                          * the frame was short), so we don't know what
10544                          * type of transaction this is.
10545                          */
10546                         proto_tree_add_text(tree, tvb, 0, 0,
10547                                 "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
10548                         if (check_col(pinfo->fd, COL_INFO)) {
10549                                 col_append_fstr(pinfo->fd, COL_INFO, "<unknown>");
10550                         }
10551                 } else {
10552                         proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
10553                         if (check_col(pinfo->fd, COL_INFO)) {
10554                                 col_append_fstr(pinfo->fd, COL_INFO, " %s",
10555                                         val_to_str(t2i->subcmd,
10556                                                 trans2_cmd_vals, 
10557                                                 "<unknown (0x%02x)>"));
10558                         }
10559                 }
10560                 break;
10561         }
10562
10563         WORD_COUNT;
10564
10565         /* total param count, only a 16bit integer here */
10566         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10567         offset += 2;
10568
10569         /* total data count, only a 16 bit integer here */
10570         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
10571         offset += 2;
10572
10573         /* 2 reserved bytes */
10574         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10575         offset += 2;
10576
10577         /* param count */
10578         pc = tvb_get_letohs(tvb, offset);
10579         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
10580         offset += 2;
10581
10582         /* param offset */
10583         po = tvb_get_letohs(tvb, offset);
10584         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
10585         offset += 2;
10586
10587         /* param disp */
10588         pd = tvb_get_letohs(tvb, offset);
10589         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
10590         offset += 2;
10591
10592         /* data count */
10593         dc = tvb_get_letohs(tvb, offset);
10594         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
10595         offset += 2;
10596
10597         /* data offset */
10598         od = tvb_get_letohs(tvb, offset);
10599         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
10600         offset += 2;
10601
10602         /* data disp */
10603         dd = tvb_get_letohs(tvb, offset);
10604         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
10605         offset += 2;
10606
10607         /* setup count */
10608         sc = tvb_get_guint8(tvb, offset);
10609         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
10610         offset += 1;
10611
10612         /* reserved byte */
10613         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
10614         offset += 1;
10615
10616         /* save setup offset */ 
10617         so = offset;
10618
10619         /* if there were any setup bytes, decode them */
10620         sl = sc*2;
10621         if(sl){
10622                 /* XXXX dissect setup words */
10623                 offset += sl;
10624         }
10625
10626         /*
10627          * The pipe or mailslot arguments for Transaction start with
10628          * the first setup word (or where the first setup word would
10629          * be if there were any setup words), and run to the current
10630          * offset (which could mean that there aren't any).
10631          */
10632         spo = so;
10633         spc = offset - spo;
10634
10635         BYTE_COUNT;
10636         
10637         /* parameters */
10638         if(po>offset){
10639                 /* We have some initial padding bytes.
10640                 */
10641                 padcnt = po-offset;
10642                 if (padcnt > bc)
10643                         padcnt = bc;
10644                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10645                 COUNT_BYTES(padcnt);
10646         }
10647         if(pc){
10648                 CHECK_BYTE_COUNT(pc);
10649                 switch(si->cmd){
10650
10651                 case 0x32:
10652                         /* TRANSACTION2 parameters*/
10653                         offset = dissect_transaction2_response_parameters(tvb, pinfo, tree, offset, pc, od);
10654                         bc -= pc;
10655                         break;
10656
10657                 case 0x25:
10658                         /* TRANSACTION parameters processed below */
10659                         COUNT_BYTES(pc);
10660                         break;
10661                 }
10662         }
10663
10664         /* data */
10665         if(od>offset){
10666                 /* We have some initial padding bytes.
10667                 */
10668                 padcnt = od-offset;
10669                 if (padcnt > bc)
10670                         padcnt = bc;
10671                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
10672                 COUNT_BYTES(padcnt);
10673         }
10674         if(dc){
10675                 CHECK_BYTE_COUNT(dc);
10676                 switch(si->cmd){
10677
10678                 case 0x32:
10679                         /* TRANSACTION2 data*/
10680                         offset = dissect_transaction2_response_data(tvb, pinfo, tree, offset, dc);
10681                         bc -= dc;
10682                         break;
10683
10684                 case 0x25:
10685                         /* TRANSACTION information processed below */
10686                         COUNT_BYTES(dc);
10687                         break;
10688                 }
10689         }
10690
10691         /* TRANSACTION response parameters */
10692         if(si->cmd==0x25){
10693                 /* only call subdissector for the first packet */
10694                 if(dd==0){
10695                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
10696                         tvbuff_t *sp_tvb, *pd_tvb;
10697                         smb_transact_info_t *tri;
10698
10699                         if(pc>0){
10700                                 if(pc>tvb_length_remaining(tvb, po)){
10701                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
10702                                 } else {
10703                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
10704                                 }
10705                         } else {
10706                                 p_tvb = NULL;
10707                         }
10708                         if(dc>0){
10709                                 if(dc>tvb_length_remaining(tvb, od)){
10710                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
10711                                 } else {
10712                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
10713                                 }
10714                         } else {
10715                                 d_tvb = NULL;
10716                         }
10717                         if(sl){
10718                                 if(sl>tvb_length_remaining(tvb, so)){
10719                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
10720                                 } else {
10721                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
10722                                 }
10723                         } else {
10724                                 s_tvb = NULL;
10725                         }
10726
10727                         dissected_trans = FALSE;
10728                         if (si->sip != NULL)
10729                                 tri = si->sip->extra_info;
10730                         else
10731                                 tri = NULL;
10732                         if (tri != NULL) {
10733                                 switch(tri->subcmd){
10734
10735                                 case TRANSACTION_PIPE:
10736                                         /*
10737                                          * A tvbuff containing the setup
10738                                          * words and the pipe path.
10739                                          */
10740                                         sp_tvb = tvb_new_subset(tvb, spo, spc,
10741                                             spc);
10742
10743                                         /*
10744                                          * A tvbuff containing the parameters
10745                                          * and the data.
10746                                          */
10747                                         pd_tvb = tvb_new_subset(tvb, po, -1, -1);
10748
10749                                         dissected_trans = dissect_pipe_smb(
10750                                             sp_tvb, s_tvb, pd_tvb, p_tvb,
10751                                             d_tvb, NULL, pinfo, top_tree);
10752                                         break;
10753
10754                                 case TRANSACTION_MAILSLOT:
10755                                         /*
10756                                          * A tvbuff containing the setup
10757                                          * words and the mailslot path.
10758                                          */
10759                                         sp_tvb = tvb_new_subset(tvb, spo, spc,
10760                                             spc);
10761
10762                                         dissected_trans = dissect_mailslot_smb(
10763                                             sp_tvb, s_tvb, d_tvb, NULL, pinfo,
10764                                             top_tree);
10765                                         break;
10766                                 }
10767                         }
10768                         if (!dissected_trans) {
10769                                 dissect_trans_data(s_tvb, p_tvb, d_tvb,
10770                                     pinfo, tree);
10771                         }
10772                 } else {
10773                         if(check_col(pinfo->fd, COL_INFO)){
10774                                 col_append_str(pinfo->fd, COL_INFO,
10775                                         "[transact continuation]");
10776                         }
10777                 }
10778         }
10779
10780         END_OF_SMB
10781
10782         return offset;
10783 }
10784
10785
10786 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10787    END Transaction/Transaction2 Primary and secondary requests
10788    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
10789
10790
10791 static int
10792 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
10793 {
10794         guint8 wc;
10795         guint16 bc;
10796
10797         WORD_COUNT;
10798  
10799         if (wc != 0)
10800                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
10801
10802         BYTE_COUNT;
10803
10804         if (bc != 0)
10805                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
10806
10807         END_OF_SMB
10808
10809         return offset;
10810 }
10811
10812 typedef struct _smb_function {
10813        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
10814        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
10815 } smb_function;
10816
10817 smb_function smb_dissector[256] = {
10818   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
10819   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
10820   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
10821   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
10822   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
10823   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
10824   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
10825   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
10826   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
10827   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
10828   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
10829   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
10830   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
10831   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
10832   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
10833   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
10834
10835   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
10836   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
10837   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
10838   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
10839   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
10840   /* 0x15 */  {dissect_unknown, dissect_unknown},
10841   /* 0x16 */  {dissect_unknown, dissect_unknown},
10842   /* 0x17 */  {dissect_unknown, dissect_unknown},
10843   /* 0x18 */  {dissect_unknown, dissect_unknown},
10844   /* 0x19 */  {dissect_unknown, dissect_unknown},
10845   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
10846   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
10847   /* 0x1c */  {dissect_unknown, dissect_unknown},
10848   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
10849   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
10850   /* 0x1f */  {dissect_unknown, dissect_unknown},
10851
10852   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
10853   /* 0x21 */  {dissect_unknown, dissect_unknown},
10854   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
10855   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
10856   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
10857   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
10858   /* 0x26 */  {dissect_unknown, dissect_unknown},
10859   /* 0x27 */  {dissect_unknown, dissect_unknown},
10860   /* 0x28 */  {dissect_unknown, dissect_unknown},
10861   /* 0x29 */  {dissect_unknown, dissect_unknown},
10862   /* 0x2a Move File*/  {dissect_move_request, dissect_move_response},
10863   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
10864   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
10865   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
10866   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
10867   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
10868
10869   /* 0x30 */  {dissect_unknown, dissect_unknown},
10870   /* 0x31 */  {dissect_unknown, dissect_unknown},
10871   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
10872   /* 0x33 */  {dissect_unknown, dissect_unknown},
10873   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
10874   /* 0x35 */  {dissect_unknown, dissect_unknown},
10875   /* 0x36 */  {dissect_unknown, dissect_unknown},
10876   /* 0x37 */  {dissect_unknown, dissect_unknown},
10877   /* 0x38 */  {dissect_unknown, dissect_unknown},
10878   /* 0x39 */  {dissect_unknown, dissect_unknown},
10879   /* 0x3a */  {dissect_unknown, dissect_unknown},
10880   /* 0x3b */  {dissect_unknown, dissect_unknown},
10881   /* 0x3c */  {dissect_unknown, dissect_unknown},
10882   /* 0x3d */  {dissect_unknown, dissect_unknown},
10883   /* 0x3e */  {dissect_unknown, dissect_unknown},
10884   /* 0x3f */  {dissect_unknown, dissect_unknown},
10885
10886   /* 0x40 */  {dissect_unknown, dissect_unknown},
10887   /* 0x41 */  {dissect_unknown, dissect_unknown},
10888   /* 0x42 */  {dissect_unknown, dissect_unknown},
10889   /* 0x43 */  {dissect_unknown, dissect_unknown},
10890   /* 0x44 */  {dissect_unknown, dissect_unknown},
10891   /* 0x45 */  {dissect_unknown, dissect_unknown},
10892   /* 0x46 */  {dissect_unknown, dissect_unknown},
10893   /* 0x47 */  {dissect_unknown, dissect_unknown},
10894   /* 0x48 */  {dissect_unknown, dissect_unknown},
10895   /* 0x49 */  {dissect_unknown, dissect_unknown},
10896   /* 0x4a */  {dissect_unknown, dissect_unknown},
10897   /* 0x4b */  {dissect_unknown, dissect_unknown},
10898   /* 0x4c */  {dissect_unknown, dissect_unknown},
10899   /* 0x4d */  {dissect_unknown, dissect_unknown},
10900   /* 0x4e */  {dissect_unknown, dissect_unknown},
10901   /* 0x4f */  {dissect_unknown, dissect_unknown},
10902
10903   /* 0x50 */  {dissect_unknown, dissect_unknown},
10904   /* 0x51 */  {dissect_unknown, dissect_unknown},
10905   /* 0x52 */  {dissect_unknown, dissect_unknown},
10906   /* 0x53 */  {dissect_unknown, dissect_unknown},
10907   /* 0x54 */  {dissect_unknown, dissect_unknown},
10908   /* 0x55 */  {dissect_unknown, dissect_unknown},
10909   /* 0x56 */  {dissect_unknown, dissect_unknown},
10910   /* 0x57 */  {dissect_unknown, dissect_unknown},
10911   /* 0x58 */  {dissect_unknown, dissect_unknown},
10912   /* 0x59 */  {dissect_unknown, dissect_unknown},
10913   /* 0x5a */  {dissect_unknown, dissect_unknown},
10914   /* 0x5b */  {dissect_unknown, dissect_unknown},
10915   /* 0x5c */  {dissect_unknown, dissect_unknown},
10916   /* 0x5d */  {dissect_unknown, dissect_unknown},
10917   /* 0x5e */  {dissect_unknown, dissect_unknown},
10918   /* 0x5f */  {dissect_unknown, dissect_unknown},
10919
10920   /* 0x60 */  {dissect_unknown, dissect_unknown},
10921   /* 0x61 */  {dissect_unknown, dissect_unknown},
10922   /* 0x62 */  {dissect_unknown, dissect_unknown},
10923   /* 0x63 */  {dissect_unknown, dissect_unknown},
10924   /* 0x64 */  {dissect_unknown, dissect_unknown},
10925   /* 0x65 */  {dissect_unknown, dissect_unknown},
10926   /* 0x66 */  {dissect_unknown, dissect_unknown},
10927   /* 0x67 */  {dissect_unknown, dissect_unknown},
10928   /* 0x68 */  {dissect_unknown, dissect_unknown},
10929   /* 0x69 */  {dissect_unknown, dissect_unknown},
10930   /* 0x6a */  {dissect_unknown, dissect_unknown},
10931   /* 0x6b */  {dissect_unknown, dissect_unknown},
10932   /* 0x6c */  {dissect_unknown, dissect_unknown},
10933   /* 0x6d */  {dissect_unknown, dissect_unknown},
10934   /* 0x6e */  {dissect_unknown, dissect_unknown},
10935   /* 0x6f */  {dissect_unknown, dissect_unknown},
10936
10937   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
10938   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
10939   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
10940   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
10941   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
10942   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
10943   /* 0x76 */  {dissect_unknown, dissect_unknown},
10944   /* 0x77 */  {dissect_unknown, dissect_unknown},
10945   /* 0x78 */  {dissect_unknown, dissect_unknown},
10946   /* 0x79 */  {dissect_unknown, dissect_unknown},
10947   /* 0x7a */  {dissect_unknown, dissect_unknown},
10948   /* 0x7b */  {dissect_unknown, dissect_unknown},
10949   /* 0x7c */  {dissect_unknown, dissect_unknown},
10950   /* 0x7d */  {dissect_unknown, dissect_unknown},
10951   /* 0x7e */  {dissect_unknown, dissect_unknown},
10952   /* 0x7f */  {dissect_unknown, dissect_unknown},
10953
10954   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
10955   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
10956   /* 0x82 */  {dissect_unknown, dissect_unknown},
10957   /* 0x83 */  {dissect_unknown, dissect_unknown},
10958   /* 0x84 */  {dissect_unknown, dissect_unknown},
10959   /* 0x85 */  {dissect_unknown, dissect_unknown},
10960   /* 0x86 */  {dissect_unknown, dissect_unknown},
10961   /* 0x87 */  {dissect_unknown, dissect_unknown},
10962   /* 0x88 */  {dissect_unknown, dissect_unknown},
10963   /* 0x89 */  {dissect_unknown, dissect_unknown},
10964   /* 0x8a */  {dissect_unknown, dissect_unknown},
10965   /* 0x8b */  {dissect_unknown, dissect_unknown},
10966   /* 0x8c */  {dissect_unknown, dissect_unknown},
10967   /* 0x8d */  {dissect_unknown, dissect_unknown},
10968   /* 0x8e */  {dissect_unknown, dissect_unknown},
10969   /* 0x8f */  {dissect_unknown, dissect_unknown},
10970
10971   /* 0x90 */  {dissect_unknown, dissect_unknown},
10972   /* 0x91 */  {dissect_unknown, dissect_unknown},
10973   /* 0x92 */  {dissect_unknown, dissect_unknown},
10974   /* 0x93 */  {dissect_unknown, dissect_unknown},
10975   /* 0x94 */  {dissect_unknown, dissect_unknown},
10976   /* 0x95 */  {dissect_unknown, dissect_unknown},
10977   /* 0x96 */  {dissect_unknown, dissect_unknown},
10978   /* 0x97 */  {dissect_unknown, dissect_unknown},
10979   /* 0x98 */  {dissect_unknown, dissect_unknown},
10980   /* 0x99 */  {dissect_unknown, dissect_unknown},
10981   /* 0x9a */  {dissect_unknown, dissect_unknown},
10982   /* 0x9b */  {dissect_unknown, dissect_unknown},
10983   /* 0x9c */  {dissect_unknown, dissect_unknown},
10984   /* 0x9d */  {dissect_unknown, dissect_unknown},
10985   /* 0x9e */  {dissect_unknown, dissect_unknown},
10986   /* 0x9f */  {dissect_unknown, dissect_unknown},
10987   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
10988   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
10989   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
10990   /* 0xa3 */  {dissect_unknown, dissect_unknown},
10991   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
10992   /* 0xa5 */  {dissect_unknown, dissect_unknown},
10993   /* 0xa6 */  {dissect_unknown, dissect_unknown},
10994   /* 0xa7 */  {dissect_unknown, dissect_unknown},
10995   /* 0xa8 */  {dissect_unknown, dissect_unknown},
10996   /* 0xa9 */  {dissect_unknown, dissect_unknown},
10997   /* 0xaa */  {dissect_unknown, dissect_unknown},
10998   /* 0xab */  {dissect_unknown, dissect_unknown},
10999   /* 0xac */  {dissect_unknown, dissect_unknown},
11000   /* 0xad */  {dissect_unknown, dissect_unknown},
11001   /* 0xae */  {dissect_unknown, dissect_unknown},
11002   /* 0xaf */  {dissect_unknown, dissect_unknown},
11003
11004   /* 0xb0 */  {dissect_unknown, dissect_unknown},
11005   /* 0xb1 */  {dissect_unknown, dissect_unknown},
11006   /* 0xb2 */  {dissect_unknown, dissect_unknown},
11007   /* 0xb3 */  {dissect_unknown, dissect_unknown},
11008   /* 0xb4 */  {dissect_unknown, dissect_unknown},
11009   /* 0xb5 */  {dissect_unknown, dissect_unknown},
11010   /* 0xb6 */  {dissect_unknown, dissect_unknown},
11011   /* 0xb7 */  {dissect_unknown, dissect_unknown},
11012   /* 0xb8 */  {dissect_unknown, dissect_unknown},
11013   /* 0xb9 */  {dissect_unknown, dissect_unknown},
11014   /* 0xba */  {dissect_unknown, dissect_unknown},
11015   /* 0xbb */  {dissect_unknown, dissect_unknown},
11016   /* 0xbc */  {dissect_unknown, dissect_unknown},
11017   /* 0xbd */  {dissect_unknown, dissect_unknown},
11018   /* 0xbe */  {dissect_unknown, dissect_unknown},
11019   /* 0xbf */  {dissect_unknown, dissect_unknown},
11020   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
11021   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
11022   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
11023   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
11024   /* 0xc4 */  {dissect_unknown, dissect_unknown},
11025   /* 0xc5 */  {dissect_unknown, dissect_unknown},
11026   /* 0xc6 */  {dissect_unknown, dissect_unknown},
11027   /* 0xc7 */  {dissect_unknown, dissect_unknown},
11028   /* 0xc8 */  {dissect_unknown, dissect_unknown},
11029   /* 0xc9 */  {dissect_unknown, dissect_unknown},
11030   /* 0xca */  {dissect_unknown, dissect_unknown},
11031   /* 0xcb */  {dissect_unknown, dissect_unknown},
11032   /* 0xcc */  {dissect_unknown, dissect_unknown},
11033   /* 0xcd */  {dissect_unknown, dissect_unknown},
11034   /* 0xce */  {dissect_unknown, dissect_unknown},
11035   /* 0xcf */  {dissect_unknown, dissect_unknown},
11036
11037   /* 0xd0 */  {dissect_unknown, dissect_unknown},
11038   /* 0xd1 */  {dissect_unknown, dissect_unknown},
11039   /* 0xd2 */  {dissect_unknown, dissect_unknown},
11040   /* 0xd3 */  {dissect_unknown, dissect_unknown},
11041   /* 0xd4 */  {dissect_unknown, dissect_unknown},
11042   /* 0xd5 */  {dissect_unknown, dissect_unknown},
11043   /* 0xd6 */  {dissect_unknown, dissect_unknown},
11044   /* 0xd7 */  {dissect_unknown, dissect_unknown},
11045   /* 0xd8 */  {dissect_unknown, dissect_unknown},
11046   /* 0xd9 */  {dissect_unknown, dissect_unknown},
11047   /* 0xda */  {dissect_unknown, dissect_unknown},
11048   /* 0xdb */  {dissect_unknown, dissect_unknown},
11049   /* 0xdc */  {dissect_unknown, dissect_unknown},
11050   /* 0xdd */  {dissect_unknown, dissect_unknown},
11051   /* 0xde */  {dissect_unknown, dissect_unknown},
11052   /* 0xdf */  {dissect_unknown, dissect_unknown},
11053
11054   /* 0xe0 */  {dissect_unknown, dissect_unknown},
11055   /* 0xe1 */  {dissect_unknown, dissect_unknown},
11056   /* 0xe2 */  {dissect_unknown, dissect_unknown},
11057   /* 0xe3 */  {dissect_unknown, dissect_unknown},
11058   /* 0xe4 */  {dissect_unknown, dissect_unknown},
11059   /* 0xe5 */  {dissect_unknown, dissect_unknown},
11060   /* 0xe6 */  {dissect_unknown, dissect_unknown},
11061   /* 0xe7 */  {dissect_unknown, dissect_unknown},
11062   /* 0xe8 */  {dissect_unknown, dissect_unknown},
11063   /* 0xe9 */  {dissect_unknown, dissect_unknown},
11064   /* 0xea */  {dissect_unknown, dissect_unknown},
11065   /* 0xeb */  {dissect_unknown, dissect_unknown},
11066   /* 0xec */  {dissect_unknown, dissect_unknown},
11067   /* 0xed */  {dissect_unknown, dissect_unknown},
11068   /* 0xee */  {dissect_unknown, dissect_unknown},
11069   /* 0xef */  {dissect_unknown, dissect_unknown},
11070
11071   /* 0xf0 */  {dissect_unknown, dissect_unknown},
11072   /* 0xf1 */  {dissect_unknown, dissect_unknown},
11073   /* 0xf2 */  {dissect_unknown, dissect_unknown},
11074   /* 0xf3 */  {dissect_unknown, dissect_unknown},
11075   /* 0xf4 */  {dissect_unknown, dissect_unknown},
11076   /* 0xf5 */  {dissect_unknown, dissect_unknown},
11077   /* 0xf6 */  {dissect_unknown, dissect_unknown},
11078   /* 0xf7 */  {dissect_unknown, dissect_unknown},
11079   /* 0xf8 */  {dissect_unknown, dissect_unknown},
11080   /* 0xf9 */  {dissect_unknown, dissect_unknown},
11081   /* 0xfa */  {dissect_unknown, dissect_unknown},
11082   /* 0xfb */  {dissect_unknown, dissect_unknown},
11083   /* 0xfc */  {dissect_unknown, dissect_unknown},
11084   /* 0xfd */  {dissect_unknown, dissect_unknown},
11085   /* 0xfe */  {dissect_unknown, dissect_unknown},
11086   /* 0xff */  {dissect_unknown, dissect_unknown},
11087 };
11088
11089 static int
11090 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree, int offset, proto_tree *smb_tree, guint8 cmd)
11091 {
11092         int old_offset = offset;
11093         smb_info_t *si;
11094  
11095         si = pinfo->private_data;
11096         if(cmd!=0xff){
11097                 proto_item *cmd_item;
11098                 proto_tree *cmd_tree;
11099                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
11100
11101                 if (check_col(pinfo->fd, COL_INFO)) {
11102                         col_add_fstr(pinfo->fd, COL_INFO, "%s %s",
11103                                 decode_smb_name(cmd),
11104                                 (si->request)? "Request" : "Response");
11105                 }
11106
11107                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset,
11108                         0, "%s %s (0x%02x)",
11109                         decode_smb_name(cmd), 
11110                         (si->request)?"Request":"Response",
11111                         cmd);
11112
11113                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
11114
11115                 dissector = (si->request)?
11116                         smb_dissector[cmd].request:smb_dissector[cmd].response;
11117
11118                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
11119                 proto_item_set_len(cmd_item, offset-old_offset);
11120         }
11121         return offset;
11122 }
11123
11124
11125 /* NOTE: this value_string array will also be used to access data directly by
11126  * index instead of val_to_str() since 
11127  * 1, the array will always span every value from 0x00 to 0xff and
11128  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
11129  * This means that this value_string array MUST always
11130  * 1, contain all entries 0x00 to 0xff
11131  * 2, all entries must be in order.
11132  */
11133 static const value_string smb_cmd_vals[] = {
11134   { 0x00, "Create Directory" },
11135   { 0x01, "Delete Directory" },
11136   { 0x02, "Open" },
11137   { 0x03, "Create" },
11138   { 0x04, "Close" },
11139   { 0x05, "Flush" },
11140   { 0x06, "Delete" },
11141   { 0x07, "Rename" },
11142   { 0x08, "Query Information" },
11143   { 0x09, "Set Information" },
11144   { 0x0A, "Read" },
11145   { 0x0B, "Write" },
11146   { 0x0C, "Lock Byte Range" },
11147   { 0x0D, "Unlock Byte Range" },
11148   { 0x0E, "Create Temp" },
11149   { 0x0F, "Create New" },
11150   { 0x10, "Check Directory" },
11151   { 0x11, "Process Exit" },
11152   { 0x12, "Seek" },
11153   { 0x13, "Lock And Read" },
11154   { 0x14, "Write And Unlock" },
11155   { 0x15, "unknown-0x15" },
11156   { 0x16, "unknown-0x16" },
11157   { 0x17, "unknown-0x17" },
11158   { 0x18, "unknown-0x18" },
11159   { 0x19, "unknown-0x19" },
11160   { 0x1A, "Read Raw" },
11161   { 0x1B, "Read MPX" },
11162   { 0x1C, "Read MPX Secondary" },
11163   { 0x1D, "Write Raw" },
11164   { 0x1E, "Write MPX" },
11165   { 0x1F, "SMBwriteBs" },
11166   { 0x20, "Write Complete" },
11167   { 0x21, "unknown-0x21" },
11168   { 0x22, "Set Information2" },
11169   { 0x23, "Query Information2" },
11170   { 0x24, "Locking AndX" },
11171   { 0x25, "Transaction" },
11172   { 0x26, "Transaction Secondary" },
11173   { 0x27, "IOCTL" },
11174   { 0x28, "IOCTL Secondary" },
11175   { 0x29, "Copy" },
11176   { 0x2A, "Move" },
11177   { 0x2B, "Echo" },
11178   { 0x2C, "Write And Close" },
11179   { 0x2D, "Open AndX" },
11180   { 0x2E, "Read AndX" },
11181   { 0x2F, "Write AndX" },
11182   { 0x30, "unknown-0x30" },
11183   { 0x31, "Close And Tree Discover" },
11184   { 0x32, "Transaction2" },
11185   { 0x33, "Transaction2 Secondary" },
11186   { 0x34, "Find Close2" },
11187   { 0x35, "Find Notify Close" },
11188   { 0x36, "unknown-0x36" },
11189   { 0x37, "unknown-0x37" },
11190   { 0x38, "unknown-0x38" },
11191   { 0x39, "unknown-0x39" },
11192   { 0x3A, "unknown-0x3A" },
11193   { 0x3B, "unknown-0x3B" },
11194   { 0x3C, "unknown-0x3C" },
11195   { 0x3D, "unknown-0x3D" },
11196   { 0x3E, "unknown-0x3E" },
11197   { 0x3F, "unknown-0x3F" },
11198   { 0x40, "unknown-0x40" },
11199   { 0x41, "unknown-0x41" },
11200   { 0x42, "unknown-0x42" },
11201   { 0x43, "unknown-0x43" },
11202   { 0x44, "unknown-0x44" },
11203   { 0x45, "unknown-0x45" },
11204   { 0x46, "unknown-0x46" },
11205   { 0x47, "unknown-0x47" },
11206   { 0x48, "unknown-0x48" },
11207   { 0x49, "unknown-0x49" },
11208   { 0x4A, "unknown-0x4A" },
11209   { 0x4B, "unknown-0x4B" },
11210   { 0x4C, "unknown-0x4C" },
11211   { 0x4D, "unknown-0x4D" },
11212   { 0x4E, "unknown-0x4E" },
11213   { 0x4F, "unknown-0x4F" },
11214   { 0x50, "unknown-0x50" },
11215   { 0x51, "unknown-0x51" },
11216   { 0x52, "unknown-0x52" },
11217   { 0x53, "unknown-0x53" },
11218   { 0x54, "unknown-0x54" },
11219   { 0x55, "unknown-0x55" },
11220   { 0x56, "unknown-0x56" },
11221   { 0x57, "unknown-0x57" },
11222   { 0x58, "unknown-0x58" },
11223   { 0x59, "unknown-0x59" },
11224   { 0x5A, "unknown-0x5A" },
11225   { 0x5B, "unknown-0x5B" },
11226   { 0x5C, "unknown-0x5C" },
11227   { 0x5D, "unknown-0x5D" },
11228   { 0x5E, "unknown-0x5E" },
11229   { 0x5F, "unknown-0x5F" },
11230   { 0x60, "unknown-0x60" },
11231   { 0x61, "unknown-0x61" },
11232   { 0x62, "unknown-0x62" },
11233   { 0x63, "unknown-0x63" },
11234   { 0x64, "unknown-0x64" },
11235   { 0x65, "unknown-0x65" },
11236   { 0x66, "unknown-0x66" },
11237   { 0x67, "unknown-0x67" },
11238   { 0x68, "unknown-0x68" },
11239   { 0x69, "unknown-0x69" },
11240   { 0x6A, "unknown-0x6A" },
11241   { 0x6B, "unknown-0x6B" },
11242   { 0x6C, "unknown-0x6C" },
11243   { 0x6D, "unknown-0x6D" },
11244   { 0x6E, "unknown-0x6E" },
11245   { 0x6F, "unknown-0x6F" },
11246   { 0x70, "Tree Connect" },
11247   { 0x71, "Tree Disconnect" },
11248   { 0x72, "Negotiate Protocol" },
11249   { 0x73, "Session Setup AndX" },
11250   { 0x74, "Logoff AndX" },
11251   { 0x75, "Tree Connect AndX" },
11252   { 0x76, "unknown-0x76" },
11253   { 0x77, "unknown-0x77" },
11254   { 0x78, "unknown-0x78" },
11255   { 0x79, "unknown-0x79" },
11256   { 0x7A, "unknown-0x7A" },
11257   { 0x7B, "unknown-0x7B" },
11258   { 0x7C, "unknown-0x7C" },
11259   { 0x7D, "unknown-0x7D" },
11260   { 0x7E, "unknown-0x7E" },
11261   { 0x7F, "unknown-0x7F" },
11262   { 0x80, "Query Information Disk" },
11263   { 0x81, "Search" },
11264   { 0x82, "Find" },
11265   { 0x83, "Find Unique" },
11266   { 0x84, "SMBfclose" },
11267   { 0x85, "unknown-0x85" },
11268   { 0x86, "unknown-0x86" },
11269   { 0x87, "unknown-0x87" },
11270   { 0x88, "unknown-0x88" },
11271   { 0x89, "unknown-0x89" },
11272   { 0x8A, "unknown-0x8A" },
11273   { 0x8B, "unknown-0x8B" },
11274   { 0x8C, "unknown-0x8C" },
11275   { 0x8D, "unknown-0x8D" },
11276   { 0x8E, "unknown-0x8E" },
11277   { 0x8F, "unknown-0x8F" },
11278   { 0x90, "unknown-0x90" },
11279   { 0x91, "unknown-0x91" },
11280   { 0x92, "unknown-0x92" },
11281   { 0x93, "unknown-0x93" },
11282   { 0x94, "unknown-0x94" },
11283   { 0x95, "unknown-0x95" },
11284   { 0x96, "unknown-0x96" },
11285   { 0x97, "unknown-0x97" },
11286   { 0x98, "unknown-0x98" },
11287   { 0x99, "unknown-0x99" },
11288   { 0x9A, "unknown-0x9A" },
11289   { 0x9B, "unknown-0x9B" },
11290   { 0x9C, "unknown-0x9C" },
11291   { 0x9D, "unknown-0x9D" },
11292   { 0x9E, "unknown-0x9E" },
11293   { 0x9F, "unknown-0x9F" },
11294   { 0xA0, "NT Transact" },
11295   { 0xA1, "NT Transact Secondary" },
11296   { 0xA2, "NT Create AndX" },
11297   { 0xA3, "unknown-0xA3" },
11298   { 0xA4, "NT Cancel" },
11299   { 0xA5, "unknown-0xA5" },
11300   { 0xA6, "unknown-0xA6" },
11301   { 0xA7, "unknown-0xA7" },
11302   { 0xA8, "unknown-0xA8" },
11303   { 0xA9, "unknown-0xA9" },
11304   { 0xAA, "unknown-0xAA" },
11305   { 0xAB, "unknown-0xAB" },
11306   { 0xAC, "unknown-0xAC" },
11307   { 0xAD, "unknown-0xAD" },
11308   { 0xAE, "unknown-0xAE" },
11309   { 0xAF, "unknown-0xAF" },
11310   { 0xB0, "unknown-0xB0" },
11311   { 0xB1, "unknown-0xB1" },
11312   { 0xB2, "unknown-0xB2" },
11313   { 0xB3, "unknown-0xB3" },
11314   { 0xB4, "unknown-0xB4" },
11315   { 0xB5, "unknown-0xB5" },
11316   { 0xB6, "unknown-0xB6" },
11317   { 0xB7, "unknown-0xB7" },
11318   { 0xB8, "unknown-0xB8" },
11319   { 0xB9, "unknown-0xB9" },
11320   { 0xBA, "unknown-0xBA" },
11321   { 0xBB, "unknown-0xBB" },
11322   { 0xBC, "unknown-0xBC" },
11323   { 0xBD, "unknown-0xBD" },
11324   { 0xBE, "unknown-0xBE" },
11325   { 0xBF, "unknown-0xBF" },
11326   { 0xC0, "Open Print File" },
11327   { 0xC1, "Write Print File" },
11328   { 0xC2, "Close Print File" },
11329   { 0xC3, "Get Print Queue" },
11330   { 0xC4, "unknown-0xC4" },
11331   { 0xC5, "unknown-0xC5" },
11332   { 0xC6, "unknown-0xC6" },
11333   { 0xC7, "unknown-0xC7" },
11334   { 0xC8, "unknown-0xC8" },
11335   { 0xC9, "unknown-0xC9" },
11336   { 0xCA, "unknown-0xCA" },
11337   { 0xCB, "unknown-0xCB" },
11338   { 0xCC, "unknown-0xCC" },
11339   { 0xCD, "unknown-0xCD" },
11340   { 0xCE, "unknown-0xCE" },
11341   { 0xCF, "unknown-0xCF" },
11342   { 0xD0, "SMBsends" },
11343   { 0xD1, "SMBsendb" },
11344   { 0xD2, "SMBfwdname" },
11345   { 0xD3, "SMBcancelf" },
11346   { 0xD4, "SMBgetmac" },
11347   { 0xD5, "SMBsendstrt" },
11348   { 0xD6, "SMBsendend" },
11349   { 0xD7, "SMBsendtxt" },
11350   { 0xD8, "SMBreadbulk" },
11351   { 0xD9, "SMBwritebulk" },
11352   { 0xDA, "SMBwritebulkdata" },
11353   { 0xDB, "unknown-0xDB" },
11354   { 0xDC, "unknown-0xDC" },
11355   { 0xDD, "unknown-0xDD" },
11356   { 0xDE, "unknown-0xDE" },
11357   { 0xDF, "unknown-0xDF" },
11358   { 0xE0, "unknown-0xE0" },
11359   { 0xE1, "unknown-0xE1" },
11360   { 0xE2, "unknown-0xE2" },
11361   { 0xE3, "unknown-0xE3" },
11362   { 0xE4, "unknown-0xE4" },
11363   { 0xE5, "unknown-0xE5" },
11364   { 0xE6, "unknown-0xE6" },
11365   { 0xE7, "unknown-0xE7" },
11366   { 0xE8, "unknown-0xE8" },
11367   { 0xE9, "unknown-0xE9" },
11368   { 0xEA, "unknown-0xEA" },
11369   { 0xEB, "unknown-0xEB" },
11370   { 0xEC, "unknown-0xEC" },
11371   { 0xED, "unknown-0xED" },
11372   { 0xEE, "unknown-0xEE" },
11373   { 0xEF, "unknown-0xEF" },
11374   { 0xF0, "unknown-0xF0" },
11375   { 0xF1, "unknown-0xF1" },
11376   { 0xF2, "unknown-0xF2" },
11377   { 0xF3, "unknown-0xF3" },
11378   { 0xF4, "unknown-0xF4" },
11379   { 0xF5, "unknown-0xF5" },
11380   { 0xF6, "unknown-0xF6" },
11381   { 0xF7, "unknown-0xF7" },
11382   { 0xF8, "unknown-0xF8" },
11383   { 0xF9, "unknown-0xF9" },
11384   { 0xFA, "unknown-0xFA" },
11385   { 0xFB, "unknown-0xFB" },
11386   { 0xFC, "unknown-0xFC" },
11387   { 0xFD, "unknown-0xFD" },
11388   { 0xFE, "SMBinvalid" },
11389   { 0xFF, "unknown-0xFF" },
11390   { 0x00, NULL },
11391 };
11392
11393 static char *decode_smb_name(unsigned char cmd)
11394 {
11395   return(smb_cmd_vals[cmd].strptr);
11396 }
11397  
11398
11399
11400 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
11401  * Everything TVBUFFIFIED above this line
11402  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
11403
11404
11405 /*
11406  * Struct passed to each SMB decode routine of info it may need
11407  */
11408
11409 static void
11410 smb_init_protocol(void)
11411 {
11412         if (smb_saved_info_chunk)
11413                 g_mem_chunk_destroy(smb_saved_info_chunk);
11414         if (smb_nt_transact_info_chunk)
11415                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
11416         if (smb_transact2_info_chunk)
11417                 g_mem_chunk_destroy(smb_transact2_info_chunk);
11418         if (smb_transact_info_chunk)
11419                 g_mem_chunk_destroy(smb_transact_info_chunk);
11420         if (conv_tables_chunk)
11421                 g_mem_chunk_destroy(conv_tables_chunk);
11422
11423         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
11424             sizeof(smb_saved_info_t),
11425             smb_saved_info_init_count * sizeof(smb_saved_info_t),
11426             G_ALLOC_ONLY);
11427         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
11428             sizeof(smb_nt_transact_info_t),
11429             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
11430             G_ALLOC_ONLY);
11431         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
11432             sizeof(smb_transact2_info_t),
11433             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
11434             G_ALLOC_ONLY);
11435         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
11436             sizeof(smb_transact_info_t),
11437             smb_transact_info_init_count * sizeof(smb_transact_info_t),
11438             G_ALLOC_ONLY);
11439         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
11440             sizeof(conv_tables_t),
11441             conv_tables_count * sizeof(conv_tables_t),
11442             G_ALLOC_ONLY);
11443 }
11444
11445 /* Max string length for displaying Unicode strings.  */
11446 #define MAX_UNICODE_STR_LEN     256
11447
11448
11449 /* Turn a little-endian Unicode '\0'-terminated string into a string we
11450    can display.
11451    XXX - for now, we just handle the ISO 8859-1 characters.
11452    If exactlen==TRUE then us_lenp contains the exact len of the string in
11453    bytes. It might not be null terminated !
11454    bc specifies the number of bytes in the byte parameters; Windows 2000,
11455    at least, appears, in some cases, to put only 1 byte of 0 at the end
11456    of a Unicode string if the byte count
11457 */
11458 static gchar *
11459 unicode_to_str(tvbuff_t *tvb, int offset, int *us_lenp, gboolean exactlen,
11460                    guint16 bc)
11461 {
11462   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
11463   static gchar *cur;
11464   gchar        *p;
11465   guint16       uchar;
11466   int           len;
11467   int           us_len;
11468   int           overflow = 0;
11469
11470   if (cur == &str[0][0]) {
11471     cur = &str[1][0];
11472   } else if (cur == &str[1][0]) {  
11473     cur = &str[2][0];
11474   } else {  
11475     cur = &str[0][0];
11476   }
11477   p = cur;
11478   len = MAX_UNICODE_STR_LEN;
11479   us_len = 0;
11480   for (;;) {
11481     if (bc == 0)
11482       break;
11483     if (bc == 1) {
11484       /* XXX - explain this */
11485       if (!exactlen)
11486         us_len += 1;    /* this is a one-byte null terminator */
11487       break;
11488     }
11489     uchar = tvb_get_letohs(tvb, offset);
11490     if (uchar == 0) {
11491       us_len += 2;      /* this is a two-byte null terminator */
11492       break;
11493     }
11494     if (len > 0) {
11495       if ((uchar & 0xFF00) == 0)
11496         *p++ = uchar;   /* ISO 8859-1 */
11497       else
11498         *p++ = '?';     /* not 8859-1 */
11499       len--;
11500     } else
11501       overflow = 1;
11502     offset += 2;
11503     bc -= 2;
11504     us_len += 2;
11505     if(exactlen){
11506       if(us_len>= *us_lenp){
11507         break;
11508       }
11509     }
11510   }
11511   if (overflow) {
11512     /* Note that we're not showing the full string.  */
11513     *p++ = '.';
11514     *p++ = '.';
11515     *p++ = '.';
11516   }
11517   *p = '\0';
11518   *us_lenp = us_len;
11519   return cur;
11520 }
11521  
11522
11523 /* nopad == TRUE : Do not add any padding before this string
11524  * exactlen == TRUE : len contains the exact len of the string in bytes.
11525  * bc: pointer to variable with amount of data left in the byte parameters
11526  *   region
11527  */
11528 static const gchar *
11529 get_unicode_or_ascii_string(tvbuff_t *tvb, int *offsetp,
11530     packet_info *pinfo, int *len, gboolean nopad, gboolean exactlen,
11531     guint16 *bcp)
11532 {
11533   static gchar  str[3][MAX_UNICODE_STR_LEN+3+1];
11534   static gchar *cur;
11535   int offset = *offsetp;
11536   const gchar *string;
11537   int string_len;
11538   smb_info_t *si;
11539   int copylen;
11540
11541   if (*bcp == 0) {
11542     /* Not enough data in buffer */
11543     return NULL;
11544   }
11545   si = pinfo->private_data;
11546   if (si->unicode) {
11547     if ((!nopad) && (*offsetp % 2)) {
11548       /*
11549        * XXX - this should be an offset relative to the beginning of the SMB,
11550        * not an offset relative to the beginning of the frame; if the stuff
11551        * before the SMB has an odd number of bytes, an offset relative to
11552        * the beginning of the frame will give the wrong answer.
11553        */
11554       (*offsetp)++;   /* Looks like a pad byte there sometimes */
11555       (*bcp)--;
11556       if (*bcp == 0) {
11557         /* Not enough data in buffer */
11558         return NULL;
11559       }
11560     }
11561     if(exactlen){
11562       string_len = *len;
11563       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
11564     } else {
11565       string = unicode_to_str(tvb, *offsetp, &string_len, exactlen, *bcp);
11566     }
11567   } else {
11568     if(exactlen){
11569       /*
11570        * The string we return must be null-terminated.
11571        */
11572       if (cur == &str[0][0]) {
11573         cur = &str[1][0];
11574       } else if (cur == &str[1][0]) {  
11575         cur = &str[2][0];
11576       } else {  
11577         cur = &str[0][0];
11578       }
11579       copylen = *len;
11580       if (copylen > MAX_UNICODE_STR_LEN)
11581         copylen = MAX_UNICODE_STR_LEN;
11582       tvb_memcpy(tvb, (guint8 *)cur, *offsetp, copylen);
11583       cur[copylen] = '\0';
11584       if (copylen > MAX_UNICODE_STR_LEN)
11585         strcat(cur, "...");
11586       string_len = *len;
11587       string = cur;
11588     } else {
11589       string_len = tvb_strsize(tvb, *offsetp);
11590       string = tvb_get_ptr(tvb, *offsetp, string_len);
11591     }
11592   }
11593   *len = string_len;
11594   return string;
11595 }
11596
11597
11598
11599 static const value_string errcls_types[] = {
11600   { SMB_SUCCESS, "Success"},
11601   { SMB_ERRDOS, "DOS Error"},
11602   { SMB_ERRSRV, "Server Error"},
11603   { SMB_ERRHRD, "Hardware Error"},
11604   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
11605   { 0, NULL }
11606 };
11607
11608 static const value_string DOS_errors[] = {
11609   {SMBE_badfunc, "Invalid function (or system call)"},
11610   {SMBE_badfile, "File not found (pathname error)"},
11611   {SMBE_badpath, "Directory not found"},
11612   {SMBE_nofids, "Too many open files"},
11613   {SMBE_noaccess, "Access denied"},
11614   {SMBE_badfid, "Invalid fid"},
11615   {SMBE_nomem,  "Out of memory"},
11616   {SMBE_badmem, "Invalid memory block address"},
11617   {SMBE_badenv, "Invalid environment"},
11618   {SMBE_badaccess, "Invalid open mode"},
11619   {SMBE_baddata, "Invalid data (only from ioctl call)"},
11620   {SMBE_res, "Reserved error code?"}, 
11621   {SMBE_baddrive, "Invalid drive"},
11622   {SMBE_remcd, "Attempt to delete current directory"},
11623   {SMBE_diffdevice, "Rename/move across different filesystems"},
11624   {SMBE_nofiles, "No more files found in file search"},
11625   {SMBE_badshare, "Share mode on file conflict with open mode"},
11626   {SMBE_lock, "Lock request conflicts with existing lock"},
11627   {SMBE_unsup, "Request unsupported, returned by Win 95"},
11628   {SMBE_nosuchshare, "Requested share does not exist"},
11629   {SMBE_filexists, "File in operation already exists"},
11630   {SMBE_cannotopen, "Cannot open the file specified"},
11631   {SMBE_unknownlevel, "Unknown level??"},
11632   {SMBE_badpipe, "Named pipe invalid"},
11633   {SMBE_pipebusy, "All instances of pipe are busy"},
11634   {SMBE_pipeclosing, "Named pipe close in progress"},
11635   {SMBE_notconnected, "No process on other end of named pipe"},
11636   {SMBE_moredata, "More data to be returned"},
11637   {SMBE_baddirectory,  "Invalid directory name in a path."},
11638   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
11639   {SMBE_eas_nsup, "Extended attributes not supported"},
11640   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
11641   {SMBE_unknownipc, "Unknown IPC Operation"},
11642   {SMBE_noipc, "Don't support ipc"},
11643   {0, NULL}
11644   };
11645
11646 /* Error codes for the ERRSRV class */
11647
11648 static const value_string SRV_errors[] = {
11649   {SMBE_error, "Non specific error code"},
11650   {SMBE_badpw, "Bad password"},
11651   {SMBE_badtype, "Reserved"},
11652   {SMBE_access, "No permissions to perform the requested operation"},
11653   {SMBE_invnid, "TID invalid"},
11654   {SMBE_invnetname, "Invalid network name. Service not found"},
11655   {SMBE_invdevice, "Invalid device"},
11656   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
11657   {SMBE_qfull, "Print queue full"},
11658   {SMBE_qtoobig, "Queued item too big"},
11659   {SMBE_qeof, "EOF on print queue dump"},
11660   {SMBE_invpfid, "Invalid print file in smb_fid"},
11661   {SMBE_smbcmd, "Unrecognised command"},
11662   {SMBE_srverror, "SMB server internal error"},
11663   {SMBE_filespecs, "Fid and pathname invalid combination"},
11664   {SMBE_badlink, "Bad link in request ???"},
11665   {SMBE_badpermits, "Access specified for a file is not valid"},
11666   {SMBE_badpid, "Bad process id in request"},
11667   {SMBE_setattrmode, "Attribute mode invalid"},
11668   {SMBE_paused, "Message server paused"},
11669   {SMBE_msgoff, "Not receiving messages"},
11670   {SMBE_noroom, "No room for message"},
11671   {SMBE_rmuns, "Too many remote usernames"},
11672   {SMBE_timeout, "Operation timed out"},
11673   {SMBE_noresource, "No resources currently available for request."},
11674   {SMBE_toomanyuids, "Too many userids"},
11675   {SMBE_baduid, "Bad userid"},
11676   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
11677   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
11678   {SMBE_contMPX, "Resume MPX mode"},
11679   {SMBE_badPW, "Bad Password???"},
11680   {SMBE_nosupport, "Operation not supported"},
11681   { 0, NULL}
11682 };
11683
11684 /* Error codes for the ERRHRD class */
11685
11686 static const value_string HRD_errors[] = {
11687   {SMBE_nowrite, "Read only media"},
11688   {SMBE_badunit, "Unknown device"},
11689   {SMBE_notready, "Drive not ready"},
11690   {SMBE_badcmd, "Unknown command"},
11691   {SMBE_data, "Data (CRC) error"},
11692   {SMBE_badreq, "Bad request structure length"},
11693   {SMBE_seek, "Seek error???"},
11694   {SMBE_badmedia, "Bad media???"},
11695   {SMBE_badsector, "Bad sector???"},
11696   {SMBE_nopaper, "No paper in printer???"},
11697   {SMBE_write, "Write error???"},
11698   {SMBE_read, "Read error???"},
11699   {SMBE_general, "General error???"},
11700   {SMBE_badshare, "A open conflicts with an existing open"},
11701   {SMBE_lock, "Lock/unlock error"},
11702   {SMBE_wrongdisk,  "Wrong disk???"},
11703   {SMBE_FCBunavail, "FCB unavailable???"},
11704   {SMBE_sharebufexc, "Share buffer excluded???"},
11705   {SMBE_diskfull, "Disk full???"},
11706   {0, NULL}
11707 };
11708
11709 static char *decode_smb_error(guint8 errcls, guint16 errcode)
11710 {
11711
11712   switch (errcls) {
11713
11714   case SMB_SUCCESS:
11715
11716     return("No Error");   /* No error ??? */
11717     break;
11718
11719   case SMB_ERRDOS:
11720
11721     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
11722     break;
11723
11724   case SMB_ERRSRV:
11725
11726     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
11727     break;
11728
11729   case SMB_ERRHRD:
11730
11731     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
11732     break;
11733
11734   default:
11735
11736     return("Unknown error class!");
11737
11738   }
11739
11740 }
11741
11742 /*
11743  * NT error codes.
11744  *
11745  * From
11746  *
11747  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
11748  */
11749 static const value_string NT_errors[] = {
11750   { 0x00000000, "STATUS_SUCCESS" },
11751   { 0x00000000, "STATUS_WAIT_0" },
11752   { 0x00000001, "STATUS_WAIT_1" },
11753   { 0x00000002, "STATUS_WAIT_2" },
11754   { 0x00000003, "STATUS_WAIT_3" },
11755   { 0x0000003F, "STATUS_WAIT_63" },
11756   { 0x00000080, "STATUS_ABANDONED" },
11757   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
11758   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
11759   { 0x000000C0, "STATUS_USER_APC" },
11760   { 0x00000100, "STATUS_KERNEL_APC" },
11761   { 0x00000101, "STATUS_ALERTED" },
11762   { 0x00000102, "STATUS_TIMEOUT" },
11763   { 0x00000103, "STATUS_PENDING" },
11764   { 0x00000104, "STATUS_REPARSE" },
11765   { 0x00000105, "STATUS_MORE_ENTRIES" },
11766   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
11767   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
11768   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
11769   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
11770   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
11771   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
11772   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
11773   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
11774   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
11775   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
11776   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
11777   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
11778   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
11779   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
11780   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
11781   { 0x00000116, "STATUS_CRASH_DUMP" },
11782   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
11783   { 0x00000118, "STATUS_REPARSE_OBJECT" },
11784   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
11785   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
11786   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
11787   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
11788   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
11789   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
11790   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
11791   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
11792   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
11793   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
11794   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
11795   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
11796   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
11797   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
11798   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
11799   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
11800   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
11801   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
11802   { 0x40000012, "STATUS_EVENT_DONE" },
11803   { 0x40000013, "STATUS_EVENT_PENDING" },
11804   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
11805   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
11806   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
11807   { 0x40000017, "STATUS_WAS_UNLOCKED" },
11808   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
11809   { 0x40000019, "STATUS_WAS_LOCKED" },
11810   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
11811   { 0x4000001B, "STATUS_ALREADY_WIN32" },
11812   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
11813   { 0x4000001D, "STATUS_WX86_CONTINUE" },
11814   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
11815   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
11816   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
11817   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
11818   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
11819   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
11820   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
11821   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
11822   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
11823   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
11824   { 0x80000003, "STATUS_BREAKPOINT" },
11825   { 0x80000004, "STATUS_SINGLE_STEP" },
11826   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
11827   { 0x80000006, "STATUS_NO_MORE_FILES" },
11828   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
11829   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
11830   { 0x8000000B, "STATUS_NO_INHERITANCE" },
11831   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
11832   { 0x8000000D, "STATUS_PARTIAL_COPY" },
11833   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
11834   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
11835   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
11836   { 0x80000011, "STATUS_DEVICE_BUSY" },
11837   { 0x80000012, "STATUS_NO_MORE_EAS" },
11838   { 0x80000013, "STATUS_INVALID_EA_NAME" },
11839   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
11840   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
11841   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
11842   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
11843   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
11844   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
11845   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
11846   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
11847   { 0x8000001D, "STATUS_BUS_RESET" },
11848   { 0x8000001E, "STATUS_END_OF_MEDIA" },
11849   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
11850   { 0x80000020, "STATUS_MEDIA_CHECK" },
11851   { 0x80000021, "STATUS_SETMARK_DETECTED" },
11852   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
11853   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
11854   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
11855   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
11856   { 0x80000026, "STATUS_LONGJUMP" },
11857   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
11858   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
11859   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
11860   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
11861   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
11862   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
11863   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
11864   { 0xC0000008, "STATUS_INVALID_HANDLE" },
11865   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
11866   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
11867   { 0xC000000B, "STATUS_INVALID_CID" },
11868   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
11869   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
11870   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
11871   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
11872   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
11873   { 0xC0000011, "STATUS_END_OF_FILE" },
11874   { 0xC0000012, "STATUS_WRONG_VOLUME" },
11875   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
11876   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
11877   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
11878   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
11879   { 0xC0000017, "STATUS_NO_MEMORY" },
11880   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
11881   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
11882   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
11883   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
11884   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
11885   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
11886   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
11887   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
11888   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
11889   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
11890   { 0xC0000022, "STATUS_ACCESS_DENIED" },
11891   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
11892   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
11893   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
11894   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
11895   { 0xC0000027, "STATUS_UNWIND" },
11896   { 0xC0000028, "STATUS_BAD_STACK" },
11897   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
11898   { 0xC000002A, "STATUS_NOT_LOCKED" },
11899   { 0xC000002B, "STATUS_PARITY_ERROR" },
11900   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
11901   { 0xC000002D, "STATUS_NOT_COMMITTED" },
11902   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
11903   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
11904   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
11905   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
11906   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
11907   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
11908   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
11909   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
11910   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
11911   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
11912   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
11913   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
11914   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
11915   { 0xC000003C, "STATUS_DATA_OVERRUN" },
11916   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
11917   { 0xC000003E, "STATUS_DATA_ERROR" },
11918   { 0xC000003F, "STATUS_CRC_ERROR" },
11919   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
11920   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
11921   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
11922   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
11923   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
11924   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
11925   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
11926   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
11927   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
11928   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
11929   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
11930   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
11931   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
11932   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
11933   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
11934   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
11935   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
11936   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
11937   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
11938   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
11939   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
11940   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
11941   { 0xC0000056, "STATUS_DELETE_PENDING" },
11942   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
11943   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
11944   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
11945   { 0xC000005A, "STATUS_INVALID_OWNER" },
11946   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
11947   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
11948   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
11949   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
11950   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
11951   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
11952   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
11953   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
11954   { 0xC0000063, "STATUS_USER_EXISTS" },
11955   { 0xC0000064, "STATUS_NO_SUCH_USER" },
11956   { 0xC0000065, "STATUS_GROUP_EXISTS" },
11957   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
11958   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
11959   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
11960   { 0xC0000069, "STATUS_LAST_ADMIN" },
11961   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
11962   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
11963   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
11964   { 0xC000006D, "STATUS_LOGON_FAILURE" },
11965   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
11966   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
11967   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
11968   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
11969   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
11970   { 0xC0000073, "STATUS_NONE_MAPPED" },
11971   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
11972   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
11973   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
11974   { 0xC0000077, "STATUS_INVALID_ACL" },
11975   { 0xC0000078, "STATUS_INVALID_SID" },
11976   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
11977   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
11978   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
11979   { 0xC000007C, "STATUS_NO_TOKEN" },
11980   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
11981   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
11982   { 0xC000007F, "STATUS_DISK_FULL" },
11983   { 0xC0000080, "STATUS_SERVER_DISABLED" },
11984   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
11985   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
11986   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
11987   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
11988   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
11989   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
11990   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
11991   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
11992   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
11993   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
11994   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
11995   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
11996   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
11997   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
11998   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
11999   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
12000   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
12001   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
12002   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
12003   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
12004   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
12005   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
12006   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
12007   { 0xC0000098, "STATUS_FILE_INVALID" },
12008   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
12009   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
12010   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
12011   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
12012   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
12013   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
12014   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
12015   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
12016   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
12017   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
12018   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
12019   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
12020   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
12021   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
12022   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
12023   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
12024   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
12025   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
12026   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
12027   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
12028   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
12029   { 0xC00000AE, "STATUS_PIPE_BUSY" },
12030   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
12031   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
12032   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
12033   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
12034   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
12035   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
12036   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
12037   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
12038   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
12039   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
12040   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
12041   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
12042   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
12043   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
12044   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
12045   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
12046   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
12047   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
12048   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
12049   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
12050   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
12051   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
12052   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
12053   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
12054   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
12055   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
12056   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
12057   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
12058   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
12059   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
12060   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
12061   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
12062   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
12063   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
12064   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
12065   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
12066   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
12067   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
12068   { 0xC00000D5, "STATUS_FILE_RENAMED" },
12069   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
12070   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
12071   { 0xC00000D8, "STATUS_CANT_WAIT" },
12072   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
12073   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
12074   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
12075   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
12076   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
12077   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
12078   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
12079   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
12080   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
12081   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
12082   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
12083   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
12084   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
12085   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
12086   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
12087   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
12088   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
12089   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
12090   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
12091   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
12092   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
12093   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
12094   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
12095   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
12096   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
12097   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
12098   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
12099   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
12100   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
12101   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
12102   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
12103   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
12104   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
12105   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
12106   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
12107   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
12108   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
12109   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
12110   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
12111   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
12112   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
12113   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
12114   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
12115   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
12116   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
12117   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
12118   { 0xC0000107, "STATUS_FILES_OPEN" },
12119   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
12120   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
12121   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
12122   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
12123   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
12124   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
12125   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
12126   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
12127   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
12128   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
12129   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
12130   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
12131   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
12132   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
12133   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
12134   { 0xC0000117, "STATUS_NO_LDT" },
12135   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
12136   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
12137   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
12138   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
12139   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
12140   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
12141   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
12142   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
12143   { 0xC0000120, "STATUS_CANCELLED" },
12144   { 0xC0000121, "STATUS_CANNOT_DELETE" },
12145   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
12146   { 0xC0000123, "STATUS_FILE_DELETED" },
12147   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
12148   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
12149   { 0xC0000126, "STATUS_SPECIAL_USER" },
12150   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
12151   { 0xC0000128, "STATUS_FILE_CLOSED" },
12152   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
12153   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
12154   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
12155   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
12156   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
12157   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
12158   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
12159   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
12160   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
12161   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
12162   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
12163   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
12164   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
12165   { 0xC0000136, "STATUS_OPEN_FAILED" },
12166   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
12167   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
12168   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
12169   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
12170   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
12171   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
12172   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
12173   { 0xC000013E, "STATUS_LINK_FAILED" },
12174   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
12175   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
12176   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
12177   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
12178   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
12179   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
12180   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
12181   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
12182   { 0xC0000147, "STATUS_NO_PAGEFILE" },
12183   { 0xC0000148, "STATUS_INVALID_LEVEL" },
12184   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
12185   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
12186   { 0xC000014B, "STATUS_PIPE_BROKEN" },
12187   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
12188   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
12189   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
12190   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
12191   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
12192   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
12193   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
12194   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
12195   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
12196   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
12197   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
12198   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
12199   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
12200   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
12201   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
12202   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
12203   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
12204   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
12205   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
12206   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
12207   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
12208   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
12209   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
12210   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
12211   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
12212   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
12213   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
12214   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
12215   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
12216   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
12217   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
12218   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
12219   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
12220   { 0xC000016D, "STATUS_FT_ORPHANING" },
12221   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
12222   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
12223   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
12224   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
12225   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
12226   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
12227   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
12228   { 0xC0000178, "STATUS_NO_MEDIA" },
12229   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
12230   { 0xC000017B, "STATUS_INVALID_MEMBER" },
12231   { 0xC000017C, "STATUS_KEY_DELETED" },
12232   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
12233   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
12234   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
12235   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
12236   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
12237   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
12238   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
12239   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
12240   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
12241   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
12242   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
12243   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
12244   { 0xC0000189, "STATUS_TOO_LATE" },
12245   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
12246   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
12247   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
12248   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
12249   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
12250   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
12251   { 0xC0000190, "STATUS_TRUST_FAILURE" },
12252   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
12253   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
12254   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
12255   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
12256   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
12257   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
12258   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
12259   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
12260   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
12261   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
12262   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
12263   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
12264   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
12265   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
12266   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
12267   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
12268   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
12269   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
12270   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
12271   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
12272   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
12273   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
12274   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
12275   { 0xC000020D, "STATUS_CONNECTION_RESET" },
12276   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
12277   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
12278   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
12279   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
12280   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
12281   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
12282   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
12283   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
12284   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
12285   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
12286   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
12287   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
12288   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
12289   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
12290   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
12291   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
12292   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
12293   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
12294   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
12295   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
12296   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
12297   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
12298   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
12299   { 0xC0000225, "STATUS_NOT_FOUND" },
12300   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
12301   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
12302   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
12303   { 0xC0000229, "STATUS_FAIL_CHECK" },
12304   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
12305   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
12306   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
12307   { 0xC000022D, "STATUS_RETRY" },
12308   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
12309   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
12310   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
12311   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
12312   { 0xC0000232, "STATUS_INVALID_VARIANT" },
12313   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
12314   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
12315   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
12316   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
12317   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
12318   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
12319   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
12320   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
12321   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
12322   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
12323   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
12324   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
12325   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
12326   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
12327   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
12328   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
12329   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
12330   { 0xC0000244, "STATUS_AUDIT_FAILED" },
12331   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
12332   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
12333   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
12334   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
12335   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
12336   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
12337   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
12338   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
12339   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
12340   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
12341   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
12342   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
12343   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
12344   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
12345   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
12346   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
12347   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
12348   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
12349   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
12350   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
12351   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
12352   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
12353   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
12354   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
12355   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
12356   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
12357   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
12358   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
12359   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
12360   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
12361   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
12362   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
12363   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
12364   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
12365   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
12366   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
12367   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
12368   { 0xC0009898, "STATUS_WOW_ASSERTION" },
12369   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
12370   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
12371   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
12372   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
12373   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
12374   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
12375   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
12376   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
12377   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
12378   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
12379   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
12380   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
12381   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
12382   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
12383   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
12384   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
12385   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
12386   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
12387   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
12388   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
12389   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
12390   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
12391   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
12392   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
12393   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
12394   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
12395   { 0xC002001B, "RPC_NT_CALL_FAILED" },
12396   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
12397   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
12398   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
12399   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
12400   { 0xC0020022, "RPC_NT_INVALID_TAG" },
12401   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
12402   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
12403   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
12404   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
12405   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
12406   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
12407   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
12408   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
12409   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
12410   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
12411   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
12412   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
12413   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
12414   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
12415   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
12416   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
12417   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
12418   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
12419   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
12420   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
12421   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
12422   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
12423   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
12424   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
12425   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
12426   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
12427   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
12428   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
12429   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
12430   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
12431   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
12432   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
12433   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
12434   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
12435   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
12436   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
12437   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
12438   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
12439   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
12440   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
12441   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
12442   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
12443   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
12444   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
12445   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
12446   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
12447   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
12448   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
12449   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
12450   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
12451   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
12452   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
12453   { 0xC002004C, "EPT_NT_CANT_CREATE" },
12454   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
12455   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
12456   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
12457   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
12458   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
12459   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
12460   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
12461   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
12462   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
12463   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
12464   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
12465   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
12466   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
12467   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
12468   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
12469   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
12470   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
12471   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
12472   { 0,          NULL }
12473 };
12474
12475
12476
12477 static const true_false_string tfs_smb_flags_lock = {
12478         "Lock&Read, Write&Unlock are supported",
12479         "Lock&Read, Write&Unlock are not supported"
12480 };
12481 static const true_false_string tfs_smb_flags_receive_buffer = {
12482         "Receive buffer has been posted",
12483         "Receive buffer has not been posted"
12484 };
12485 static const true_false_string tfs_smb_flags_caseless = {
12486         "Path names are caseless",
12487         "Path names are case sensitive"
12488 };
12489 static const true_false_string tfs_smb_flags_canon = {
12490         "Pathnames are canonicalized",
12491         "Pathnames are not canonicalized"
12492 };
12493 static const true_false_string tfs_smb_flags_oplock = {
12494         "OpLock requested/granted",
12495         "OpLock not requested/granted"
12496 };
12497 static const true_false_string tfs_smb_flags_notify = {
12498         "Notify client on all modifications",
12499         "Notify client only on open"
12500 };
12501 static const true_false_string tfs_smb_flags_response = {
12502         "Message is a response to the client/redirector",
12503         "Message is a request to the server"
12504 };
12505
12506 static int
12507 dissect_smb_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
12508 {
12509         guint8 mask;
12510         proto_item *item = NULL;
12511         proto_tree *tree = NULL;
12512
12513         mask = tvb_get_guint8(tvb, offset);
12514
12515         if(parent_tree){
12516                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
12517                         "Flags: 0x%02x", mask);
12518                 tree = proto_item_add_subtree(item, ett_smb_flags);
12519         }
12520         proto_tree_add_boolean(tree, hf_smb_flags_response,
12521                 tvb, offset, 1, mask);
12522         proto_tree_add_boolean(tree, hf_smb_flags_notify,
12523                 tvb, offset, 1, mask);
12524         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
12525                 tvb, offset, 1, mask);
12526         proto_tree_add_boolean(tree, hf_smb_flags_canon,
12527                 tvb, offset, 1, mask);
12528         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
12529                 tvb, offset, 1, mask);
12530         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
12531                 tvb, offset, 1, mask);
12532         proto_tree_add_boolean(tree, hf_smb_flags_lock,
12533                 tvb, offset, 1, mask);
12534         offset += 1;
12535         return offset;
12536 }
12537
12538
12539  
12540 static const true_false_string tfs_smb_flags2_long_names_allowed = {
12541         "Long file names are allowed in the response",
12542         "Long file names are not allowed in the response"
12543 };
12544 static const true_false_string tfs_smb_flags2_ea = {
12545         "Extended attributes are supported",
12546         "Extended attributes are not supported"
12547 };
12548 static const true_false_string tfs_smb_flags2_sec_sig = {
12549         "Security signatures are supported",
12550         "Security signatures are not supported"
12551 };
12552 static const true_false_string tfs_smb_flags2_long_names_used = {
12553         "Path names in request are long file names",
12554         "Path names in request are not long file names"
12555 };
12556 static const true_false_string tfs_smb_flags2_esn = {
12557         "Extended security negotiation is supported",
12558         "Extended security negotiation is not supported"
12559 };
12560 static const true_false_string tfs_smb_flags2_dfs = {
12561         "Resolve pathnames with Dfs",
12562         "Don't resolve pathnames with Dfs"
12563 };
12564 static const true_false_string tfs_smb_flags2_roe = {
12565         "Permit reads if execute-only",
12566         "Don't permit reads if execute-only"
12567 };
12568 static const true_false_string tfs_smb_flags2_nt_error = {
12569         "Error codes are NT error codes",
12570         "Error codes are DOS error codes"
12571 };
12572 static const true_false_string tfs_smb_flags2_string = {
12573         "Strings are Unicode",
12574         "Strings are ASCII"
12575 };
12576 static int
12577 dissect_smb_flags2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
12578 {
12579         guint16 mask;
12580         proto_item *item = NULL;
12581         proto_tree *tree = NULL;
12582
12583         mask = tvb_get_letohs(tvb, offset);
12584
12585         if(parent_tree){
12586                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
12587                         "Flags2: 0x%04x", mask);
12588                 tree = proto_item_add_subtree(item, ett_smb_flags2);
12589         }
12590
12591         proto_tree_add_boolean(tree, hf_smb_flags2_string,
12592                 tvb, offset, 2, mask);
12593         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
12594                 tvb, offset, 2, mask);
12595         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
12596                 tvb, offset, 2, mask);
12597         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
12598                 tvb, offset, 2, mask);
12599         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
12600                 tvb, offset, 2, mask);
12601         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
12602                 tvb, offset, 2, mask);
12603         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
12604                 tvb, offset, 2, mask);
12605         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
12606                 tvb, offset, 2, mask);
12607         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
12608                 tvb, offset, 2, mask);
12609
12610         offset += 2;
12611         return offset;
12612 }
12613
12614
12615
12616 #define SMB_FLAGS_DIRN 0x80
12617
12618
12619 static gboolean
12620 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
12621 {
12622         int offset = 0;
12623         proto_item *item = NULL, *hitem = NULL;
12624         proto_tree *tree = NULL, *htree = NULL;
12625         guint8          flags;
12626         guint16         flags2;
12627         smb_info_t      si;
12628         smb_saved_info_t        *sip = NULL;
12629         proto_item *cmd_item = NULL;
12630         proto_tree *cmd_tree = NULL;
12631         guint32 nt_status = 0;
12632         guint8 errclass = 0;
12633         guint16 errcode = 0;
12634         guint16 uid, pid, tid;
12635
12636         top_tree=parent_tree;
12637
12638         /* must check that this really is a smb packet */
12639         if (!tvb_bytes_exist(tvb, 0, 4))
12640                 return FALSE;
12641
12642         if( (tvb_get_guint8(tvb, 0) != 0xff)
12643             || (tvb_get_guint8(tvb, 1) != 'S')
12644             || (tvb_get_guint8(tvb, 2) != 'M')
12645             || (tvb_get_guint8(tvb, 3) != 'B') ){
12646                 return FALSE;
12647         }
12648          
12649         if (check_col(pinfo->fd, COL_PROTOCOL)){
12650                 col_set_str(pinfo->fd, COL_PROTOCOL, "SMB");
12651         }
12652         if (check_col(pinfo->fd, COL_INFO)){
12653                 col_clear(pinfo->fd, COL_INFO);
12654         }
12655
12656         /* start off using the local variable, we will allocate a new one if we
12657            need to*/
12658         si.mid = tvb_get_letohs(tvb, offset+30);
12659         uid = tvb_get_letohs(tvb, offset+28);
12660         pid = tvb_get_letohs(tvb, offset+26);
12661         tid = tvb_get_letohs(tvb, offset+24);
12662         flags2 = tvb_get_letohs(tvb, offset+10);
12663         if(flags2 & 0x8000){
12664                 si.unicode = TRUE; /* Mark them as Unicode */
12665         } else {
12666                 si.unicode = FALSE;
12667         }
12668         flags = tvb_get_guint8(tvb, offset+9);
12669         si.request = !(flags&SMB_FLAGS_DIRN);
12670         si.cmd = tvb_get_guint8(tvb, offset+4);
12671         si.info_count = -1;
12672
12673         if (parent_tree) {
12674                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset, 
12675                         tvb_length_remaining(tvb, 0), FALSE);
12676                 tree = proto_item_add_subtree(item, ett_smb);
12677
12678                 hitem = proto_tree_add_text(tree, tvb, offset, 32, 
12679                         "SMB Header");
12680
12681                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
12682         }
12683
12684         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
12685         offset += 4;  /* Skip the marker */
12686
12687
12688         if( (si.request)
12689             &&  (si.mid==0)
12690             &&  (uid==0)
12691             &&  (pid==0)
12692             &&  (tid==0) ){
12693                 /* this is a broadcast SMB packet, there will not be a reply.
12694                    We dont need to do anything 
12695                 */
12696                 si.unidir = TRUE;
12697         } else {
12698                 conversation_t *conversation;
12699                 conv_tables_t *ct;
12700
12701                 si.unidir = FALSE;
12702
12703                 /* first we try to find which conversation this packet is 
12704                    part of 
12705                 */
12706                 conversation = find_conversation(&pinfo->src, &pinfo->dst,
12707                          pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
12708                 if(conversation==NULL){
12709                         /* OK this is a new conversation, we must create it
12710                            and attach appropriate data (matched and unmatched 
12711                            table for this conversation)
12712                         */
12713                         conversation = conversation_new(&pinfo->src, &pinfo->dst, 
12714                                 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
12715                         ct = g_mem_chunk_alloc(conv_tables_chunk);
12716                         ct->matched= g_hash_table_new(smb_saved_info_hash_matched, 
12717                                 smb_saved_info_equal_matched);          
12718                         ct->unmatched= g_hash_table_new(smb_saved_info_hash_matched, 
12719                                 smb_saved_info_equal_matched);          
12720                         conversation_add_proto_data(conversation, proto_smb, ct);
12721                 } else {
12722                         /* this is an old conversation, just get the tables */
12723                         ct=conversation_get_proto_data(conversation, proto_smb);
12724                 }
12725                 if(!pinfo->fd->flags.visited){
12726                         /* first see if we find an unmatched smb "equal" to 
12727                            the current one 
12728                         */
12729                         sip=g_hash_table_lookup(ct->unmatched, (void *)si.mid);
12730                         if(sip!=NULL){
12731                                 if(si.request){
12732                                         /* ok, we are processing an SMB
12733                                            request but there was already
12734                                            another "identical" smb resuest
12735                                            we had not matched yet.
12736                                            This must mean that either we have
12737                                            a retransmission or that the
12738                                            response to the previous one was
12739                                            lost and the client has reused
12740                                            the MID for this conversation.
12741                                            In either case it's not much more
12742                                            we can do than forget the old
12743                                            request and concentrate on the 
12744                                            present one instead.
12745
12746                                            An exception is made for NT
12747                                            Cancel.  A Cancel request has
12748                                            the same TID/PID/MID/UID as
12749                                            the request to be cancelled;
12750                                            in that case, we leave the
12751                                            old request in place, that
12752                                            being the request being
12753                                            cancelled.
12754                                         */
12755                                         if (si.cmd != 0xa4) {
12756                                                 /*
12757                                                  * Not NT Cancel.
12758                                                  * Remove the old entry.
12759                                                  */
12760                                                 g_hash_table_remove(ct->unmatched, (void *)si.mid);
12761                                         }
12762                                 } else {
12763                                         /* we have found a response to some request we have seen earlier.
12764                                            What we do now depends on whether this is the first response
12765                                            to that request we see (id frame_res==0) or not. 
12766                                         */
12767                                         if(sip->frame_res==0){
12768                                                 /* ok it is the first response we have seen to this packet */
12769                                                 sip->frame_res = pinfo->fd->num;
12770                                                 g_hash_table_insert(ct->matched, (void *)sip->frame_req, sip);
12771                                                 g_hash_table_insert(ct->matched, (void *)sip->frame_res, sip);
12772                                         } else {
12773                                                 /* we have already seen another response to this one, but
12774                                                    register it anyway so we see which request it matches 
12775                                                 */
12776                                                 g_hash_table_insert(ct->matched, (void *)pinfo->fd->num, sip);
12777                                         }
12778                                 }
12779                         }
12780                         if(si.request && si.cmd != 0xa4){
12781                                 /*
12782                                  * A request, and not an NT Cancel request.
12783                                  * If we found a "smb_saved_info_t"
12784                                  * for this request, we removed it, and
12785                                  * we should allocate and fill in a new
12786                                  * one.
12787                                  */
12788                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
12789                                 sip->frame_req = pinfo->fd->num;
12790                                 sip->frame_res = 0;
12791                                 sip->extra_info = NULL;
12792                                 g_hash_table_insert(ct->unmatched, (void *)si.mid, sip);
12793                         }
12794                 } else {
12795                         /* we have seen this packet before; check the
12796                            matching table
12797                         */
12798                         sip=g_hash_table_lookup(ct->matched, (void *)pinfo->fd->num);
12799                         if (sip == NULL) {
12800                                 /*
12801                                  * We didn't find it.
12802                                  * If that's a request, it's because we haven't
12803                                  * yet seen the reply (either because we
12804                                  * don't have it, or because we haven't
12805                                  * dissected it yet - yes, that can happen
12806                                  * if, for example, we're rebuilding the
12807                                  * packet list, and we've added the packet
12808                                  * to the list, and it's made the selected
12809                                  * entry), so check the unmatched table.
12810                                  */
12811                                 if (si.request)
12812                                         sip=g_hash_table_lookup(ct->unmatched, (void *)si.mid);
12813                         }
12814                 }
12815         }
12816
12817         /*
12818          * Pass the "sip" on to subdissectors through "si".
12819          */
12820         si.sip = sip;
12821
12822         if (sip != NULL) {
12823                 /*
12824                  * Put in fields for the frame number of the frame to which
12825                  * this is a response or the frame with the response to this
12826                  * frame - if we know the frame number (i.e., it's not 0).
12827                  */
12828                 if(si.request){
12829                         if (si.cmd != 0xa4 && sip->frame_res != 0)
12830                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
12831                 } else {
12832                         if (sip->frame_req != 0)
12833                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
12834                 }
12835         }
12836
12837         /* smb command */
12838         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);
12839         offset += 1;
12840
12841         if(flags2 & 0x4000){
12842                 /* handle NT 32 bit error code */
12843
12844                 nt_status = tvb_get_letohl(tvb, offset);
12845
12846                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
12847                         TRUE);
12848                 offset += 4;
12849
12850         } else {
12851                 /* handle DOS error code & class */
12852                 errclass = tvb_get_guint8(tvb, offset);
12853                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
12854                         errclass);
12855                 offset += 1;
12856
12857                 /* reserved byte */
12858                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
12859                 offset += 1;
12860
12861                 /* error code */
12862                 /* XXX - the type of this field depends on the value of
12863                  * "errcls", so there is isn't a single value_string array
12864                  * fo it, so there can't be a single field for it.
12865                  */
12866                 errcode = tvb_get_letohs(tvb, offset);
12867                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
12868                         offset, 2, errcode, "Error Code: %s",
12869                         decode_smb_error(errclass, errcode));
12870                 offset += 2;
12871         }
12872
12873         /* flags */
12874         offset = dissect_smb_flags(tvb, pinfo, htree, offset);
12875
12876         /* flags2 */
12877         offset = dissect_smb_flags2(tvb, pinfo, htree, offset);
12878
12879         /*
12880          * The document at
12881          *
12882          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
12883          *
12884          * (a text version of "Microsoft Networks SMB FILE SHARING
12885          * PROTOCOL, Document Version 6.0p") says that:
12886          *
12887          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
12888          *      the "High Part of PID";
12889          *
12890          *      the next four bytes are reserved;
12891          *
12892          *      the next four bytes are, for SMB-over-IPX (with no
12893          *      NetBIOS involved) two bytes of Session ID and two bytes
12894          *      of SequenceNumber.
12895          *
12896          * If we ever implement SMB-over-IPX (which I suspect goes over
12897          * IPX sockets 0x0550, 0x0552, and maybe 0x0554, as per the
12898          * document in question), we'd probably want to have some way
12899          * to determine whether this is SMB-over-IPX or not (which could
12900          * be done by adding a PT_IPXSOCKET port type, having the
12901          * IPX dissector set "pinfo->srcport" and "pinfo->destport",
12902          * and having the SMB dissector check for a port type of
12903          * PT_IPXSOCKET and for "pinfo->match_port" being either
12904          * IPX_SOCKET_NWLINK_SMB_SERVER or IPX_SOCKET_NWLINK_SMB_REDIR
12905          * or, if it also uses 0x0554, IPX_SOCKET_NWLINK_SMB_MESSENGER).
12906          */
12907
12908         /* 12 reserved bytes */
12909         proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 12, TRUE);
12910         offset += 12;
12911
12912         /* TID */
12913         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, tid);
12914         offset += 2;
12915
12916         /* PID */
12917         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, pid);
12918         offset += 2;
12919
12920         /* UID */
12921         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, uid);
12922         offset += 2;
12923
12924         /* MID */
12925         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si.mid);
12926         offset += 2;
12927
12928         pinfo->private_data = &si;
12929         dissect_smb_command(tvb, pinfo, parent_tree, offset, tree, si.cmd);
12930
12931         /* Append error info from this packet to info string. */
12932         if (!si.request && check_col(pinfo->fd, COL_INFO)) {
12933                 if (flags2 & 0x4000) {
12934                         /*
12935                          * The status is an NT status code; was there
12936                          * an error?
12937                          */
12938                         if (nt_status != 0) {
12939                                 /*
12940                                  * Yes.
12941                                  */
12942                                 col_append_fstr(
12943                                         pinfo->fd, COL_INFO, ", Error: %s",
12944                                         val_to_str(nt_status, NT_errors, "%s"));
12945                         }
12946                 } else {
12947                         /*
12948                          * The status is a DOS error class and code; was
12949                          * there an error?
12950                          */
12951                         if (errclass != SMB_SUCCESS) {
12952                                 /*
12953                                  * Yes.
12954                                  */
12955                                 col_append_fstr(
12956                                         pinfo->fd, COL_INFO, ", Error: %s",
12957                                         decode_smb_error(errclass, errcode));
12958                         }
12959                 }
12960         }
12961
12962         return TRUE;
12963 }
12964
12965 void
12966 proto_register_smb(void)
12967 {
12968         static hf_register_info hf[] = {
12969         { &hf_smb_cmd,
12970                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
12971                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
12972
12973         { &hf_smb_word_count,
12974                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
12975                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
12976
12977         { &hf_smb_byte_count,
12978                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
12979                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
12980
12981         { &hf_smb_response_to,
12982                 { "Response to", "smb.response_to", FT_UINT32, BASE_DEC,
12983                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
12984
12985         { &hf_smb_response_in,
12986                 { "Response in", "smb.response_in", FT_UINT32, BASE_DEC,
12987                 NULL, 0, "The response to this packet is in this packet", HFILL }},
12988
12989         { &hf_smb_nt_status,
12990                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
12991                 VALS(NT_errors), 0, "NT Status code", HFILL }},
12992
12993         { &hf_smb_error_class,
12994                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
12995                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
12996
12997         { &hf_smb_error_code,
12998                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
12999                 NULL, 0, "DOS Error Code", HFILL }},
13000
13001         { &hf_smb_reserved,
13002                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
13003                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
13004
13005         { &hf_smb_pid,
13006                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
13007                 NULL, 0, "Process ID", HFILL }},
13008
13009         { &hf_smb_tid,
13010                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
13011                 NULL, 0, "Tree ID", HFILL }},
13012
13013         { &hf_smb_uid,
13014                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
13015                 NULL, 0, "User ID", HFILL }},
13016
13017         { &hf_smb_mid,
13018                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
13019                 NULL, 0, "Multiplex ID", HFILL }},
13020
13021         { &hf_smb_flags_lock,
13022                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
13023                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
13024
13025         { &hf_smb_flags_receive_buffer,
13026                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
13027                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
13028
13029         { &hf_smb_flags_caseless,
13030                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
13031                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
13032
13033         { &hf_smb_flags_canon,
13034                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
13035                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
13036
13037         { &hf_smb_flags_oplock,
13038                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
13039                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
13040
13041         { &hf_smb_flags_notify,
13042                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
13043                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
13044
13045         { &hf_smb_flags_response,
13046                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
13047                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
13048
13049         { &hf_smb_flags2_long_names_allowed,
13050                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
13051                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
13052
13053         { &hf_smb_flags2_ea,
13054                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
13055                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
13056
13057         { &hf_smb_flags2_sec_sig,
13058                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
13059                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
13060
13061         { &hf_smb_flags2_long_names_used,
13062                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
13063                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
13064
13065         { &hf_smb_flags2_esn,
13066                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
13067                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
13068
13069         { &hf_smb_flags2_dfs,
13070                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
13071                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
13072
13073         { &hf_smb_flags2_roe,
13074                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
13075                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
13076
13077         { &hf_smb_flags2_nt_error,
13078                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
13079                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
13080
13081         { &hf_smb_flags2_string,
13082                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
13083                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
13084
13085         { &hf_smb_buffer_format,
13086                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
13087                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
13088
13089         { &hf_smb_dialect_name,
13090                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
13091                 NULL, 0, "Name of dialect", HFILL }},
13092
13093         { &hf_smb_dialect_index,
13094                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
13095                 NULL, 0, "Index of selected dialect", HFILL }},
13096
13097         { &hf_smb_max_trans_buf_size,
13098                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
13099                 NULL, 0, "Maximum transmit buffer size", HFILL }},
13100
13101         { &hf_smb_max_mpx_count,
13102                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
13103                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
13104
13105         { &hf_smb_max_vcs_num,
13106                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
13107                 NULL, 0, "Maximum VCs between client and server", HFILL }},
13108
13109         { &hf_smb_session_key,
13110                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
13111                 NULL, 0, "Unique token identifying this session", HFILL }},
13112
13113         { &hf_smb_server_timezone,
13114                 { "Time Zone", "smb.server.timezone", FT_INT16, BASE_DEC,
13115                 NULL, 0, "Current timezone at server.", HFILL }},
13116
13117         { &hf_smb_encryption_key_length,
13118                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
13119                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
13120
13121         { &hf_smb_encryption_key,
13122                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
13123                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
13124
13125         { &hf_smb_primary_domain,
13126                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
13127                 NULL, 0, "The server's primary domain", HFILL }},
13128
13129         { &hf_smb_max_raw_buf_size,
13130                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
13131                 NULL, 0, "Maximum raw buffer size", HFILL }},
13132
13133         { &hf_smb_server_guid,
13134                 { "Server GUID", "smb.server.guid", FT_BYTES, BASE_HEX,
13135                 NULL, 0, "Globally unique identifier for this server", HFILL }},
13136
13137         { &hf_smb_security_blob_len,
13138                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
13139                 NULL, 0, "Security blob length", HFILL }},
13140
13141         { &hf_smb_security_blob,
13142                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
13143                 NULL, 0, "Security blob", HFILL }},
13144
13145         { &hf_smb_sm_mode16,
13146                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
13147                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
13148
13149         { &hf_smb_sm_password16,
13150                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
13151                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
13152
13153         { &hf_smb_sm_mode,
13154                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
13155                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
13156
13157         { &hf_smb_sm_password,
13158                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
13159                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
13160
13161         { &hf_smb_sm_signatures,
13162                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
13163                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
13164
13165         { &hf_smb_sm_sig_required,
13166                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
13167                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
13168
13169         { &hf_smb_rm_read,
13170                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
13171                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
13172
13173         { &hf_smb_rm_write,
13174                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
13175                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
13176
13177         { &hf_smb_server_date_time,
13178                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
13179                 NULL, 0, "Current date and time at server", HFILL }},
13180
13181         { &hf_smb_server_smb_date,
13182                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
13183                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
13184
13185         { &hf_smb_server_smb_time,
13186                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
13187                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
13188
13189         { &hf_smb_server_cap_raw_mode,
13190                 { "Raw Mode", "smb.server.cap.raw_mode", FT_BOOLEAN, 32,
13191                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
13192
13193         { &hf_smb_server_cap_mpx_mode,
13194                 { "MPX Mode", "smb.server.cap.mpx_mode", FT_BOOLEAN, 32,
13195                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
13196
13197         { &hf_smb_server_cap_unicode,
13198                 { "Unicode", "smb.server.cap.unicode", FT_BOOLEAN, 32,
13199                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
13200
13201         { &hf_smb_server_cap_large_files,
13202                 { "Large Files", "smb.server.cap.large_files", FT_BOOLEAN, 32,
13203                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
13204
13205         { &hf_smb_server_cap_nt_smbs,
13206                 { "NT SMBs", "smb.server.cap.nt_smbs", FT_BOOLEAN, 32,
13207                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
13208
13209         { &hf_smb_server_cap_rpc_remote_apis,
13210                 { "RPC Remote APIs", "smb.server.cap.rpc_remote_apis", FT_BOOLEAN, 32,
13211                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
13212
13213         { &hf_smb_server_cap_nt_status,
13214                 { "NT Status Codes", "smb.server.cap.nt_status", FT_BOOLEAN, 32,
13215                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
13216
13217         { &hf_smb_server_cap_level_ii_oplocks,
13218                 { "Level 2 Oplocks", "smb.server.cap.level_2_oplocks", FT_BOOLEAN, 32,
13219                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
13220
13221         { &hf_smb_server_cap_lock_and_read,
13222                 { "Lock and Read", "smb.server.cap.lock_and_read", FT_BOOLEAN, 32,
13223                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
13224
13225         { &hf_smb_server_cap_nt_find,
13226                 { "NT Find", "smb.server.cap.nt_find", FT_BOOLEAN, 32,
13227                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
13228
13229         { &hf_smb_server_cap_dfs,
13230                 { "Dfs", "smb.server.cap.dfs", FT_BOOLEAN, 32,
13231                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
13232
13233         { &hf_smb_server_cap_infolevel_passthru,
13234                 { "Infolevel Passthru", "smb.server.cap.infolevel_passthru", FT_BOOLEAN, 32,
13235                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
13236
13237         { &hf_smb_server_cap_large_readx,
13238                 { "Large ReadX", "smb.server.cap.large_readx", FT_BOOLEAN, 32,
13239                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
13240
13241         { &hf_smb_server_cap_large_writex,
13242                 { "Large WriteX", "smb.server.cap.large_writex", FT_BOOLEAN, 32,
13243                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
13244
13245         { &hf_smb_server_cap_unix,
13246                 { "UNIX", "smb.server.cap.unix", FT_BOOLEAN, 32,
13247                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
13248
13249         { &hf_smb_server_cap_reserved,
13250                 { "Reserved", "smb.server.cap.reserved", FT_BOOLEAN, 32,
13251                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
13252
13253         { &hf_smb_server_cap_bulk_transfer,
13254                 { "Bulk Transfer", "smb.server.cap.bulk_transfer", FT_BOOLEAN, 32,
13255                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
13256
13257         { &hf_smb_server_cap_compressed_data,
13258                 { "Compressed Data", "smb.server.cap.compressed_data", FT_BOOLEAN, 32,
13259                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
13260
13261         { &hf_smb_server_cap_extended_security,
13262                 { "Extended Security", "smb.server.cap.extended_security", FT_BOOLEAN, 32,
13263                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
13264
13265         { &hf_smb_system_time,
13266                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
13267                 NULL, 0, "System Time", HFILL }},
13268
13269         { &hf_smb_unknown,
13270                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
13271                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
13272
13273         { &hf_smb_dir_name,
13274                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
13275                 NULL, 0, "SMB Directory Name", HFILL }},
13276
13277         { &hf_smb_echo_count,
13278                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
13279                 NULL, 0, "Number of times to echo data back", HFILL }},
13280
13281         { &hf_smb_echo_data,
13282                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
13283                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
13284
13285         { &hf_smb_echo_seq_num,
13286                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
13287                 NULL, 0, "Sequence number for this echo response", HFILL }},
13288
13289         { &hf_smb_max_buf_size,
13290                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
13291                 NULL, 0, "Max client buffer size", HFILL }},
13292
13293         { &hf_smb_path,
13294                 { "Path", "smb.path", FT_STRING, BASE_NONE,
13295                 NULL, 0, "Path. Server name and share name", HFILL }},
13296
13297         { &hf_smb_service,
13298                 { "Service", "smb.service", FT_STRING, BASE_NONE,
13299                 NULL, 0, "Service name", HFILL }},
13300
13301         { &hf_smb_password,
13302                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
13303                 NULL, 0, "Password", HFILL }},
13304
13305         { &hf_smb_ansi_password,
13306                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
13307                 NULL, 0, "ANSI Password", HFILL }},
13308
13309         { &hf_smb_unicode_password,
13310                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
13311                 NULL, 0, "Unicode Password", HFILL }},
13312
13313         { &hf_smb_move_flags_file,
13314                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
13315                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
13316
13317         { &hf_smb_move_flags_dir,
13318                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
13319                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
13320
13321         { &hf_smb_move_flags_verify,
13322                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
13323                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
13324
13325         { &hf_smb_count,
13326                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
13327                 NULL, 0, "Count number of items/bytes", HFILL }},
13328
13329         { &hf_smb_file_name,
13330                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
13331                 NULL, 0, "File Name", HFILL }},
13332
13333         { &hf_smb_open_function_create,
13334                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
13335                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
13336
13337         { &hf_smb_open_function_open,
13338                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
13339                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
13340
13341         { &hf_smb_fid,
13342                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
13343                 NULL, 0, "FID: File ID", HFILL }},
13344
13345         { &hf_smb_file_attr_read_only_16bit,
13346                 { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 16,
13347                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
13348
13349         { &hf_smb_file_attr_read_only_8bit,
13350                 { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 8,
13351                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
13352
13353         { &hf_smb_file_attr_hidden_16bit,
13354                 { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 16,
13355                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
13356
13357         { &hf_smb_file_attr_hidden_8bit,
13358                 { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 8,
13359                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
13360
13361         { &hf_smb_file_attr_system_16bit,
13362                 { "System", "smb.file.attribute.system", FT_BOOLEAN, 16,
13363                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
13364
13365         { &hf_smb_file_attr_system_8bit,
13366                 { "System", "smb.file.attribute.system", FT_BOOLEAN, 8,
13367                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
13368
13369         { &hf_smb_file_attr_volume_16bit,
13370                 { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 16,
13371                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
13372
13373         { &hf_smb_file_attr_volume_8bit,
13374                 { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 8,
13375                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
13376
13377         { &hf_smb_file_attr_directory_16bit,
13378                 { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 16,
13379                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
13380
13381         { &hf_smb_file_attr_directory_8bit,
13382                 { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 8,
13383                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
13384
13385         { &hf_smb_file_attr_archive_16bit,
13386                 { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 16,
13387                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
13388
13389         { &hf_smb_file_attr_archive_8bit,
13390                 { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 8,
13391                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
13392
13393         { &hf_smb_file_attr_device,
13394                 { "Device", "smb.file.attribute.device", FT_BOOLEAN, 16,
13395                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
13396
13397         { &hf_smb_file_attr_normal,
13398                 { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 16,
13399                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
13400
13401         { &hf_smb_file_attr_temporary,
13402                 { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 16,
13403                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
13404
13405         { &hf_smb_file_attr_sparse,
13406                 { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 16,
13407                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
13408
13409         { &hf_smb_file_attr_reparse,
13410                 { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 16,
13411                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
13412
13413         { &hf_smb_file_attr_compressed,
13414                 { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 16,
13415                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
13416
13417         { &hf_smb_file_attr_offline,
13418                 { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 16,
13419                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
13420
13421         { &hf_smb_file_attr_not_content_indexed,
13422                 { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 16,
13423                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
13424
13425         { &hf_smb_file_attr_encrypted,
13426                 { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 16,
13427                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
13428
13429         { &hf_smb_file_size,
13430                 { "File Size", "smb.file.size", FT_UINT32, BASE_DEC,
13431                 NULL, 0, "File Size", HFILL }},
13432
13433         { &hf_smb_search_attribute_read_only,
13434                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
13435                 TFS(&tfs_search_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
13436
13437         { &hf_smb_search_attribute_hidden,
13438                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
13439                 TFS(&tfs_search_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
13440
13441         { &hf_smb_search_attribute_system,
13442                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
13443                 TFS(&tfs_search_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
13444
13445         { &hf_smb_search_attribute_volume,
13446                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
13447                 TFS(&tfs_search_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
13448
13449         { &hf_smb_search_attribute_directory,
13450                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
13451                 TFS(&tfs_search_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
13452
13453         { &hf_smb_search_attribute_archive,
13454                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
13455                 TFS(&tfs_search_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
13456
13457         { &hf_smb_access_mode,
13458                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
13459                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
13460
13461         { &hf_smb_access_sharing,
13462                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
13463                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
13464
13465         { &hf_smb_access_locality,
13466                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
13467                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
13468
13469         { &hf_smb_access_caching,
13470                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
13471                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
13472
13473         { &hf_smb_access_writetru,
13474                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
13475                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
13476
13477         { &hf_smb_create_time,
13478                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
13479                 NULL, 0, "Creation Time", HFILL }},
13480
13481         { &hf_smb_create_dos_date,
13482                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
13483                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
13484
13485         { &hf_smb_create_dos_time,
13486                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
13487                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
13488
13489         { &hf_smb_last_write_time,
13490                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
13491                 NULL, 0, "Time this file was last written to", HFILL }},
13492
13493         { &hf_smb_last_write_dos_date,
13494                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
13495                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
13496
13497         { &hf_smb_last_write_dos_time,
13498                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
13499                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
13500
13501         { &hf_smb_old_file_name,
13502                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
13503                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
13504
13505         { &hf_smb_offset,
13506                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
13507                 NULL, 0, "Offset in file", HFILL }},
13508
13509         { &hf_smb_remaining,
13510                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
13511                 NULL, 0, "Remaining number of bytes", HFILL }},
13512
13513         { &hf_smb_padding,
13514                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
13515                 NULL, 0, "Padding or unknown data", HFILL }},
13516
13517         { &hf_smb_file_data,
13518                 { "File Data", "smb.file.data", FT_BYTES, BASE_HEX,
13519                 NULL, 0, "Data read/written to the file", HFILL }},
13520
13521         { &hf_smb_total_data_len,
13522                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
13523                 NULL, 0, "Total length of data", HFILL }},
13524
13525         { &hf_smb_data_len,
13526                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
13527                 NULL, 0, "Length of data", HFILL }},
13528
13529         { &hf_smb_seek_mode,
13530                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
13531                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
13532
13533         { &hf_smb_access_time,
13534                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
13535                 NULL, 0, "Last Access Time", HFILL }},
13536
13537         { &hf_smb_access_dos_date,
13538                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
13539                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
13540
13541         { &hf_smb_access_dos_time,
13542                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
13543                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
13544
13545         { &hf_smb_data_size,
13546                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
13547                 NULL, 0, "Data Size", HFILL }},
13548
13549         { &hf_smb_alloc_size,
13550                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
13551                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
13552
13553         { &hf_smb_max_count,
13554                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
13555                 NULL, 0, "Maximum Count", HFILL }},
13556
13557         { &hf_smb_min_count,
13558                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
13559                 NULL, 0, "Minimum Count", HFILL }},
13560
13561         { &hf_smb_timeout,
13562                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
13563                 NULL, 0, "Timeout in miliseconds", HFILL }},
13564
13565         { &hf_smb_high_offset,
13566                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
13567                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
13568
13569         { &hf_smb_units,
13570                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
13571                 NULL, 0, "Total number of units at server", HFILL }},
13572
13573         { &hf_smb_bpu,
13574                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
13575                 NULL, 0, "Blocks per unit at server", HFILL }},
13576
13577         { &hf_smb_blocksize,
13578                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
13579                 NULL, 0, "Block size (in bytes) at server", HFILL }},
13580
13581         { &hf_smb_freeunits,
13582                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
13583                 NULL, 0, "Number of free units at server", HFILL }},
13584
13585         { &hf_smb_data_offset,
13586                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
13587                 NULL, 0, "Data Offset", HFILL }},
13588
13589         { &hf_smb_dcm,
13590                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
13591                 NULL, 0, "Data Compaction Mode", HFILL }},
13592
13593         { &hf_smb_request_mask,
13594                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
13595                 NULL, 0, "Connectionless mode mask", HFILL }},
13596
13597         { &hf_smb_response_mask,
13598                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
13599                 NULL, 0, "Connectionless mode mask", HFILL }},
13600
13601         { &hf_smb_sid,
13602                 { "SID", "smb.sid", FT_UINT16, BASE_HEX,
13603                 NULL, 0, "SID: Search ID, handle for find operations", HFILL }},
13604
13605         { &hf_smb_write_mode_write_through,
13606                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
13607                 TFS(&tfs_write_mode_write_through), 0x0001, "Write through mode requested?", HFILL }},
13608
13609         { &hf_smb_write_mode_return_remaining,
13610                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
13611                 TFS(&tfs_write_mode_return_remaining), 0x0002, "Return remaining data responses?", HFILL }},
13612
13613         { &hf_smb_write_mode_raw,
13614                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
13615                 TFS(&tfs_write_mode_raw), 0x0004, "Use WriteRawNamedPipe?", HFILL }},
13616
13617         { &hf_smb_write_mode_message_start,
13618                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
13619                 TFS(&tfs_write_mode_message_start), 0x0008, "Is this the start of a message?", HFILL }},
13620
13621         { &hf_smb_write_mode_connectionless,
13622                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
13623                 TFS(&tfs_write_mode_connectionless), 0x0080, "Connectionless mode requested?", HFILL }},
13624
13625         { &hf_smb_resume_key_len,
13626                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
13627                 NULL, 0, "Resume Key length", HFILL }},
13628
13629         { &hf_smb_resume_server_cookie,
13630                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
13631                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
13632
13633         { &hf_smb_resume_client_cookie,
13634                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
13635                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
13636
13637         { &hf_smb_andxoffset,
13638                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
13639                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
13640
13641         { &hf_smb_lock_type_large,
13642                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
13643                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
13644
13645         { &hf_smb_lock_type_cancel,
13646                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
13647                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
13648
13649         { &hf_smb_lock_type_change,
13650                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
13651                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
13652
13653         { &hf_smb_lock_type_oplock,
13654                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
13655                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
13656
13657         { &hf_smb_lock_type_shared,
13658                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
13659                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
13660
13661         { &hf_smb_locking_ol,
13662                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
13663                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
13664
13665         { &hf_smb_number_of_locks,
13666                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
13667                 NULL, 0, "Number of lock requests in this request", HFILL }},
13668
13669         { &hf_smb_number_of_unlocks,
13670                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
13671                 NULL, 0, "Number of unlock requests in this request", HFILL }},
13672
13673         { &hf_smb_lock_long_length,
13674                 { "Length", "smb.lock.length", FT_UINT64, BASE_DEC,
13675                 NULL, 0, "Length of lock/unlock region", HFILL }},
13676
13677         { &hf_smb_lock_long_offset,
13678                 { "Offset", "smb.lock.offset", FT_UINT64, BASE_DEC,
13679                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
13680
13681         { &hf_smb_file_type,
13682                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
13683                 VALS(filetype_vals), 0, "Type of file", HFILL }},
13684
13685         { &hf_smb_ipc_state_nonblocking,
13686                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
13687                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
13688
13689         { &hf_smb_ipc_state_endpoint,
13690                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
13691                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
13692
13693         { &hf_smb_ipc_state_pipe_type,
13694                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
13695                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
13696
13697         { &hf_smb_ipc_state_read_mode,
13698                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
13699                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
13700
13701         { &hf_smb_ipc_state_icount,
13702                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
13703                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
13704
13705         { &hf_smb_server_fid,
13706                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
13707                 NULL, 0, "Server unique File ID", HFILL }},
13708
13709         { &hf_smb_open_flags_add_info,
13710                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
13711                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
13712
13713         { &hf_smb_open_flags_ex_oplock,
13714                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
13715                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
13716
13717         { &hf_smb_open_flags_batch_oplock,
13718                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
13719                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
13720
13721         { &hf_smb_open_flags_ealen,
13722                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
13723                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
13724
13725         { &hf_smb_open_action_open,
13726                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
13727                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
13728
13729         { &hf_smb_open_action_lock,
13730                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
13731                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
13732
13733         { &hf_smb_vc_num,
13734                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
13735                 NULL, 0, "VC Number", HFILL }},
13736
13737         { &hf_smb_password_len,
13738                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
13739                 NULL, 0, "Length of password", HFILL }},
13740
13741         { &hf_smb_ansi_password_len,
13742                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
13743                 NULL, 0, "Length of ANSI password", HFILL }},
13744
13745         { &hf_smb_unicode_password_len,
13746                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
13747                 NULL, 0, "Length of Unicode password", HFILL }},
13748
13749         { &hf_smb_account,
13750                 { "Account", "smb.account", FT_STRING, BASE_NONE,
13751                 NULL, 0, "Account, username", HFILL }},
13752
13753         { &hf_smb_os,
13754                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
13755                 NULL, 0, "Which OS we are running", HFILL }},
13756
13757         { &hf_smb_lanman,
13758                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
13759                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
13760
13761         { &hf_smb_setup_action_guest,
13762                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
13763                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
13764
13765         { &hf_smb_fs,
13766                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
13767                 NULL, 0, "Native File System", HFILL }},
13768
13769         { &hf_smb_connect_flags_dtid,
13770                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
13771                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
13772
13773         { &hf_smb_connect_support_search,
13774                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
13775                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
13776
13777         { &hf_smb_connect_support_in_dfs,
13778                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
13779                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
13780
13781         { &hf_smb_max_setup_count,
13782                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
13783                 NULL, 0, "Maximum number of setup words to return", HFILL }},
13784
13785         { &hf_smb_total_param_count,
13786                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
13787                 NULL, 0, "Total number of parameter bytes", HFILL }},
13788
13789         { &hf_smb_total_data_count,
13790                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
13791                 NULL, 0, "Total number of data bytes", HFILL }},
13792
13793         { &hf_smb_max_param_count,
13794                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
13795                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
13796
13797         { &hf_smb_max_data_count,
13798                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
13799                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
13800
13801         { &hf_smb_param_disp16,
13802                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
13803                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
13804
13805         { &hf_smb_param_count16,
13806                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
13807                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
13808
13809         { &hf_smb_param_offset16,
13810                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
13811                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
13812
13813         { &hf_smb_param_disp32,
13814                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
13815                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
13816
13817         { &hf_smb_param_count32,
13818                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
13819                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
13820
13821         { &hf_smb_param_offset32,
13822                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
13823                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
13824
13825         { &hf_smb_data_count16,
13826                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
13827                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
13828
13829         { &hf_smb_data_disp16,
13830                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
13831                 NULL, 0, "Data Displacement", HFILL }},
13832
13833         { &hf_smb_data_offset16,
13834                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
13835                 NULL, 0, "Data Offset", HFILL }},
13836
13837         { &hf_smb_data_count32,
13838                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
13839                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
13840
13841         { &hf_smb_data_disp32,
13842                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
13843                 NULL, 0, "Data Displacement", HFILL }},
13844
13845         { &hf_smb_data_offset32,
13846                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
13847                 NULL, 0, "Data Offset", HFILL }},
13848
13849         { &hf_smb_setup_count,
13850                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
13851                 NULL, 0, "Number of setup words in this buffer", HFILL }},
13852
13853         { &hf_smb_nt_trans_subcmd,
13854                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
13855                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
13856
13857         { &hf_smb_nt_ioctl_function_code,
13858                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
13859                 NULL, 0, "NT IOCTL function code", HFILL }},
13860
13861         { &hf_smb_nt_ioctl_isfsctl,
13862                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
13863                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
13864
13865         { &hf_smb_nt_ioctl_flags_root_handle,
13866                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
13867                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
13868
13869         { &hf_smb_nt_ioctl_data,
13870                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
13871                 NULL, 0, "Data for the IOCTL call", HFILL }},
13872
13873         { &hf_smb_nt_notify_action,
13874                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
13875                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
13876
13877         { &hf_smb_nt_notify_watch_tree,
13878                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
13879                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
13880
13881         { &hf_smb_nt_notify_stream_write,
13882                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
13883                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
13884
13885         { &hf_smb_nt_notify_stream_size,
13886                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
13887                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
13888
13889         { &hf_smb_nt_notify_stream_name,
13890                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
13891                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
13892
13893         { &hf_smb_nt_notify_security,
13894                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
13895                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
13896
13897         { &hf_smb_nt_notify_ea,
13898                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
13899                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
13900
13901         { &hf_smb_nt_notify_creation,
13902                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
13903                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
13904
13905         { &hf_smb_nt_notify_last_access,
13906                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
13907                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
13908
13909         { &hf_smb_nt_notify_last_write,
13910                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
13911                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
13912
13913         { &hf_smb_nt_notify_size,
13914                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
13915                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
13916
13917         { &hf_smb_nt_notify_attributes,
13918                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
13919                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
13920
13921         { &hf_smb_nt_notify_dir_name,
13922                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
13923                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
13924
13925         { &hf_smb_nt_notify_file_name,
13926                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
13927                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
13928
13929         { &hf_smb_root_dir_fid,
13930                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
13931                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
13932
13933         { &hf_smb_alloc_size64,
13934                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
13935                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
13936
13937         { &hf_smb_nt_create_disposition,
13938                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
13939                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
13940
13941         { &hf_smb_sd_length,
13942                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
13943                 NULL, 0, "Total length of security descriptor", HFILL }},
13944
13945         { &hf_smb_ea_length,
13946                 { "EA Length", "smb.ea.length", FT_UINT32, BASE_DEC,
13947                 NULL, 0, "Total EA length for opened file", HFILL }},
13948
13949         { &hf_smb_file_name_len,
13950                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
13951                 NULL, 0, "Length of File Name", HFILL }},
13952
13953         { &hf_smb_nt_impersonation_level,
13954                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
13955                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
13956
13957         { &hf_smb_nt_security_flags_context_tracking,
13958                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
13959                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
13960
13961         { &hf_smb_nt_security_flags_effective_only,
13962                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
13963                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
13964
13965         { &hf_smb_nt_access_mask_generic_read,
13966                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
13967                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
13968
13969         { &hf_smb_nt_access_mask_generic_write,
13970                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
13971                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
13972
13973         { &hf_smb_nt_access_mask_generic_execute,
13974                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
13975                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
13976
13977         { &hf_smb_nt_access_mask_generic_all,
13978                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
13979                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
13980
13981         { &hf_smb_nt_access_mask_maximum_allowed,
13982                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
13983                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
13984
13985         { &hf_smb_nt_access_mask_system_security,
13986                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
13987                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
13988
13989         { &hf_smb_nt_access_mask_synchronize,
13990                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
13991                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
13992
13993         { &hf_smb_nt_access_mask_write_owner,
13994                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
13995                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
13996
13997         { &hf_smb_nt_access_mask_write_dac,
13998                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
13999                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
14000
14001         { &hf_smb_nt_access_mask_read_control,
14002                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
14003                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
14004
14005         { &hf_smb_nt_access_mask_delete,
14006                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
14007                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
14008
14009         { &hf_smb_nt_access_mask_write_attributes,
14010                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
14011                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
14012
14013         { &hf_smb_nt_access_mask_read_attributes,
14014                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
14015                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
14016
14017         { &hf_smb_nt_access_mask_delete_child,
14018                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
14019                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
14020
14021         /*
14022          * "Execute" for files, "traverse" for directories.
14023          */
14024         { &hf_smb_nt_access_mask_execute,
14025                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
14026                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
14027
14028         { &hf_smb_nt_access_mask_write_ea,
14029                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
14030                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
14031
14032         { &hf_smb_nt_access_mask_read_ea,
14033                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
14034                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
14035
14036         /*
14037          * "Append data" for files, "add subdirectory" for directories,
14038          * "create pipe instance" for named pipes.
14039          */
14040         { &hf_smb_nt_access_mask_append,
14041                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
14042                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
14043
14044         /*
14045          * "Write data" for files and pipes, "add file" for directory.
14046          */
14047         { &hf_smb_nt_access_mask_write,
14048                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
14049                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
14050
14051         /*
14052          * "Read data" for files and pipes, "list directory" for directory.
14053          */
14054         { &hf_smb_nt_access_mask_read,
14055                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
14056                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
14057
14058         { &hf_smb_nt_create_bits_oplock,
14059                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
14060                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
14061
14062         { &hf_smb_nt_create_bits_boplock,
14063                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
14064                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
14065
14066         { &hf_smb_nt_create_bits_dir,
14067                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
14068                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
14069
14070         { &hf_smb_nt_create_options_directory_file,
14071                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
14072                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
14073
14074         { &hf_smb_nt_create_options_write_through,
14075                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
14076                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
14077
14078         { &hf_smb_nt_create_options_sequential_only,
14079                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
14080                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
14081
14082         { &hf_smb_nt_create_options_sync_io_alert,
14083                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
14084                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
14085
14086         { &hf_smb_nt_create_options_sync_io_nonalert,
14087                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
14088                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
14089
14090         { &hf_smb_nt_create_options_non_directory_file,
14091                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
14092                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
14093
14094         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
14095            and "NtOpenFile()"; is that sent over the wire?  Network
14096            Monitor thinks so, but its author may just have grabbed
14097            the flag bits from a system header file. */
14098
14099         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
14100            and "NtOpenFile()"; is that sent over the wire?  NetMon
14101            thinks so, but see previous comment. */
14102
14103         { &hf_smb_nt_create_options_no_ea_knowledge,
14104                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
14105                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
14106
14107         { &hf_smb_nt_create_options_eight_dot_three_only,
14108                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
14109                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
14110
14111         { &hf_smb_nt_create_options_random_access,
14112                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
14113                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
14114
14115         { &hf_smb_nt_create_options_delete_on_close,
14116                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
14117                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
14118
14119         /* 0x00002000 is "open by FID", or something such as that (which
14120            I suspect is like "open by inumber" on UNIX), at least in
14121            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
14122            wire?  NetMon thinks so, but see previous comment. */
14123
14124         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
14125            and "NtOpenFile()"; is that sent over the wire?  NetMon
14126            thinks so, but see previous comment. */
14127
14128         { &hf_smb_nt_share_access_read,
14129                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
14130                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
14131
14132         { &hf_smb_nt_share_access_write,
14133                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
14134                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
14135
14136         { &hf_smb_nt_share_access_delete,
14137                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
14138                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
14139
14140         { &hf_smb_file_eattr_read_only,
14141                 { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 32,
14142                 TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
14143
14144         { &hf_smb_file_eattr_hidden,
14145                 { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 32,
14146                 TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
14147
14148         { &hf_smb_file_eattr_system,
14149                 { "System", "smb.file.attribute.system", FT_BOOLEAN, 32,
14150                 TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
14151
14152         { &hf_smb_file_eattr_volume,
14153                 { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 32,
14154                 TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
14155
14156         { &hf_smb_file_eattr_directory,
14157                 { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 32,
14158                 TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
14159
14160         { &hf_smb_file_eattr_archive,
14161                 { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 32,
14162                 TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
14163
14164         { &hf_smb_file_eattr_device,
14165                 { "Device", "smb.file.attribute.device", FT_BOOLEAN, 32,
14166                 TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
14167
14168         { &hf_smb_file_eattr_normal,
14169                 { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 32,
14170                 TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
14171
14172         { &hf_smb_file_eattr_temporary,
14173                 { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 32,
14174                 TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
14175
14176         { &hf_smb_file_eattr_sparse,
14177                 { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 32,
14178                 TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
14179
14180         { &hf_smb_file_eattr_reparse,
14181                 { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 32,
14182                 TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
14183
14184         { &hf_smb_file_eattr_compressed,
14185                 { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 32,
14186                 TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
14187
14188         { &hf_smb_file_eattr_offline,
14189                 { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 32,
14190                 TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
14191
14192         { &hf_smb_file_eattr_not_content_indexed,
14193                 { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 32,
14194                 TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
14195
14196         { &hf_smb_file_eattr_encrypted,
14197                 { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 32,
14198                 TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
14199
14200         { &hf_smb_file_eattr_write_through,
14201                 { "Write Through", "smb.file.attribute.write_through", FT_BOOLEAN, 32,
14202                 TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
14203
14204         { &hf_smb_file_eattr_no_buffering,
14205                 { "No Buffering", "smb.file.attribute.no_buffering", FT_BOOLEAN, 32,
14206                 TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
14207
14208         { &hf_smb_file_eattr_random_access,
14209                 { "Random Access", "smb.file.attribute.random_access", FT_BOOLEAN, 32,
14210                 TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
14211
14212         { &hf_smb_file_eattr_sequential_scan,
14213                 { "Sequential Scan", "smb.file.attribute.sequential_scan", FT_BOOLEAN, 32,
14214                 TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
14215
14216         { &hf_smb_file_eattr_delete_on_close,
14217                 { "Delete on Close", "smb.file.attribute.delete_on_close", FT_BOOLEAN, 32,
14218                 TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
14219
14220         { &hf_smb_file_eattr_backup_semantics,
14221                 { "Backup", "smb.file.attribute.backup_semantics", FT_BOOLEAN, 32,
14222                 TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
14223
14224         { &hf_smb_file_eattr_posix_semantics,
14225                 { "Posix", "smb.file.attribute.posix_semantics", FT_BOOLEAN, 32,
14226                 TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
14227
14228         { &hf_smb_security_descriptor_len,
14229                 { "Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
14230                 NULL, 0, "Security Descriptor Length", HFILL }},
14231
14232         { &hf_smb_security_descriptor,
14233                 { "Security Descriptor", "smb.sec_desc", FT_BYTES, BASE_HEX,
14234                 NULL, 0, "Security Descriptor", HFILL }},
14235
14236         { &hf_smb_nt_qsd_owner,
14237                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
14238                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
14239
14240         { &hf_smb_nt_qsd_group,
14241                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
14242                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
14243
14244         { &hf_smb_nt_qsd_dacl,
14245                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
14246                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
14247
14248         { &hf_smb_nt_qsd_sacl,
14249                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
14250                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
14251
14252         { &hf_smb_extended_attributes,
14253                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
14254                 NULL, 0, "Extended Attributes", HFILL }},
14255
14256         { &hf_smb_oplock_level,
14257                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
14258                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
14259
14260         { &hf_smb_create_action,
14261                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
14262                 VALS(create_disposition_vals), 0, "Type of action taken", HFILL }},
14263
14264         { &hf_smb_ea_error_offset,
14265                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
14266                 NULL, 0, "Offset into EA list if EA error", HFILL }},
14267
14268         { &hf_smb_end_of_file,
14269                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
14270                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
14271
14272         { &hf_smb_device_type,
14273                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
14274                 VALS(device_type_vals), 0, "Type of device", HFILL }},
14275
14276         { &hf_smb_is_directory,
14277                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
14278                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
14279
14280         { &hf_smb_next_entry_offset,
14281                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
14282                 NULL, 0, "Offset to next entry", HFILL }},
14283
14284         { &hf_smb_change_time,
14285                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
14286                 NULL, 0, "Last Change Time", HFILL }},
14287
14288         { &hf_smb_setup_len,
14289                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
14290                 NULL, 0, "Length of prionter setup data", HFILL }},
14291
14292         { &hf_smb_print_mode,
14293                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
14294                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
14295
14296         { &hf_smb_print_identifier,
14297                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
14298                 NULL, 0, "Identifier string for this print job", HFILL }},
14299
14300         { &hf_smb_restart_index,
14301                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
14302                 NULL, 0, "Index of entry after last returned", HFILL }},
14303
14304         { &hf_smb_print_queue_date,
14305                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
14306                 NULL, 0, "Date when this entry was queued", HFILL }},
14307
14308         { &hf_smb_print_queue_dos_date,
14309                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
14310                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
14311
14312         { &hf_smb_print_queue_dos_time,
14313                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
14314                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
14315
14316         { &hf_smb_print_status,
14317                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
14318                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
14319
14320         { &hf_smb_print_spool_file_number,
14321                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
14322                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
14323
14324         { &hf_smb_print_spool_file_size,
14325                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
14326                 NULL, 0, "Number of bytes in spool file", HFILL }},
14327
14328         { &hf_smb_print_spool_file_name,
14329                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
14330                 NULL, 0, "Name of client that submitted this job", HFILL }},
14331
14332         { &hf_smb_start_index,
14333                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
14334                 NULL, 0, "First queue entry to return", HFILL }},
14335
14336         { &hf_smb_cancel_to,
14337                 { "Cancel to", "smb.cancel_to", FT_UINT32, BASE_DEC,
14338                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
14339
14340         { &hf_smb_trans2_subcmd,
14341                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
14342                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
14343
14344         { &hf_smb_trans_name,
14345                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
14346                 NULL, 0, "Name of transaction", HFILL }},
14347
14348         { &hf_smb_transaction_flags_dtid,
14349                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
14350                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
14351
14352         { &hf_smb_transaction_flags_owt,
14353                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
14354                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
14355
14356         { &hf_smb_search_count,
14357                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
14358                 NULL, 0, "Maximum number of search entries to return", HFILL }},
14359
14360         { &hf_smb_search_pattern,
14361                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
14362                 NULL, 0, "Search Pattern", HFILL }},
14363
14364         { &hf_smb_ff2_backup,
14365                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
14366                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
14367
14368         { &hf_smb_ff2_continue,
14369                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
14370                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
14371
14372         { &hf_smb_ff2_resume,
14373                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
14374                 TFS(&tfs_ff2_resume), 0x0004, "Return resume keys for each entry found", HFILL }},
14375
14376         { &hf_smb_ff2_close_eos,
14377                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
14378                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
14379
14380         { &hf_smb_ff2_close,
14381                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
14382                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
14383
14384         { &hf_smb_ff2_information_level,
14385                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
14386                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
14387
14388         { &hf_smb_qpi_loi,
14389                 { "Level of Interest", "smb.loi", FT_UINT16, BASE_DEC,
14390                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] commands", HFILL }},
14391
14392         { &hf_smb_storage_type,
14393                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
14394                 NULL, 0, "Type of storage", HFILL }},
14395
14396         { &hf_smb_resume,
14397                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
14398                 NULL, 0, "Resume Key", HFILL }},
14399
14400         { &hf_smb_max_referral_level,
14401                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
14402                 NULL, 0, "Latest referral version number understood", HFILL }},
14403
14404         { &hf_smb_qfsi_information_level,
14405                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_DEC,
14406                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
14407
14408         { &hf_smb_ea_size,
14409                 { "EA Size", "smb.ea_size", FT_UINT32, BASE_DEC,
14410                 NULL, 0, "Size of file's EA information", HFILL }},
14411
14412         { &hf_smb_list_length,
14413                 { "ListLength", "smb.list_len", FT_UINT32, BASE_DEC,
14414                 NULL, 0, "Length of the remaining data", HFILL }},
14415
14416         { &hf_smb_number_of_links,
14417                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
14418                 NULL, 0, "Number of hard links to the file", HFILL }},
14419
14420         { &hf_smb_delete_pending,
14421                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
14422                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
14423
14424         { &hf_smb_index_number,
14425                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
14426                 NULL, 0, "File system unique identifier", HFILL }},
14427
14428         { &hf_smb_current_offset,
14429                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
14430                 NULL, 0, "Current offset in the file", HFILL }},
14431
14432         { &hf_smb_t2_alignment,
14433                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
14434                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
14435
14436         { &hf_smb_t2_stream_name_length,
14437                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
14438                 NULL, 0, "Length of stream name", HFILL }},
14439
14440         { &hf_smb_t2_stream_size,
14441                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
14442                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
14443
14444         { &hf_smb_t2_stream_name,
14445                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
14446                 NULL, 0, "Name of the stream", HFILL }},
14447
14448         { &hf_smb_t2_compressed_file_size,
14449                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
14450                 NULL, 0, "Size of the compressed file", HFILL }},
14451
14452         { &hf_smb_t2_compressed_format,
14453                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
14454                 NULL, 0, "Compression algorithm used", HFILL }},
14455
14456         { &hf_smb_t2_compressed_unit_shift,
14457                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
14458                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
14459
14460         { &hf_smb_t2_compressed_chunk_shift,
14461                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
14462                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
14463
14464         { &hf_smb_t2_compressed_cluster_shift,
14465                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
14466                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
14467
14468         { &hf_smb_dfs_path_consumed,
14469                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
14470                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
14471
14472         { &hf_smb_dfs_num_referrals,
14473                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
14474                 NULL, 0, "Number of referrals in this pdu", HFILL }},
14475
14476         { &hf_smb_get_dfs_server_hold_storage,
14477                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
14478                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
14479
14480         { &hf_smb_get_dfs_fielding,
14481                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
14482                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
14483
14484         { &hf_smb_dfs_referral_version,
14485                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
14486                 NULL, 0, "Version of referral element", HFILL }},
14487
14488         { &hf_smb_dfs_referral_size,
14489                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
14490                 NULL, 0, "Size of referral element", HFILL }},
14491
14492         { &hf_smb_dfs_referral_server_type,
14493                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
14494                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
14495
14496         { &hf_smb_dfs_referral_flags_strip,
14497                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
14498                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
14499
14500         { &hf_smb_dfs_referral_node_offset,
14501                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
14502                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
14503
14504         { &hf_smb_dfs_referral_node,
14505                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
14506                 NULL, 0, "Name of entity to visit next", HFILL }},
14507
14508         { &hf_smb_dfs_referral_proximity,
14509                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
14510                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
14511
14512         { &hf_smb_dfs_referral_ttl,
14513                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
14514                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
14515
14516         { &hf_smb_dfs_referral_path_offset,
14517                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
14518                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
14519
14520         { &hf_smb_dfs_referral_path,
14521                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
14522                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
14523
14524         { &hf_smb_dfs_referral_alt_path_offset,
14525                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
14526                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
14527
14528         { &hf_smb_dfs_referral_alt_path,
14529                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
14530                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
14531
14532         { &hf_smb_end_of_search,
14533                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
14534                 NULL, 0, "Was last entry returned?", HFILL }},
14535
14536         { &hf_smb_last_name_offset,
14537                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
14538                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
14539
14540         { &hf_smb_file_index,
14541                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
14542                 NULL, 0, "File index", HFILL }},
14543
14544         { &hf_smb_short_file_name,
14545                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
14546                 NULL, 0, "Short (8.3) File Name", HFILL }},
14547
14548         { &hf_smb_short_file_name_len,
14549                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
14550                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
14551
14552         { &hf_smb_fs_id,
14553                 { "FS Id", "smb.fs.id", FT_UINT32, BASE_DEC,
14554                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
14555
14556         { &hf_smb_sector_unit,
14557                 { "Sectors/Unit", "smb.fs.sector_per_unit", FT_UINT32, BASE_DEC,
14558                 NULL, 0, "Sectors per allocation unit", HFILL }},
14559
14560         { &hf_smb_fs_units,
14561                 { "Total Units", "smb.fs.units", FT_UINT32, BASE_DEC,
14562                 NULL, 0, "Total number of units on this filesystem", HFILL }},
14563
14564         { &hf_smb_fs_sector,
14565                 { "Bytes per Sector", "smb.fs.bytes_per_sector", FT_UINT32, BASE_DEC,
14566                 NULL, 0, "Bytes per sector", HFILL }},
14567
14568         { &hf_smb_avail_units,
14569                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
14570                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
14571
14572         { &hf_smb_volume_serial_num,
14573                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
14574                 NULL, 0, "Volume serial number", HFILL }},
14575
14576         { &hf_smb_volume_label_len,
14577                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
14578                 NULL, 0, "Length of volume label", HFILL }},
14579
14580         { &hf_smb_volume_label,
14581                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
14582                 NULL, 0, "Volume label", HFILL }},
14583
14584         { &hf_smb_free_alloc_units64,
14585                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
14586                 NULL, 0, "Number of free allocation units", HFILL }},
14587
14588         { &hf_smb_max_name_len,
14589                 { "Max name length", "smb.fs.max_name_len", FT_UINT32, BASE_DEC,
14590                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
14591
14592         { &hf_smb_fs_name_len,
14593                 { "Label Length", "smb.fs.name.len", FT_UINT32, BASE_DEC,
14594                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
14595
14596         { &hf_smb_fs_name,
14597                 { "FS Name", "smb.fs.name", FT_STRING, BASE_DEC,
14598                 NULL, 0, "Name of filesystem", HFILL }},
14599
14600         { &hf_smb_device_char_removable,
14601                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
14602                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
14603
14604         { &hf_smb_device_char_read_only,
14605                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
14606                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
14607
14608         { &hf_smb_device_char_floppy,
14609                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
14610                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
14611
14612         { &hf_smb_device_char_write_once,
14613                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
14614                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
14615
14616         { &hf_smb_device_char_remote,
14617                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
14618                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
14619
14620         { &hf_smb_device_char_mounted,
14621                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
14622                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
14623
14624         { &hf_smb_device_char_virtual,
14625                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
14626                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
14627
14628         { &hf_smb_fs_attr_css,
14629                 { "Case Sensitive Search", "smb.fs.attr.css", FT_BOOLEAN, 32,
14630                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
14631
14632         { &hf_smb_fs_attr_cpn,
14633                 { "Case Preserving", "smb.fs.attr.cpn", FT_BOOLEAN, 32,
14634                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
14635
14636         { &hf_smb_fs_attr_pacls,
14637                 { "Persistent ACLs", "smb.fs.attr.pacls", FT_BOOLEAN, 32,
14638                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
14639
14640         { &hf_smb_fs_attr_fc,
14641                 { "Compression", "smb.fs.attr.fc", FT_BOOLEAN, 32,
14642                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
14643
14644         { &hf_smb_fs_attr_vq,
14645                 { "Volume Quotas", "smb.fs.attr.vq", FT_BOOLEAN, 32,
14646                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
14647
14648         { &hf_smb_fs_attr_dim,
14649                 { "Mounted", "smb.fs.attr.dim", FT_BOOLEAN, 32,
14650                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
14651
14652         { &hf_smb_fs_attr_vic,
14653                 { "Compressed", "smb.fs.attr.vic", FT_BOOLEAN, 32,
14654                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
14655         };
14656         static gint *ett[] = {
14657                 &ett_smb,
14658                 &ett_smb_hdr,
14659                 &ett_smb_command,
14660                 &ett_smb_fileattributes,
14661                 &ett_smb_capabilities,
14662                 &ett_smb_aflags,
14663                 &ett_smb_dialect,
14664                 &ett_smb_dialects,
14665                 &ett_smb_mode,
14666                 &ett_smb_rawmode,
14667                 &ett_smb_flags,
14668                 &ett_smb_flags2,
14669                 &ett_smb_desiredaccess,
14670                 &ett_smb_search,
14671                 &ett_smb_file,
14672                 &ett_smb_openfunction,
14673                 &ett_smb_filetype,
14674                 &ett_smb_openaction,
14675                 &ett_smb_writemode,
14676                 &ett_smb_lock_type,
14677                 &ett_smb_ssetupandxaction,
14678                 &ett_smb_optionsup,
14679                 &ett_smb_time_date,
14680                 &ett_smb_64bit_time,
14681                 &ett_smb_move_flags,
14682                 &ett_smb_file_attributes,
14683                 &ett_smb_search_resume_key,
14684                 &ett_smb_search_dir_info,
14685                 &ett_smb_unlocks,
14686                 &ett_smb_unlock,
14687                 &ett_smb_locks,
14688                 &ett_smb_lock,
14689                 &ett_smb_open_flags,
14690                 &ett_smb_ipc_state,
14691                 &ett_smb_open_action,
14692                 &ett_smb_setup_action,
14693                 &ett_smb_connect_flags,
14694                 &ett_smb_connect_support_bits,
14695                 &ett_smb_nt_access_mask,
14696                 &ett_smb_nt_create_bits,
14697                 &ett_smb_nt_create_options,
14698                 &ett_smb_nt_share_access,
14699                 &ett_smb_nt_security_flags,
14700                 &ett_smb_nt_trans_setup,
14701                 &ett_smb_nt_notify_completion_filter,
14702                 &ett_smb_nt_ioctl_flags,
14703                 &ett_smb_security_information_mask,
14704                 &ett_smb_print_queue_entry,
14705                 &ett_smb_transaction_flags,
14706                 &ett_smb_transaction_params,
14707                 &ett_smb_find_first2_flags,
14708                 &ett_smb_transaction_data,
14709                 &ett_smb_stream_info,
14710                 &ett_smb_dfs_referrals,
14711                 &ett_smb_dfs_referral,
14712                 &ett_smb_dfs_referral_flags,
14713                 &ett_smb_get_dfs_flags,
14714                 &ett_smb_ff2_data,
14715                 &ett_smb_device_characteristics,
14716                 &ett_smb_fs_attributes,
14717         };
14718
14719         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
14720             "SMB", "smb");
14721
14722         proto_register_subtree_array(ett, array_length(ett));
14723         proto_register_field_array(proto_smb, hf, array_length(hf));
14724         register_init_routine(&smb_init_protocol);
14725 }
14726
14727 void
14728 proto_reg_handoff_smb(void)
14729 {
14730         heur_dissector_add("netbios", dissect_smb, proto_smb);
14731 }