As the gtk2 directory is no longer needed (GTK1 and 2 are using the same sources...
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id$
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #include <time.h>
36 #include <string.h>
37 #include <glib.h>
38 #include <ctype.h>
39 #include <epan/int-64bit.h>
40 #include <epan/packet.h>
41 #include <epan/conversation.h>
42 #include "smb.h"
43 #include <epan/strutil.h>
44 #include "prefs.h"
45 #include "reassemble.h"
46 #include "tap.h"
47 #include "packet-ipx.h"
48
49 #include "packet-smb-common.h"
50 #include "packet-smb-mailslot.h"
51 #include "packet-smb-pipe.h"
52 #include "packet-dcerpc.h"
53 #include "packet-smb-sidsnooping.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 specification from the Storage Networking Industry Association
61  * can be found on a link from the page at
62  *
63  *      http://www.snia.org/tech_activities/CIFS
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 available
72  * for download; 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_key = -1;
96 static int hf_smb_session_id = -1;
97 static int hf_smb_sequence_num = -1;
98 static int hf_smb_group_id = -1;
99 static int hf_smb_pid = -1;
100 static int hf_smb_tid = -1;
101 static int hf_smb_uid = -1;
102 static int hf_smb_mid = -1;
103 static int hf_smb_pid_high = -1;
104 static int hf_smb_sig = -1;
105 static int hf_smb_response_to = -1;
106 static int hf_smb_time = -1;
107 static int hf_smb_response_in = -1;
108 static int hf_smb_continuation_to = -1;
109 static int hf_smb_nt_status = -1;
110 static int hf_smb_error_class = -1;
111 static int hf_smb_error_code = -1;
112 static int hf_smb_reserved = -1;
113 static int hf_smb_flags_lock = -1;
114 static int hf_smb_flags_receive_buffer = -1;
115 static int hf_smb_flags_caseless = -1;
116 static int hf_smb_flags_canon = -1;
117 static int hf_smb_flags_oplock = -1;
118 static int hf_smb_flags_notify = -1;
119 static int hf_smb_flags_response = -1;
120 static int hf_smb_flags2_long_names_allowed = -1;
121 static int hf_smb_flags2_ea = -1;
122 static int hf_smb_flags2_sec_sig = -1;
123 static int hf_smb_flags2_long_names_used = -1;
124 static int hf_smb_flags2_esn = -1;
125 static int hf_smb_flags2_dfs = -1;
126 static int hf_smb_flags2_roe = -1;
127 static int hf_smb_flags2_nt_error = -1;
128 static int hf_smb_flags2_string = -1;
129 static int hf_smb_word_count = -1;
130 static int hf_smb_byte_count = -1;
131 static int hf_smb_buffer_format = -1;
132 static int hf_smb_dialect_name = -1;
133 static int hf_smb_dialect_index = -1;
134 static int hf_smb_max_trans_buf_size = -1;
135 static int hf_smb_max_mpx_count = -1;
136 static int hf_smb_max_vcs_num = -1;
137 static int hf_smb_session_key = -1;
138 static int hf_smb_server_timezone = -1;
139 static int hf_smb_encryption_key_length = -1;
140 static int hf_smb_encryption_key = -1;
141 static int hf_smb_primary_domain = -1;
142 static int hf_smb_server = -1;
143 static int hf_smb_max_raw_buf_size = -1;
144 static int hf_smb_server_guid = -1;
145 static int hf_smb_security_blob_len = -1;
146 static int hf_smb_security_blob = -1;
147 static int hf_smb_sm_mode16 = -1;
148 static int hf_smb_sm_password16 = -1;
149 static int hf_smb_sm_mode = -1;
150 static int hf_smb_sm_password = -1;
151 static int hf_smb_sm_signatures = -1;
152 static int hf_smb_sm_sig_required = -1;
153 static int hf_smb_rm_read = -1;
154 static int hf_smb_rm_write = -1;
155 static int hf_smb_server_date_time = -1;
156 static int hf_smb_server_smb_date = -1;
157 static int hf_smb_server_smb_time = -1;
158 static int hf_smb_server_cap_raw_mode = -1;
159 static int hf_smb_server_cap_mpx_mode = -1;
160 static int hf_smb_server_cap_unicode = -1;
161 static int hf_smb_server_cap_large_files = -1;
162 static int hf_smb_server_cap_nt_smbs = -1;
163 static int hf_smb_server_cap_rpc_remote_apis = -1;
164 static int hf_smb_server_cap_nt_status = -1;
165 static int hf_smb_server_cap_level_ii_oplocks = -1;
166 static int hf_smb_server_cap_lock_and_read = -1;
167 static int hf_smb_server_cap_nt_find = -1;
168 static int hf_smb_server_cap_dfs = -1;
169 static int hf_smb_server_cap_infolevel_passthru = -1;
170 static int hf_smb_server_cap_large_readx = -1;
171 static int hf_smb_server_cap_large_writex = -1;
172 static int hf_smb_server_cap_unix = -1;
173 static int hf_smb_server_cap_reserved = -1;
174 static int hf_smb_server_cap_bulk_transfer = -1;
175 static int hf_smb_server_cap_compressed_data = -1;
176 static int hf_smb_server_cap_extended_security = -1;
177 static int hf_smb_system_time = -1;
178 static int hf_smb_unknown = -1;
179 static int hf_smb_dir_name = -1;
180 static int hf_smb_echo_count = -1;
181 static int hf_smb_echo_data = -1;
182 static int hf_smb_echo_seq_num = -1;
183 static int hf_smb_max_buf_size = -1;
184 static int hf_smb_password = -1;
185 static int hf_smb_password_len = -1;
186 static int hf_smb_ansi_password = -1;
187 static int hf_smb_ansi_password_len = -1;
188 static int hf_smb_unicode_password = -1;
189 static int hf_smb_unicode_password_len = -1;
190 static int hf_smb_path = -1;
191 static int hf_smb_service = -1;
192 static int hf_smb_move_flags_file = -1;
193 static int hf_smb_move_flags_dir = -1;
194 static int hf_smb_move_flags_verify = -1;
195 static int hf_smb_files_moved = -1;
196 static int hf_smb_copy_flags_file = -1;
197 static int hf_smb_copy_flags_dir = -1;
198 static int hf_smb_copy_flags_dest_mode = -1;
199 static int hf_smb_copy_flags_source_mode = -1;
200 static int hf_smb_copy_flags_verify = -1;
201 static int hf_smb_copy_flags_tree_copy = -1;
202 static int hf_smb_copy_flags_ea_action = -1;
203 static int hf_smb_count = -1;
204 static int hf_smb_count_low = -1;
205 static int hf_smb_count_high = -1;
206 static int hf_smb_file_name = -1;
207 static int hf_smb_open_function_open = -1;
208 static int hf_smb_open_function_create = -1;
209 static int hf_smb_fid = -1;
210 static int hf_smb_file_attr_read_only_16bit = -1;
211 static int hf_smb_file_attr_read_only_8bit = -1;
212 static int hf_smb_file_attr_hidden_16bit = -1;
213 static int hf_smb_file_attr_hidden_8bit = -1;
214 static int hf_smb_file_attr_system_16bit = -1;
215 static int hf_smb_file_attr_system_8bit = -1;
216 static int hf_smb_file_attr_volume_16bit = -1;
217 static int hf_smb_file_attr_volume_8bit = -1;
218 static int hf_smb_file_attr_directory_16bit = -1;
219 static int hf_smb_file_attr_directory_8bit = -1;
220 static int hf_smb_file_attr_archive_16bit = -1;
221 static int hf_smb_file_attr_archive_8bit = -1;
222 static int hf_smb_file_attr_device = -1;
223 static int hf_smb_file_attr_normal = -1;
224 static int hf_smb_file_attr_temporary = -1;
225 static int hf_smb_file_attr_sparse = -1;
226 static int hf_smb_file_attr_reparse = -1;
227 static int hf_smb_file_attr_compressed = -1;
228 static int hf_smb_file_attr_offline = -1;
229 static int hf_smb_file_attr_not_content_indexed = -1;
230 static int hf_smb_file_attr_encrypted = -1;
231 static int hf_smb_file_size = -1;
232 static int hf_smb_search_attribute_read_only = -1;
233 static int hf_smb_search_attribute_hidden = -1;
234 static int hf_smb_search_attribute_system = -1;
235 static int hf_smb_search_attribute_volume = -1;
236 static int hf_smb_search_attribute_directory = -1;
237 static int hf_smb_search_attribute_archive = -1;
238 static int hf_smb_access_mode = -1;
239 static int hf_smb_access_sharing = -1;
240 static int hf_smb_access_locality = -1;
241 static int hf_smb_access_caching = -1;
242 static int hf_smb_access_writetru = -1;
243 static int hf_smb_create_time = -1;
244 static int hf_smb_modify_time = -1;
245 static int hf_smb_backup_time = -1;
246 static int hf_smb_mac_alloc_block_count = -1;
247 static int hf_smb_mac_alloc_block_size = -1;
248 static int hf_smb_mac_free_block_count = -1;
249 static int hf_smb_mac_fndrinfo = -1;
250 static int hf_smb_mac_root_file_count = -1;
251 static int hf_smb_mac_root_dir_count = -1;
252 static int hf_smb_mac_file_count = -1;
253 static int hf_smb_mac_dir_count = -1;
254 static int hf_smb_mac_support_flags = -1;
255 static int hf_smb_mac_sup_access_ctrl = -1;
256 static int hf_smb_mac_sup_getset_comments = -1;
257 static int hf_smb_mac_sup_desktopdb_calls = -1;
258 static int hf_smb_mac_sup_unique_ids = -1;
259 static int hf_smb_mac_sup_streams = -1;
260 static int hf_smb_create_dos_date = -1;
261 static int hf_smb_create_dos_time = -1;
262 static int hf_smb_last_write_time = -1;
263 static int hf_smb_last_write_dos_date = -1;
264 static int hf_smb_last_write_dos_time = -1;
265 static int hf_smb_access_time = -1;
266 static int hf_smb_access_dos_date = -1;
267 static int hf_smb_access_dos_time = -1;
268 static int hf_smb_old_file_name = -1;
269 static int hf_smb_offset = -1;
270 static int hf_smb_remaining = -1;
271 static int hf_smb_padding = -1;
272 static int hf_smb_file_data = -1;
273 static int hf_smb_total_data_len = -1;
274 static int hf_smb_data_len = -1;
275 static int hf_smb_data_len_low = -1;
276 static int hf_smb_data_len_high = -1;
277 static int hf_smb_seek_mode = -1;
278 static int hf_smb_data_size = -1;
279 static int hf_smb_alloc_size = -1;
280 static int hf_smb_alloc_size64 = -1;
281 static int hf_smb_max_count = -1;
282 static int hf_smb_max_count_low = -1;
283 static int hf_smb_max_count_high = -1;
284 static int hf_smb_min_count = -1;
285 static int hf_smb_timeout = -1;
286 static int hf_smb_high_offset = -1;
287 static int hf_smb_units = -1;
288 static int hf_smb_bpu = -1;
289 static int hf_smb_blocksize = -1;
290 static int hf_smb_freeunits = -1;
291 static int hf_smb_data_offset = -1;
292 static int hf_smb_dcm = -1;
293 static int hf_smb_request_mask = -1;
294 static int hf_smb_response_mask = -1;
295 static int hf_smb_search_id = -1;
296 static int hf_smb_write_mode_write_through = -1;
297 static int hf_smb_write_mode_return_remaining = -1;
298 static int hf_smb_write_mode_raw = -1;
299 static int hf_smb_write_mode_message_start = -1;
300 static int hf_smb_write_mode_connectionless = -1;
301 static int hf_smb_resume_key_len = -1;
302 static int hf_smb_resume_find_id = -1;
303 static int hf_smb_resume_server_cookie = -1;
304 static int hf_smb_resume_client_cookie = -1;
305 static int hf_smb_andxoffset = -1;
306 static int hf_smb_lock_type_large = -1;
307 static int hf_smb_lock_type_cancel = -1;
308 static int hf_smb_lock_type_change = -1;
309 static int hf_smb_lock_type_oplock = -1;
310 static int hf_smb_lock_type_shared = -1;
311 static int hf_smb_locking_ol = -1;
312 static int hf_smb_number_of_locks = -1;
313 static int hf_smb_number_of_unlocks = -1;
314 static int hf_smb_lock_long_offset = -1;
315 static int hf_smb_lock_long_length = -1;
316 static int hf_smb_file_type = -1;
317 static int hf_smb_ipc_state_nonblocking = -1;
318 static int hf_smb_ipc_state_endpoint = -1;
319 static int hf_smb_ipc_state_pipe_type = -1;
320 static int hf_smb_ipc_state_read_mode = -1;
321 static int hf_smb_ipc_state_icount = -1;
322 static int hf_smb_server_fid = -1;
323 static int hf_smb_open_flags_add_info = -1;
324 static int hf_smb_open_flags_ex_oplock = -1;
325 static int hf_smb_open_flags_batch_oplock = -1;
326 static int hf_smb_open_flags_ealen = -1;
327 static int hf_smb_open_action_open = -1;
328 static int hf_smb_open_action_lock = -1;
329 static int hf_smb_vc_num = -1;
330 static int hf_smb_account = -1;
331 static int hf_smb_os = -1;
332 static int hf_smb_lanman = -1;
333 static int hf_smb_setup_action_guest = -1;
334 static int hf_smb_fs = -1;
335 static int hf_smb_connect_flags_dtid = -1;
336 static int hf_smb_connect_support_search = -1;
337 static int hf_smb_connect_support_in_dfs = -1;
338 static int hf_smb_max_setup_count = -1;
339 static int hf_smb_total_param_count = -1;
340 static int hf_smb_total_data_count = -1;
341 static int hf_smb_max_param_count = -1;
342 static int hf_smb_max_data_count = -1;
343 static int hf_smb_param_disp16 = -1;
344 static int hf_smb_param_count16 = -1;
345 static int hf_smb_param_offset16 = -1;
346 static int hf_smb_param_disp32 = -1;
347 static int hf_smb_param_count32 = -1;
348 static int hf_smb_param_offset32 = -1;
349 static int hf_smb_data_disp16 = -1;
350 static int hf_smb_data_count16 = -1;
351 static int hf_smb_data_offset16 = -1;
352 static int hf_smb_data_disp32 = -1;
353 static int hf_smb_data_count32 = -1;
354 static int hf_smb_data_offset32 = -1;
355 static int hf_smb_setup_count = -1;
356 static int hf_smb_nt_trans_subcmd = -1;
357 static int hf_smb_nt_ioctl_function_code = -1;
358 static int hf_smb_nt_ioctl_isfsctl = -1;
359 static int hf_smb_nt_ioctl_flags_root_handle = -1;
360 static int hf_smb_nt_ioctl_data = -1;
361 #ifdef SMB_UNUSED_HANDLES
362 static int hf_smb_nt_security_information = -1;
363 #endif
364 static int hf_smb_nt_notify_action = -1;
365 static int hf_smb_nt_notify_watch_tree = -1;
366 static int hf_smb_nt_notify_stream_write = -1;
367 static int hf_smb_nt_notify_stream_size = -1;
368 static int hf_smb_nt_notify_stream_name = -1;
369 static int hf_smb_nt_notify_security = -1;
370 static int hf_smb_nt_notify_ea = -1;
371 static int hf_smb_nt_notify_creation = -1;
372 static int hf_smb_nt_notify_last_access = -1;
373 static int hf_smb_nt_notify_last_write = -1;
374 static int hf_smb_nt_notify_size = -1;
375 static int hf_smb_nt_notify_attributes = -1;
376 static int hf_smb_nt_notify_dir_name = -1;
377 static int hf_smb_nt_notify_file_name = -1;
378 static int hf_smb_root_dir_fid = -1;
379 static int hf_smb_nt_create_disposition = -1;
380 static int hf_smb_sd_length = -1;
381 static int hf_smb_ea_list_length = -1;
382 static int hf_smb_ea_flags = -1;
383 static int hf_smb_ea_name_length = -1;
384 static int hf_smb_ea_data_length = -1;
385 static int hf_smb_ea_name = -1;
386 static int hf_smb_ea_data = -1;
387 static int hf_smb_file_name_len = -1;
388 static int hf_smb_nt_impersonation_level = -1;
389 static int hf_smb_nt_security_flags_context_tracking = -1;
390 static int hf_smb_nt_security_flags_effective_only = -1;
391 static int hf_smb_nt_access_mask_generic_read = -1;
392 static int hf_smb_nt_access_mask_generic_write = -1;
393 static int hf_smb_nt_access_mask_generic_execute = -1;
394 static int hf_smb_nt_access_mask_generic_all = -1;
395 static int hf_smb_nt_access_mask_maximum_allowed = -1;
396 static int hf_smb_nt_access_mask_system_security = -1;
397 static int hf_smb_nt_access_mask_synchronize = -1;
398 static int hf_smb_nt_access_mask_write_owner = -1;
399 static int hf_smb_nt_access_mask_write_dac = -1;
400 static int hf_smb_nt_access_mask_read_control = -1;
401 static int hf_smb_nt_access_mask_delete = -1;
402 static int hf_smb_nt_access_mask_write_attributes = -1;
403 static int hf_smb_nt_access_mask_read_attributes = -1;
404 static int hf_smb_nt_access_mask_delete_child = -1;
405 static int hf_smb_nt_access_mask_execute = -1;
406 static int hf_smb_nt_access_mask_write_ea = -1;
407 static int hf_smb_nt_access_mask_read_ea = -1;
408 static int hf_smb_nt_access_mask_append = -1;
409 static int hf_smb_nt_access_mask_write = -1;
410 static int hf_smb_nt_access_mask_read = -1;
411 static int hf_smb_nt_create_bits_oplock = -1;
412 static int hf_smb_nt_create_bits_boplock = -1;
413 static int hf_smb_nt_create_bits_dir = -1;
414 static int hf_smb_nt_create_bits_ext_resp = -1;
415 static int hf_smb_nt_create_options_directory_file = -1;
416 static int hf_smb_nt_create_options_write_through = -1;
417 static int hf_smb_nt_create_options_sequential_only = -1;
418 static int hf_smb_nt_create_options_sync_io_alert = -1;
419 static int hf_smb_nt_create_options_sync_io_nonalert = -1;
420 static int hf_smb_nt_create_options_non_directory_file = -1;
421 static int hf_smb_nt_create_options_no_ea_knowledge = -1;
422 static int hf_smb_nt_create_options_eight_dot_three_only = -1;
423 static int hf_smb_nt_create_options_random_access = -1;
424 static int hf_smb_nt_create_options_delete_on_close = -1;
425 static int hf_smb_nt_share_access_read = -1;
426 static int hf_smb_nt_share_access_write = -1;
427 static int hf_smb_nt_share_access_delete = -1;
428 static int hf_smb_file_eattr_read_only = -1;
429 static int hf_smb_file_eattr_hidden = -1;
430 static int hf_smb_file_eattr_system = -1;
431 static int hf_smb_file_eattr_volume = -1;
432 static int hf_smb_file_eattr_directory = -1;
433 static int hf_smb_file_eattr_archive = -1;
434 static int hf_smb_file_eattr_device = -1;
435 static int hf_smb_file_eattr_normal = -1;
436 static int hf_smb_file_eattr_temporary = -1;
437 static int hf_smb_file_eattr_sparse = -1;
438 static int hf_smb_file_eattr_reparse = -1;
439 static int hf_smb_file_eattr_compressed = -1;
440 static int hf_smb_file_eattr_offline = -1;
441 static int hf_smb_file_eattr_not_content_indexed = -1;
442 static int hf_smb_file_eattr_encrypted = -1;
443 static int hf_smb_sec_desc_len = -1;
444 static int hf_smb_sec_desc_revision = -1;
445 static int hf_smb_sec_desc_type_owner_defaulted = -1;
446 static int hf_smb_sec_desc_type_group_defaulted = -1;
447 static int hf_smb_sec_desc_type_dacl_present = -1;
448 static int hf_smb_sec_desc_type_dacl_defaulted = -1;
449 static int hf_smb_sec_desc_type_sacl_present = -1;
450 static int hf_smb_sec_desc_type_sacl_defaulted = -1;
451 static int hf_smb_sec_desc_type_dacl_auto_inherit_req = -1;
452 static int hf_smb_sec_desc_type_sacl_auto_inherit_req = -1;
453 static int hf_smb_sec_desc_type_dacl_auto_inherited = -1;
454 static int hf_smb_sec_desc_type_sacl_auto_inherited = -1;
455 static int hf_smb_sec_desc_type_dacl_protected = -1;
456 static int hf_smb_sec_desc_type_sacl_protected = -1;
457 static int hf_smb_sec_desc_type_self_relative = -1;
458 static int hf_smb_sid = -1;
459 static int hf_smb_sid_revision = -1;
460 static int hf_smb_sid_num_auth = -1;
461 static int hf_smb_acl_revision = -1;
462 static int hf_smb_acl_size = -1;
463 static int hf_smb_acl_num_aces = -1;
464 static int hf_smb_ace_type = -1;
465 static int hf_smb_ace_size = -1;
466 static int hf_smb_ace_flags_object_inherit = -1;
467 static int hf_smb_ace_flags_container_inherit = -1;
468 static int hf_smb_ace_flags_non_propagate_inherit = -1;
469 static int hf_smb_ace_flags_inherit_only = -1;
470 static int hf_smb_ace_flags_inherited_ace = -1;
471 static int hf_smb_ace_flags_successful_access = -1;
472 static int hf_smb_ace_flags_failed_access = -1;
473 static int hf_smb_nt_qsd_owner = -1;
474 static int hf_smb_nt_qsd_group = -1;
475 static int hf_smb_nt_qsd_dacl = -1;
476 static int hf_smb_nt_qsd_sacl = -1;
477 static int hf_smb_extended_attributes = -1;
478 static int hf_smb_oplock_level = -1;
479 static int hf_smb_create_action = -1;
480 static int hf_smb_file_id = -1;
481 static int hf_smb_ea_error_offset = -1;
482 static int hf_smb_end_of_file = -1;
483 static int hf_smb_replace = -1;
484 static int hf_smb_root_dir_handle = -1;
485 static int hf_smb_target_name_len = -1;
486 static int hf_smb_target_name = -1;
487 static int hf_smb_device_type = -1;
488 static int hf_smb_is_directory = -1;
489 static int hf_smb_next_entry_offset = -1;
490 static int hf_smb_change_time = -1;
491 static int hf_smb_setup_len = -1;
492 static int hf_smb_print_mode = -1;
493 static int hf_smb_print_identifier = -1;
494 static int hf_smb_restart_index = -1;
495 static int hf_smb_print_queue_date = -1;
496 static int hf_smb_print_queue_dos_date = -1;
497 static int hf_smb_print_queue_dos_time = -1;
498 static int hf_smb_print_status = -1;
499 static int hf_smb_print_spool_file_number = -1;
500 static int hf_smb_print_spool_file_size = -1;
501 static int hf_smb_print_spool_file_name = -1;
502 static int hf_smb_start_index = -1;
503 static int hf_smb_originator_name = -1;
504 static int hf_smb_destination_name = -1;
505 static int hf_smb_message_len = -1;
506 static int hf_smb_message = -1;
507 static int hf_smb_mgid = -1;
508 static int hf_smb_forwarded_name = -1;
509 static int hf_smb_machine_name = -1;
510 static int hf_smb_cancel_to = -1;
511 static int hf_smb_trans2_subcmd = -1;
512 static int hf_smb_trans_name = -1;
513 static int hf_smb_transaction_flags_dtid = -1;
514 static int hf_smb_transaction_flags_owt = -1;
515 static int hf_smb_search_count = -1;
516 static int hf_smb_search_pattern = -1;
517 static int hf_smb_ff2_backup = -1;
518 static int hf_smb_ff2_continue = -1;
519 static int hf_smb_ff2_resume = -1;
520 static int hf_smb_ff2_close_eos = -1;
521 static int hf_smb_ff2_close = -1;
522 static int hf_smb_ff2_information_level = -1;
523 static int hf_smb_qpi_loi = -1;
524 static int hf_smb_spi_loi = -1;
525 #if 0
526 static int hf_smb_sfi_writetru = -1;
527 static int hf_smb_sfi_caching = -1;
528 #endif
529 static int hf_smb_storage_type = -1;
530 static int hf_smb_resume = -1;
531 static int hf_smb_max_referral_level = -1;
532 static int hf_smb_qfsi_information_level = -1;
533 static int hf_smb_number_of_links = -1;
534 static int hf_smb_delete_pending = -1;
535 static int hf_smb_index_number = -1;
536 static int hf_smb_current_offset = -1;
537 static int hf_smb_t2_alignment = -1;
538 static int hf_smb_t2_stream_name_length = -1;
539 static int hf_smb_t2_stream_size = -1;
540 static int hf_smb_t2_stream_name = -1;
541 static int hf_smb_t2_compressed_file_size = -1;
542 static int hf_smb_t2_compressed_format = -1;
543 static int hf_smb_t2_compressed_unit_shift = -1;
544 static int hf_smb_t2_compressed_chunk_shift = -1;
545 static int hf_smb_t2_compressed_cluster_shift = -1;
546 static int hf_smb_t2_marked_for_deletion = -1;
547 static int hf_smb_dfs_path_consumed = -1;
548 static int hf_smb_dfs_num_referrals = -1;
549 static int hf_smb_get_dfs_server_hold_storage = -1;
550 static int hf_smb_get_dfs_fielding = -1;
551 static int hf_smb_dfs_referral_version = -1;
552 static int hf_smb_dfs_referral_size = -1;
553 static int hf_smb_dfs_referral_server_type = -1;
554 static int hf_smb_dfs_referral_flags_strip = -1;
555 static int hf_smb_dfs_referral_node_offset = -1;
556 static int hf_smb_dfs_referral_node = -1;
557 static int hf_smb_dfs_referral_proximity = -1;
558 static int hf_smb_dfs_referral_ttl = -1;
559 static int hf_smb_dfs_referral_path_offset = -1;
560 static int hf_smb_dfs_referral_path = -1;
561 static int hf_smb_dfs_referral_alt_path_offset = -1;
562 static int hf_smb_dfs_referral_alt_path = -1;
563 static int hf_smb_end_of_search = -1;
564 static int hf_smb_last_name_offset = -1;
565 static int hf_smb_fn_information_level = -1;
566 static int hf_smb_monitor_handle = -1;
567 static int hf_smb_change_count = -1;
568 static int hf_smb_file_index = -1;
569 static int hf_smb_short_file_name = -1;
570 static int hf_smb_short_file_name_len = -1;
571 static int hf_smb_fs_id = -1;
572 static int hf_smb_fs_guid = -1;
573 static int hf_smb_sector_unit = -1;
574 static int hf_smb_fs_units = -1;
575 static int hf_smb_fs_sector = -1;
576 static int hf_smb_avail_units = -1;
577 static int hf_smb_volume_serial_num = -1;
578 static int hf_smb_volume_label_len = -1;
579 static int hf_smb_volume_label = -1;
580 static int hf_smb_free_alloc_units64 = -1;
581 static int hf_smb_caller_free_alloc_units64 = -1;
582 static int hf_smb_actual_free_alloc_units64 = -1;
583 static int hf_smb_max_name_len = -1;
584 static int hf_smb_fs_name_len = -1;
585 static int hf_smb_fs_name = -1;
586 static int hf_smb_device_char_removable = -1;
587 static int hf_smb_device_char_read_only = -1;
588 static int hf_smb_device_char_floppy = -1;
589 static int hf_smb_device_char_write_once = -1;
590 static int hf_smb_device_char_remote = -1;
591 static int hf_smb_device_char_mounted = -1;
592 static int hf_smb_device_char_virtual = -1;
593 static int hf_smb_fs_attr_css = -1;
594 static int hf_smb_fs_attr_cpn = -1;
595 static int hf_smb_fs_attr_pacls = -1;
596 static int hf_smb_fs_attr_fc = -1;
597 static int hf_smb_fs_attr_vq = -1;
598 static int hf_smb_fs_attr_dim = -1;
599 static int hf_smb_fs_attr_vic = -1;
600 static int hf_smb_quota_flags_enabled = -1;
601 static int hf_smb_quota_flags_deny_disk = -1;
602 static int hf_smb_quota_flags_log_limit = -1;
603 static int hf_smb_quota_flags_log_warning = -1;
604 static int hf_smb_soft_quota_limit = -1;
605 static int hf_smb_hard_quota_limit = -1;
606 static int hf_smb_user_quota_used = -1;
607 static int hf_smb_user_quota_offset = -1;
608 static int hf_smb_nt_rename_level = -1;
609 static int hf_smb_cluster_count = -1;
610 static int hf_smb_segments = -1;
611 static int hf_smb_segment = -1;
612 static int hf_smb_segment_overlap = -1;
613 static int hf_smb_segment_overlap_conflict = -1;
614 static int hf_smb_segment_multiple_tails = -1;
615 static int hf_smb_segment_too_long_fragment = -1;
616 static int hf_smb_segment_error = -1;
617 static int hf_smb_pipe_write_len = -1;
618 static int hf_smb_unix_major_version = -1;
619 static int hf_smb_unix_minor_version = -1;
620 static int hf_smb_unix_capability_fcntl = -1;
621 static int hf_smb_unix_capability_posix_acl = -1;
622 static int hf_smb_unix_file_size = -1;
623 static int hf_smb_unix_file_num_bytes = -1;
624 static int hf_smb_unix_file_last_status = -1;
625 static int hf_smb_unix_file_last_access = -1;
626 static int hf_smb_unix_file_last_change = -1;
627 static int hf_smb_unix_file_uid = -1;
628 static int hf_smb_unix_file_gid = -1;
629 static int hf_smb_unix_file_type = -1;
630 static int hf_smb_unix_file_dev_major = -1;
631 static int hf_smb_unix_file_dev_minor = -1;
632 static int hf_smb_unix_file_unique_id = -1;
633 static int hf_smb_unix_file_permissions = -1;
634 static int hf_smb_unix_file_nlinks = -1;
635 static int hf_smb_unix_file_link_dest = -1;
636 static int hf_smb_unix_find_file_nextoffset = -1;
637 static int hf_smb_unix_find_file_resumekey = -1;
638
639 static gint ett_smb = -1;
640 static gint ett_smb_hdr = -1;
641 static gint ett_smb_command = -1;
642 static gint ett_smb_fileattributes = -1;
643 static gint ett_smb_capabilities = -1;
644 static gint ett_smb_aflags = -1;
645 static gint ett_smb_dialect = -1;
646 static gint ett_smb_dialects = -1;
647 static gint ett_smb_mode = -1;
648 static gint ett_smb_rawmode = -1;
649 static gint ett_smb_flags = -1;
650 static gint ett_smb_flags2 = -1;
651 static gint ett_smb_desiredaccess = -1;
652 static gint ett_smb_search = -1;
653 static gint ett_smb_file = -1;
654 static gint ett_smb_openfunction = -1;
655 static gint ett_smb_filetype = -1;
656 static gint ett_smb_openaction = -1;
657 static gint ett_smb_writemode = -1;
658 static gint ett_smb_lock_type = -1;
659 static gint ett_smb_ssetupandxaction = -1;
660 static gint ett_smb_optionsup = -1;
661 static gint ett_smb_time_date = -1;
662 static gint ett_smb_move_copy_flags = -1;
663 static gint ett_smb_file_attributes = -1;
664 static gint ett_smb_search_resume_key = -1;
665 static gint ett_smb_search_dir_info = -1;
666 static gint ett_smb_unlocks = -1;
667 static gint ett_smb_unlock = -1;
668 static gint ett_smb_locks = -1;
669 static gint ett_smb_lock = -1;
670 static gint ett_smb_open_flags = -1;
671 static gint ett_smb_ipc_state = -1;
672 static gint ett_smb_open_action = -1;
673 static gint ett_smb_setup_action = -1;
674 static gint ett_smb_connect_flags = -1;
675 static gint ett_smb_connect_support_bits = -1;
676 static gint ett_smb_nt_access_mask = -1;
677 static gint ett_smb_nt_create_bits = -1;
678 static gint ett_smb_nt_create_options = -1;
679 static gint ett_smb_nt_share_access = -1;
680 static gint ett_smb_nt_security_flags = -1;
681 static gint ett_smb_nt_trans_setup = -1;
682 static gint ett_smb_nt_trans_data = -1;
683 static gint ett_smb_nt_trans_param = -1;
684 static gint ett_smb_nt_notify_completion_filter = -1;
685 static gint ett_smb_nt_ioctl_flags = -1;
686 static gint ett_smb_security_information_mask = -1;
687 static gint ett_smb_print_queue_entry = -1;
688 static gint ett_smb_transaction_flags = -1;
689 static gint ett_smb_transaction_params = -1;
690 static gint ett_smb_find_first2_flags = -1;
691 static gint ett_smb_mac_support_flags = -1;
692 #if 0
693 static gint ett_smb_ioflag = -1;
694 #endif
695 static gint ett_smb_transaction_data = -1;
696 static gint ett_smb_stream_info = -1;
697 static gint ett_smb_dfs_referrals = -1;
698 static gint ett_smb_dfs_referral = -1;
699 static gint ett_smb_dfs_referral_flags = -1;
700 static gint ett_smb_get_dfs_flags = -1;
701 static gint ett_smb_ff2_data = -1;
702 static gint ett_smb_device_characteristics = -1;
703 static gint ett_smb_fs_attributes = -1;
704 static gint ett_smb_segments = -1;
705 static gint ett_smb_segment = -1;
706 static gint ett_smb_sec_desc = -1;
707 static gint ett_smb_sid = -1;
708 static gint ett_smb_acl = -1;
709 static gint ett_smb_ace = -1;
710 static gint ett_smb_ace_flags = -1;
711 static gint ett_smb_sec_desc_type = -1;
712 static gint ett_smb_quotaflags = -1;
713 static gint ett_smb_secblob = -1;
714 static gint ett_smb_unicode_password = -1;
715 static gint ett_smb_ea = -1;
716 static gint ett_smb_unix_capabilities = -1;
717
718 static int smb_tap = -1;
719
720 static dissector_handle_t gssapi_handle = NULL;
721 static dissector_handle_t ntlmssp_handle = NULL;
722
723 static const fragment_items smb_frag_items = {
724         &ett_smb_segment,
725         &ett_smb_segments,
726
727         &hf_smb_segments,
728         &hf_smb_segment,
729         &hf_smb_segment_overlap,
730         &hf_smb_segment_overlap_conflict,
731         &hf_smb_segment_multiple_tails,
732         &hf_smb_segment_too_long_fragment,
733         &hf_smb_segment_error,
734         NULL,
735
736         "segments"
737 };
738
739 proto_tree *top_tree=NULL;     /* ugly */
740
741 static char *decode_smb_name(guint8);
742 static int dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu);
743
744 /*
745  * Macros for use in the main dissector routines for an SMB.
746  */
747
748 #define WORD_COUNT      \
749         /* Word Count */                                \
750         wc = tvb_get_guint8(tvb, offset);               \
751         proto_tree_add_uint(tree, hf_smb_word_count,    \
752                 tvb, offset, 1, wc);                    \
753         offset += 1;                                    \
754         if(wc==0) goto bytecount;
755
756 #define BYTE_COUNT      \
757         bytecount:                                      \
758         bc = tvb_get_letohs(tvb, offset);               \
759         proto_tree_add_uint(tree, hf_smb_byte_count,    \
760                         tvb, offset, 2, bc);            \
761         offset += 2;                                    \
762         if(bc==0) goto endofcommand;
763
764 #define CHECK_BYTE_COUNT(len)   \
765         if (bc < len) goto endofcommand;
766
767 #define COUNT_BYTES(len)   {\
768         int tmp;            \
769         tmp=len;            \
770         offset += tmp;      \
771         bc -= tmp;          \
772         }
773
774 #define END_OF_SMB      \
775         if (bc != 0) { \
776                 gint bc_remaining; \
777                 bc_remaining=tvb_length_remaining(tvb, offset); \
778                 if( ((gint)bc) > bc_remaining){ \
779                         bc=bc_remaining; \
780                 } \
781                 if(bc){ \
782                         proto_tree_add_text(tree, tvb, offset, bc, \
783                             "Extra byte parameters");           \
784                 } \
785                 offset += bc;                           \
786         }                                               \
787         endofcommand:
788
789 /*
790  * Macros for use in routines called by them.
791  */
792 #define CHECK_BYTE_COUNT_SUBR(len)      \
793         if (*bcp < len) {               \
794                 *trunc = TRUE;          \
795                 return offset;          \
796         }
797
798 #define CHECK_STRING_SUBR(fn)   \
799         if (fn == NULL) {       \
800                 *trunc = TRUE;  \
801                 return offset;  \
802         }
803
804 #define COUNT_BYTES_SUBR(len)   \
805         offset += len;          \
806         *bcp -= len;
807
808 /*
809  * Macros for use when dissecting transaction parameters and data
810  */
811 #define CHECK_BYTE_COUNT_TRANS(len)     \
812         if (bc < len) return offset;
813
814 #define CHECK_STRING_TRANS(fn)  \
815         if (fn == NULL) return offset;
816
817 #define COUNT_BYTES_TRANS(len)  \
818         offset += len;          \
819         bc -= len;
820
821 /*
822  * Macros for use in subrroutines dissecting transaction parameters or data
823  */
824 #define CHECK_BYTE_COUNT_TRANS_SUBR(len)        \
825         if (*bcp < len) return offset;
826
827 #define CHECK_STRING_TRANS_SUBR(fn)     \
828         if (fn == NULL) return offset;
829
830 #define COUNT_BYTES_TRANS_SUBR(len)     \
831         offset += len;                  \
832         *bcp -= len;
833
834
835 gboolean sid_name_snooping = FALSE;
836
837 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
838    These are needed by the reassembly of SMB Transaction payload and DCERPC over SMB
839    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
840 static gboolean smb_trans_reassembly = FALSE;
841 gboolean smb_dcerpc_reassembly = FALSE;
842
843 static GHashTable *smb_trans_fragment_table = NULL;
844
845 static void
846 smb_trans_reassembly_init(void)
847 {
848         fragment_table_init(&smb_trans_fragment_table);
849 }
850
851 static fragment_data *
852 smb_trans_defragment(proto_tree *tree _U_, packet_info *pinfo, tvbuff_t *tvb,
853                      int offset, int count, int pos, int totlen)
854 {
855         fragment_data *fd_head=NULL;
856         smb_info_t *si;
857         int more_frags;
858
859         more_frags=totlen>(pos+count);
860
861         si = (smb_info_t *)pinfo->private_data;
862         if (si->sip == NULL) {
863                 /*
864                  * We don't have the frame number of the request.
865                  *
866                  * XXX - is there truly nothing we can do here?
867                  * Can we not separately keep track of the original
868                  * transaction and its continuations, as we did
869                  * at one time?
870                  *
871                  * It is probably not much point in even trying to do something here
872                  * if we have never seen the initial request. Without the initial
873                  * request we probably miss all parameters and the begining of data
874                  * so we cant even call a subdissector since we can not determine
875                  * which type of transaction call this is.
876                  */
877                 return NULL;
878         }
879
880         if(!pinfo->fd->flags.visited){
881                 fd_head = fragment_add(tvb, offset, pinfo,
882                                        si->sip->frame_req, smb_trans_fragment_table,
883                                        pos, count, more_frags);
884         } else {
885                 fd_head = fragment_get(pinfo, si->sip->frame_req, smb_trans_fragment_table);
886         }
887
888         /* we only show the defragmented packet for the first fragment,
889            or else we might end up with dissecting one HUGE transaction PDU
890            a LOT of times. (first fragment is the only one containing the setup
891            bytes)
892            I have seen ONE Transaction PDU that is ~60kb, spanning many Transaction
893            SMBs. Takes a LOT of time dissecting and is not fun.
894         */
895         if( (pos==0) && fd_head && fd_head->flags&FD_DEFRAGMENTED){
896                 return fd_head;
897         } else {
898                 return NULL;
899         }
900 }
901
902
903
904
905
906 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
907    These variables and functions are used to match
908    responses with calls
909    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
910 /*
911  * The information we need to save about a request in order to show the
912  * frame number of the request in the dissection of the reply.
913  */
914 typedef struct  {
915         guint32 frame;
916         guint32 pid_mid;
917 } smb_saved_info_key_t;
918
919 static GMemChunk *smb_saved_info_key_chunk = NULL;
920 static GMemChunk *smb_saved_info_chunk = NULL;
921 static int smb_saved_info_init_count = 200;
922
923 /* unmatched smb_saved_info structures.
924    For unmatched smb_saved_info structures we store the smb_saved_info
925    structure using the MID and the PID as the key.
926
927    Oh, yes, the key is really a pointer, but we use it as if it was an integer.
928    Ugly, yes. Not portable to DEC-20 Yes. But it saves a few bytes.
929    The key is the PID in the upper 16 bits and the MID in the lower 16 bits.
930 */
931 static gint
932 smb_saved_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
933 {
934         register guint32 key1 = (guint32)k1;
935         register guint32 key2 = (guint32)k2;
936         return key1==key2;
937 }
938 static guint
939 smb_saved_info_hash_unmatched(gconstpointer k)
940 {
941         register guint32 key = (guint32)k;
942         return key;
943 }
944
945 /* matched smb_saved_info structures.
946    For matched smb_saved_info structures we store the smb_saved_info
947    structure twice in the table using the frame number, and a combination
948    of the MID and the PID, as the key.
949    The frame number is guaranteed to be unique but if ever someone makes
950    some change that will renumber the frames in a capture we are in BIG trouble.
951    This is not likely though since that would break (among other things) all the
952    reassembly routines as well.
953
954    We also need the MID as there may be more than one SMB request or reply
955    in a single frame, and we also need the PID as there may be more than
956    one outstanding request with the same MID and different PIDs.
957 */
958 static gint
959 smb_saved_info_equal_matched(gconstpointer k1, gconstpointer k2)
960 {
961         const smb_saved_info_key_t *key1 = k1;
962         const smb_saved_info_key_t *key2 = k2;
963         return key1->frame == key2->frame && key1->pid_mid == key2->pid_mid;
964 }
965 static guint
966 smb_saved_info_hash_matched(gconstpointer k)
967 {
968         const smb_saved_info_key_t *key = k;
969         return key->frame + key->pid_mid;
970 }
971
972 static GMemChunk *smb_nt_transact_info_chunk = NULL;
973 static int smb_nt_transact_info_init_count = 200;
974
975 static GMemChunk *smb_transact2_info_chunk = NULL;
976 static int smb_transact2_info_init_count = 200;
977
978 /*
979  * The information we need to save about a Transaction request in order
980  * to dissect the reply; this includes information for use by the
981  * Remote API dissector.
982  */
983 static GMemChunk *smb_transact_info_chunk = NULL;
984 static int smb_transact_info_init_count = 200;
985
986 static GMemChunk *conv_tables_chunk = NULL;
987 static GSList *conv_tables = NULL;
988 static int conv_tables_count = 10;
989
990
991 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
992    End of request/response matching functions
993    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
994
995 static const value_string buffer_format_vals[] = {
996         {1,     "Data Block"},
997         {2,     "Dialect"},
998         {3,     "Pathname"},
999         {4,     "ASCII"},
1000         {5,     "Variable Block"},
1001         {0,     NULL}
1002 };
1003
1004 /*
1005  * UTIME - this is *almost* like a UNIX time stamp, except that it's
1006  * in seconds since January 1, 1970, 00:00:00 *local* time, not since
1007  * January 1, 1970, 00:00:00 GMT.
1008  *
1009  * This means we have to do some extra work to convert it.  This code is
1010  * based on the Samba code:
1011  *
1012  *      Unix SMB/Netbios implementation.
1013  *      Version 1.9.
1014  *      time handling functions
1015  *      Copyright (C) Andrew Tridgell 1992-1998
1016  */
1017
1018 /*
1019  * Yield the difference between *A and *B, in seconds, ignoring leap
1020  * seconds.
1021  */
1022 #define TM_YEAR_BASE 1900
1023
1024 static int
1025 tm_diff(struct tm *a, struct tm *b)
1026 {
1027         int ay = a->tm_year + (TM_YEAR_BASE - 1);
1028         int by = b->tm_year + (TM_YEAR_BASE - 1);
1029         int intervening_leap_days =
1030             (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
1031         int years = ay - by;
1032         int days =
1033             365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
1034         int hours = 24*days + (a->tm_hour - b->tm_hour);
1035         int minutes = 60*hours + (a->tm_min - b->tm_min);
1036         int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
1037
1038         return seconds;
1039 }
1040
1041 /*
1042  * Return the UTC offset in seconds west of UTC, or 0 if it cannot be
1043  * determined.
1044  */
1045 static int
1046 TimeZone(time_t t)
1047 {
1048         struct tm *tm = gmtime(&t);
1049         struct tm tm_utc;
1050
1051         if (tm == NULL)
1052                 return 0;
1053         tm_utc = *tm;
1054         tm = localtime(&t);
1055         if (tm == NULL)
1056                 return 0;
1057         return tm_diff(&tm_utc,tm);
1058 }
1059
1060 /*
1061  * Return the same value as TimeZone, but it should be more efficient.
1062  *
1063  * We keep a table of DST offsets to prevent calling localtime() on each
1064  * call of this function. This saves a LOT of time on many unixes.
1065  *
1066  * Updated by Paul Eggert <eggert@twinsun.com>
1067  */
1068 #ifndef CHAR_BIT
1069 #define CHAR_BIT 8
1070 #endif
1071
1072 #ifndef TIME_T_MIN
1073 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
1074                     : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
1075 #endif
1076 #ifndef TIME_T_MAX
1077 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
1078 #endif
1079
1080 static int
1081 TimeZoneFaster(time_t t)
1082 {
1083         static struct dst_table {time_t start,end; int zone;} *tdt;
1084         static struct dst_table *dst_table = NULL;
1085         static int table_size = 0;
1086         int i;
1087         int zone = 0;
1088
1089         if (t == 0)
1090                 t = time(NULL);
1091
1092         /* Tunis has a 8 day DST region, we need to be careful ... */
1093 #define MAX_DST_WIDTH (365*24*60*60)
1094 #define MAX_DST_SKIP (7*24*60*60)
1095
1096         for (i = 0; i < table_size; i++) {
1097                 if (t >= dst_table[i].start && t <= dst_table[i].end)
1098                         break;
1099         }
1100
1101         if (i < table_size) {
1102                 zone = dst_table[i].zone;
1103         } else {
1104                 time_t low,high;
1105
1106                 zone = TimeZone(t);
1107                 if (dst_table == NULL)
1108                         tdt = g_malloc(sizeof(dst_table[0])*(i+1));
1109                 else
1110                         tdt = g_realloc(dst_table, sizeof(dst_table[0])*(i+1));
1111                 if (tdt == NULL) {
1112                         if (dst_table)
1113                                 g_free(dst_table);
1114                         table_size = 0;
1115                 } else {
1116                         dst_table = tdt;
1117                         table_size++;
1118
1119                         dst_table[i].zone = zone;
1120                         dst_table[i].start = dst_table[i].end = t;
1121
1122                         /* no entry will cover more than 6 months */
1123                         low = t - MAX_DST_WIDTH/2;
1124                         if (t < low)
1125                                 low = TIME_T_MIN;
1126
1127                         high = t + MAX_DST_WIDTH/2;
1128                         if (high < t)
1129                                 high = TIME_T_MAX;
1130
1131                         /*
1132                          * Widen the new entry using two bisection searches.
1133                          */
1134                         while (low+60*60 < dst_table[i].start) {
1135                                 if (dst_table[i].start - low > MAX_DST_SKIP*2)
1136                                         t = dst_table[i].start - MAX_DST_SKIP;
1137                                 else
1138                                         t = low + (dst_table[i].start-low)/2;
1139                                 if (TimeZone(t) == zone)
1140                                         dst_table[i].start = t;
1141                                 else
1142                                         low = t;
1143                         }
1144
1145                         while (high-60*60 > dst_table[i].end) {
1146                                 if (high - dst_table[i].end > MAX_DST_SKIP*2)
1147                                         t = dst_table[i].end + MAX_DST_SKIP;
1148                                 else
1149                                         t = high - (high-dst_table[i].end)/2;
1150                                 if (TimeZone(t) == zone)
1151                                         dst_table[i].end = t;
1152                                 else
1153                                         high = t;
1154                         }
1155                 }
1156         }
1157         return zone;
1158 }
1159
1160 /*
1161  * Return the UTC offset in seconds west of UTC, adjusted for extra time
1162  * offset, for a local time value.  If ut = lt + LocTimeDiff(lt), then
1163  * lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
1164  * daylight savings transitions because some local times are ambiguous.
1165  * LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
1166  */
1167 static int
1168 LocTimeDiff(time_t lt)
1169 {
1170         int d = TimeZoneFaster(lt);
1171         time_t t = lt + d;
1172
1173         /* if overflow occurred, ignore all the adjustments so far */
1174         if (((t < lt) ^ (d < 0)))
1175                 t = lt;
1176
1177         /*
1178          * Now t should be close enough to the true UTC to yield the
1179          * right answer.
1180          */
1181         return TimeZoneFaster(t);
1182 }
1183
1184 static int
1185 dissect_smb_UTIME(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1186 {
1187         guint32 timeval;
1188         nstime_t ts;
1189
1190         timeval = tvb_get_letohl(tvb, offset);
1191         if (timeval == 0xffffffff) {
1192                 proto_tree_add_text(tree, tvb, offset, 4,
1193                     "%s: No time specified (0xffffffff)",
1194                     proto_registrar_get_name(hf_date));
1195                 offset += 4;
1196                 return offset;
1197         }
1198
1199         /*
1200          * We add the local time offset.
1201          */
1202         ts.secs = timeval + LocTimeDiff(timeval);
1203         ts.nsecs = 0;
1204
1205         proto_tree_add_time(tree, hf_date, tvb, offset, 4, &ts);
1206         offset += 4;
1207
1208         return offset;
1209 }
1210
1211 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
1212
1213 /*
1214  * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
1215  * to an "nstime_t".
1216  * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
1217  * midnight "UTC", in 100ns units.
1218  * Return TRUE if the conversion succeeds, FALSE otherwise.
1219  *
1220  * According to the Samba code, it appears to be kludge-GMT (at least for
1221  * file listings). This means it's the GMT you get by taking a local time
1222  * and adding the server time zone offset.  This is NOT the same as GMT in
1223  * some cases.   However, we don't know the server time zone, so we don't
1224  * do that adjustment.
1225  *
1226  * This code is based on the Samba code:
1227  *
1228  *      Unix SMB/Netbios implementation.
1229  *      Version 1.9.
1230  *      time handling functions
1231  *      Copyright (C) Andrew Tridgell 1992-1998
1232  */
1233 static gboolean
1234 nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
1235 {
1236         double d;
1237         /* The next two lines are a fix needed for the
1238             broken SCO compiler. JRA. */
1239         time_t l_time_min = TIME_T_MIN;
1240         time_t l_time_max = TIME_T_MAX;
1241
1242         if (filetime_high == 0)
1243                 return FALSE;
1244
1245         /*
1246          * Get the time as a double, in seconds and fractional seconds.
1247          */
1248         d = ((double)filetime_high)*4.0*(double)(1<<30);
1249         d += filetime_low;
1250         d *= 1.0e-7;
1251
1252         /* Now adjust by 369 years, to make the seconds since 1970. */
1253         d -= TIME_FIXUP_CONSTANT;
1254
1255         if (!(l_time_min <= d && d <= l_time_max))
1256                 return FALSE;
1257
1258         /*
1259          * Get the time as seconds and nanoseconds.
1260          */
1261         tv->secs = (time_t) d;
1262         tv->nsecs = (int) ((d - tv->secs)*1000000000);
1263
1264         return TRUE;
1265 }
1266
1267 int
1268 dissect_smb_64bit_time(tvbuff_t *tvb, proto_tree *tree, int offset, int hf_date)
1269 {
1270         guint32 filetime_high, filetime_low;
1271         nstime_t ts;
1272
1273         /* XXX there seems also to be another special time value which is fairly common :
1274            0x40000000 00000000
1275            the meaning of this one is yet unknown
1276         */
1277         if (tree) {
1278                 filetime_low = tvb_get_letohl(tvb, offset);
1279                 filetime_high = tvb_get_letohl(tvb, offset + 4);
1280                 if (filetime_low == 0 && filetime_high == 0) {
1281                         proto_tree_add_text(tree, tvb, offset, 8,
1282                             "%s: No time specified (0)",
1283                             proto_registrar_get_name(hf_date));
1284                 } else if(filetime_low==0 && filetime_high==0x80000000){
1285                         proto_tree_add_text(tree, tvb, offset, 8,
1286                             "%s: Infinity (relative time)",
1287                             proto_registrar_get_name(hf_date));
1288                 } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
1289                         proto_tree_add_text(tree, tvb, offset, 8,
1290                             "%s: Infinity (absolute time)",
1291                             proto_registrar_get_name(hf_date));
1292                 } else {
1293                         if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
1294                                 proto_tree_add_time(tree, hf_date, tvb,
1295                                     offset, 8, &ts);
1296                         } else {
1297                                 proto_tree_add_text(tree, tvb, offset, 8,
1298                                     "%s: Time can't be converted",
1299                                     proto_registrar_get_name(hf_date));
1300                         }
1301                 }
1302         }
1303
1304         offset += 8;
1305         return offset;
1306 }
1307
1308 static int
1309 dissect_smb_datetime(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1310     int hf_date, int hf_dos_date, int hf_dos_time, gboolean time_first)
1311 {
1312         guint16 dos_time, dos_date;
1313         proto_item *item = NULL;
1314         proto_tree *tree = NULL;
1315         struct tm tm;
1316         time_t t;
1317         static const int mday_noleap[12] = {
1318                 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1319         };
1320         static const int mday_leap[12] = {
1321                 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1322         };
1323 #define ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1324         nstime_t tv;
1325
1326         if (time_first) {
1327                 dos_time = tvb_get_letohs(tvb, offset);
1328                 dos_date = tvb_get_letohs(tvb, offset+2);
1329         } else {
1330                 dos_date = tvb_get_letohs(tvb, offset);
1331                 dos_time = tvb_get_letohs(tvb, offset+2);
1332         }
1333
1334         if ((dos_date == 0xffff && dos_time == 0xffff) ||
1335             (dos_date == 0 && dos_time == 0)) {
1336                 /*
1337                  * No date/time specified.
1338                  */
1339                 if(parent_tree){
1340                         proto_tree_add_text(parent_tree, tvb, offset, 4,
1341                             "%s: No time specified (0x%08x)",
1342                             proto_registrar_get_name(hf_date),
1343                             (dos_date << 16) | dos_time);
1344                 }
1345                 offset += 4;
1346                 return offset;
1347         }
1348
1349         tm.tm_sec = (dos_time&0x1f)*2;
1350         tm.tm_min = (dos_time>>5)&0x3f;
1351         tm.tm_hour = (dos_time>>11)&0x1f;
1352         tm.tm_mday = dos_date&0x1f;
1353         tm.tm_mon = ((dos_date>>5)&0x0f) - 1;
1354         tm.tm_year = ((dos_date>>9)&0x7f) + 1980 - 1900;
1355         tm.tm_isdst = -1;
1356
1357         /*
1358          * Do some sanity checks before calling "mktime()";
1359          * "mktime()" doesn't do them, it "normalizes" out-of-range
1360          * values.
1361          */
1362         if (tm.tm_sec > 59 || tm.tm_min > 59 || tm.tm_hour > 23 ||
1363            tm.tm_mon < 0 || tm.tm_mon > 11 ||
1364            (ISLEAP(tm.tm_year + 1900) ?
1365              tm.tm_mday > mday_leap[tm.tm_mon] :
1366              tm.tm_mday > mday_noleap[tm.tm_mon]) ||
1367              (t = mktime(&tm)) == -1) {
1368                 /*
1369                  * Invalid date/time.
1370                  */
1371                 if (parent_tree) {
1372                         item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1373                             "%s: Invalid time",
1374                             proto_registrar_get_name(hf_date));
1375                         tree = proto_item_add_subtree(item, ett_smb_time_date);
1376                         if (time_first) {
1377                                 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);
1378                                 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);
1379                         } else {
1380                                 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);
1381                                 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);
1382                         }
1383                 }
1384                 offset += 4;
1385                 return offset;
1386         }
1387
1388         tv.secs = t;
1389         tv.nsecs = 0;
1390
1391         if(parent_tree){
1392                 item = proto_tree_add_time(parent_tree, hf_date, tvb, offset, 4, &tv);
1393                 tree = proto_item_add_subtree(item, ett_smb_time_date);
1394                 if (time_first) {
1395                         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);
1396                         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);
1397                 } else {
1398                         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);
1399                         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);
1400                 }
1401         }
1402
1403         offset += 4;
1404
1405         return offset;
1406 }
1407
1408
1409 static const value_string da_access_vals[] = {
1410         { 0,            "Open for reading"},
1411         { 1,            "Open for writing"},
1412         { 2,            "Open for reading and writing"},
1413         { 3,            "Open for execute"},
1414         {0, NULL}
1415 };
1416 static const value_string da_sharing_vals[] = {
1417         { 0,            "Compatibility mode"},
1418         { 1,            "Deny read/write/execute (exclusive)"},
1419         { 2,            "Deny write"},
1420         { 3,            "Deny read/execute"},
1421         { 4,            "Deny none"},
1422         {0, NULL}
1423 };
1424 static const value_string da_locality_vals[] = {
1425         { 0,            "Locality of reference unknown"},
1426         { 1,            "Mainly sequential access"},
1427         { 2,            "Mainly random access"},
1428         { 3,            "Random access with some locality"},
1429         {0, NULL}
1430 };
1431 static const true_false_string tfs_da_caching = {
1432         "Do not cache this file",
1433         "Caching permitted on this file"
1434 };
1435 static const true_false_string tfs_da_writetru = {
1436         "Write through enabled",
1437         "Write through disabled"
1438 };
1439 static int
1440 dissect_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset, char *type)
1441 {
1442         guint16 mask;
1443         proto_item *item = NULL;
1444         proto_tree *tree = NULL;
1445
1446         mask = tvb_get_letohs(tvb, offset);
1447
1448         if(parent_tree){
1449                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1450                         "%s Access: 0x%04x", type, mask);
1451                 tree = proto_item_add_subtree(item, ett_smb_desiredaccess);
1452         }
1453
1454         proto_tree_add_boolean(tree, hf_smb_access_writetru,
1455                 tvb, offset, 2, mask);
1456         proto_tree_add_boolean(tree, hf_smb_access_caching,
1457                 tvb, offset, 2, mask);
1458         proto_tree_add_uint(tree, hf_smb_access_locality,
1459                 tvb, offset, 2, mask);
1460         proto_tree_add_uint(tree, hf_smb_access_sharing,
1461                 tvb, offset, 2, mask);
1462         proto_tree_add_uint(tree, hf_smb_access_mode,
1463                 tvb, offset, 2, mask);
1464
1465         offset += 2;
1466
1467         return offset;
1468 }
1469
1470 #define SMB_FILE_ATTRIBUTE_READ_ONLY            0x00000001
1471 #define SMB_FILE_ATTRIBUTE_HIDDEN               0x00000002
1472 #define SMB_FILE_ATTRIBUTE_SYSTEM               0x00000004
1473 #define SMB_FILE_ATTRIBUTE_VOLUME               0x00000008
1474 #define SMB_FILE_ATTRIBUTE_DIRECTORY            0x00000010
1475 #define SMB_FILE_ATTRIBUTE_ARCHIVE              0x00000020
1476 #define SMB_FILE_ATTRIBUTE_DEVICE               0x00000040
1477 #define SMB_FILE_ATTRIBUTE_NORMAL               0x00000080
1478 #define SMB_FILE_ATTRIBUTE_TEMPORARY            0x00000100
1479 #define SMB_FILE_ATTRIBUTE_SPARSE               0x00000200
1480 #define SMB_FILE_ATTRIBUTE_REPARSE              0x00000400
1481 #define SMB_FILE_ATTRIBUTE_COMPRESSED           0x00000800
1482 #define SMB_FILE_ATTRIBUTE_OFFLINE              0x00001000
1483 #define SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
1484 #define SMB_FILE_ATTRIBUTE_ENCRYPTED            0x00004000
1485
1486 static const true_false_string tfs_file_attribute_read_only = {
1487         "This file is READ ONLY",
1488         "This file is NOT read only",
1489 };
1490 static const true_false_string tfs_file_attribute_hidden = {
1491         "This is a HIDDEN file",
1492         "This is NOT a hidden file"
1493 };
1494 static const true_false_string tfs_file_attribute_system = {
1495         "This is a SYSTEM file",
1496         "This is NOT a system file"
1497 };
1498 static const true_false_string tfs_file_attribute_volume = {
1499         "This is a VOLUME ID",
1500         "This is NOT a volume ID"
1501 };
1502 static const true_false_string tfs_file_attribute_directory = {
1503         "This is a DIRECTORY",
1504         "This is NOT a directory"
1505 };
1506 static const true_false_string tfs_file_attribute_archive = {
1507         "This file has been modified since last ARCHIVE",
1508         "This file has NOT been modified since last archive"
1509 };
1510 static const true_false_string tfs_file_attribute_device = {
1511         "This is a DEVICE",
1512         "This is NOT a device"
1513 };
1514 static const true_false_string tfs_file_attribute_normal = {
1515         "This file is an ordinary file",
1516         "This file has some attribute set"
1517 };
1518 static const true_false_string tfs_file_attribute_temporary = {
1519         "This is a TEMPORARY file",
1520         "This is NOT a temporary file"
1521 };
1522 static const true_false_string tfs_file_attribute_sparse = {
1523         "This is a SPARSE file",
1524         "This is NOT a sparse file"
1525 };
1526 static const true_false_string tfs_file_attribute_reparse = {
1527         "This file has an associated REPARSE POINT",
1528         "This file does NOT have an associated reparse point"
1529 };
1530 static const true_false_string tfs_file_attribute_compressed = {
1531         "This is a COMPRESSED file",
1532         "This is NOT a compressed file"
1533 };
1534 static const true_false_string tfs_file_attribute_offline = {
1535         "This file is OFFLINE",
1536         "This file is NOT offline"
1537 };
1538 static const true_false_string tfs_file_attribute_not_content_indexed = {
1539         "This file MAY NOT be indexed by the CONTENT INDEXING service",
1540         "This file MAY be indexed by the content indexing service"
1541 };
1542 static const true_false_string tfs_file_attribute_encrypted = {
1543         "This is an ENCRYPTED file",
1544         "This is NOT an encrypted file"
1545 };
1546
1547 /*
1548  * In some places in the CIFS_TR_1p00.pdf, from SNIA, file attributes are 
1549  * listed as USHORT, and seem to be in packets in the wild, while in other
1550  * places they are listed as ULONG, and also seem to be.
1551  *
1552  * So, I (Richard Sharpe), added a parameter to allow us to specify how many
1553  * bytes to consume.
1554  */
1555
1556 static int
1557 dissect_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
1558                         int bytes)
1559 {
1560         guint16 mask;
1561         proto_item *item = NULL;
1562         proto_tree *tree = NULL;
1563
1564         if (bytes != 2 && bytes != 4) {
1565
1566                 fprintf(stderr, "Incorrect number of bytes passed to dissect_file_attributes.\nMust be 2 or 4, was %d\n", bytes);
1567                 exit(1);
1568
1569         }
1570
1571         /*
1572          * The actual bits of interest appear to only be a USHORT
1573          */
1574         /* FIXME if this ever changes! */
1575         mask = tvb_get_letohs(tvb, offset);
1576
1577         if(parent_tree){
1578                 item = proto_tree_add_text(parent_tree, tvb, offset, bytes,
1579                         "File Attributes: 0x%08x", mask);
1580                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1581         }
1582         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted, 
1583                                tvb, offset, bytes, mask);       
1584         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed, 
1585                                tvb, offset, bytes, mask);
1586         proto_tree_add_boolean(tree, hf_smb_file_attr_offline, 
1587                                tvb, offset, bytes, mask);
1588         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed, 
1589                                tvb, offset, bytes, mask);
1590         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse, 
1591                                tvb, offset, bytes, mask);
1592         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse, 
1593                                tvb, offset, bytes, mask);
1594         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary, 
1595                                tvb, offset, bytes, mask);
1596         proto_tree_add_boolean(tree, hf_smb_file_attr_normal, 
1597                                tvb, offset, bytes, mask);
1598         proto_tree_add_boolean(tree, hf_smb_file_attr_device, 
1599                                tvb, offset, bytes, mask);
1600         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1601                 tvb, offset, bytes, mask);
1602         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1603                 tvb, offset, bytes, mask);
1604         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1605                 tvb, offset, bytes, mask);
1606         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1607                 tvb, offset, bytes, mask);
1608         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1609                 tvb, offset, bytes, mask);
1610         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1611                 tvb, offset, bytes, mask);
1612
1613         offset += bytes;
1614
1615         return offset;
1616 }
1617
1618 /* 3.11 */
1619 static int
1620 dissect_file_ext_attr(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1621 {
1622         guint32 mask;
1623         proto_item *item = NULL;
1624         proto_tree *tree = NULL;
1625
1626         mask = tvb_get_letohl(tvb, offset);
1627
1628         if(parent_tree){
1629                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
1630                         "File Attributes: 0x%08x", mask);
1631                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1632         }
1633
1634         /*
1635          * XXX - Network Monitor disagrees on some of the
1636          * bits, e.g. the bits above temporary are "atomic write"
1637          * and "transaction write", and it says nothing about the
1638          * bits above that.
1639          *
1640          * Does the Win32 API documentation, or the NT Native API book,
1641          * suggest anything?
1642          */
1643         proto_tree_add_boolean(tree, hf_smb_file_eattr_encrypted,
1644                 tvb, offset, 4, mask);
1645         proto_tree_add_boolean(tree, hf_smb_file_eattr_not_content_indexed,
1646                 tvb, offset, 4, mask);
1647         proto_tree_add_boolean(tree, hf_smb_file_eattr_offline,
1648                 tvb, offset, 4, mask);
1649         proto_tree_add_boolean(tree, hf_smb_file_eattr_compressed,
1650                 tvb, offset, 4, mask);
1651         proto_tree_add_boolean(tree, hf_smb_file_eattr_reparse,
1652                 tvb, offset, 4, mask);
1653         proto_tree_add_boolean(tree, hf_smb_file_eattr_sparse,
1654                 tvb, offset, 4, mask);
1655         proto_tree_add_boolean(tree, hf_smb_file_eattr_temporary,
1656                 tvb, offset, 4, mask);
1657         proto_tree_add_boolean(tree, hf_smb_file_eattr_normal,
1658                 tvb, offset, 4, mask);
1659         proto_tree_add_boolean(tree, hf_smb_file_eattr_device,
1660                 tvb, offset, 4, mask);
1661         proto_tree_add_boolean(tree, hf_smb_file_eattr_archive,
1662                 tvb, offset, 4, mask);
1663         proto_tree_add_boolean(tree, hf_smb_file_eattr_directory,
1664                 tvb, offset, 4, mask);
1665         proto_tree_add_boolean(tree, hf_smb_file_eattr_volume,
1666                 tvb, offset, 4, mask);
1667         proto_tree_add_boolean(tree, hf_smb_file_eattr_system,
1668                 tvb, offset, 4, mask);
1669         proto_tree_add_boolean(tree, hf_smb_file_eattr_hidden,
1670                 tvb, offset, 4, mask);
1671         proto_tree_add_boolean(tree, hf_smb_file_eattr_read_only,
1672                 tvb, offset, 4, mask);
1673
1674         offset += 4;
1675
1676         return offset;
1677 }
1678
1679 static int
1680 dissect_dir_info_file_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1681 {
1682         guint8 mask;
1683         proto_item *item = NULL;
1684         proto_tree *tree = NULL;
1685
1686         mask = tvb_get_guint8(tvb, offset);
1687
1688         if(parent_tree){
1689                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
1690                         "File Attributes: 0x%02x", mask);
1691                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1692         }
1693         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_8bit,
1694                 tvb, offset, 1, mask);
1695         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_8bit,
1696                 tvb, offset, 1, mask);
1697         proto_tree_add_boolean(tree, hf_smb_file_attr_system_8bit,
1698                 tvb, offset, 1, mask);
1699         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_8bit,
1700                 tvb, offset, 1, mask);
1701         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_8bit,
1702                 tvb, offset, 1, mask);
1703         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_8bit,
1704                 tvb, offset, 1, mask);
1705
1706         offset += 1;
1707
1708         return offset;
1709 }
1710
1711 static const true_false_string tfs_search_attribute_read_only = {
1712         "Include READ ONLY files in search results",
1713         "Do NOT include read only files in search results",
1714 };
1715 static const true_false_string tfs_search_attribute_hidden = {
1716         "Include HIDDEN files in search results",
1717         "Do NOT include hidden files in search results"
1718 };
1719 static const true_false_string tfs_search_attribute_system = {
1720         "Include SYSTEM files in search results",
1721         "Do NOT include system files in search results"
1722 };
1723 static const true_false_string tfs_search_attribute_volume = {
1724         "Include VOLUME IDs in search results",
1725         "Do NOT include volume IDs in search results"
1726 };
1727 static const true_false_string tfs_search_attribute_directory = {
1728         "Include DIRECTORIES in search results",
1729         "Do NOT include directories in search results"
1730 };
1731 static const true_false_string tfs_search_attribute_archive = {
1732         "Include ARCHIVE files in search results",
1733         "Do NOT include archive files in search results"
1734 };
1735
1736 static int
1737 dissect_search_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1738 {
1739         guint16 mask;
1740         proto_item *item = NULL;
1741         proto_tree *tree = NULL;
1742
1743         mask = tvb_get_letohs(tvb, offset);
1744
1745         if(parent_tree){
1746                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1747                         "Search Attributes: 0x%04x", mask);
1748                 tree = proto_item_add_subtree(item, ett_smb_search);
1749         }
1750
1751         proto_tree_add_boolean(tree, hf_smb_search_attribute_read_only,
1752                 tvb, offset, 2, mask);
1753         proto_tree_add_boolean(tree, hf_smb_search_attribute_hidden,
1754                 tvb, offset, 2, mask);
1755         proto_tree_add_boolean(tree, hf_smb_search_attribute_system,
1756                 tvb, offset, 2, mask);
1757         proto_tree_add_boolean(tree, hf_smb_search_attribute_volume,
1758                 tvb, offset, 2, mask);
1759         proto_tree_add_boolean(tree, hf_smb_search_attribute_directory,
1760                 tvb, offset, 2, mask);
1761         proto_tree_add_boolean(tree, hf_smb_search_attribute_archive,
1762                 tvb, offset, 2, mask);
1763
1764         offset += 2;
1765         return offset;
1766 }
1767
1768 #if 0
1769 /*
1770  * XXX - this isn't used.
1771  * Is this used for anything?  NT Create AndX doesn't use it.
1772  * Is there some 16-bit attribute field with more bits than Read Only,
1773  * Hidden, System, Volume ID, Directory, and Archive?
1774  */
1775 static int
1776 dissect_extended_file_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
1777 {
1778         guint32 mask;
1779         proto_item *item = NULL;
1780         proto_tree *tree = NULL;
1781
1782         mask = tvb_get_letohl(tvb, offset);
1783
1784         if(parent_tree){
1785                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
1786                         "File Attributes: 0x%08x", mask);
1787                 tree = proto_item_add_subtree(item, ett_smb_file_attributes);
1788         }
1789         proto_tree_add_boolean(tree, hf_smb_file_attr_read_only_16bit,
1790                 tvb, offset, 2, mask);
1791         proto_tree_add_boolean(tree, hf_smb_file_attr_hidden_16bit,
1792                 tvb, offset, 2, mask);
1793         proto_tree_add_boolean(tree, hf_smb_file_attr_system_16bit,
1794                 tvb, offset, 2, mask);
1795         proto_tree_add_boolean(tree, hf_smb_file_attr_volume_16bit,
1796                 tvb, offset, 2, mask);
1797         proto_tree_add_boolean(tree, hf_smb_file_attr_directory_16bit,
1798                 tvb, offset, 2, mask);
1799         proto_tree_add_boolean(tree, hf_smb_file_attr_archive_16bit,
1800                 tvb, offset, 2, mask);
1801         proto_tree_add_boolean(tree, hf_smb_file_attr_device,
1802                 tvb, offset, 2, mask);
1803         proto_tree_add_boolean(tree, hf_smb_file_attr_normal,
1804                 tvb, offset, 2, mask);
1805         proto_tree_add_boolean(tree, hf_smb_file_attr_temporary,
1806                 tvb, offset, 2, mask);
1807         proto_tree_add_boolean(tree, hf_smb_file_attr_sparse,
1808                 tvb, offset, 2, mask);
1809         proto_tree_add_boolean(tree, hf_smb_file_attr_reparse,
1810                 tvb, offset, 2, mask);
1811         proto_tree_add_boolean(tree, hf_smb_file_attr_compressed,
1812                 tvb, offset, 2, mask);
1813         proto_tree_add_boolean(tree, hf_smb_file_attr_offline,
1814                 tvb, offset, 2, mask);
1815         proto_tree_add_boolean(tree, hf_smb_file_attr_not_content_indexed,
1816                 tvb, offset, 2, mask);
1817         proto_tree_add_boolean(tree, hf_smb_file_attr_encrypted,
1818                 tvb, offset, 2, mask);
1819
1820         offset += 2;
1821
1822         return offset;
1823 }
1824 #endif
1825
1826
1827 #define SERVER_CAP_RAW_MODE            0x00000001
1828 #define SERVER_CAP_MPX_MODE            0x00000002
1829 #define SERVER_CAP_UNICODE             0x00000004
1830 #define SERVER_CAP_LARGE_FILES         0x00000008
1831 #define SERVER_CAP_NT_SMBS             0x00000010
1832 #define SERVER_CAP_RPC_REMOTE_APIS     0x00000020
1833 #define SERVER_CAP_STATUS32            0x00000040
1834 #define SERVER_CAP_LEVEL_II_OPLOCKS    0x00000080
1835 #define SERVER_CAP_LOCK_AND_READ       0x00000100
1836 #define SERVER_CAP_NT_FIND             0x00000200
1837 #define SERVER_CAP_DFS                 0x00001000
1838 #define SERVER_CAP_INFOLEVEL_PASSTHRU  0x00002000
1839 #define SERVER_CAP_LARGE_READX         0x00004000
1840 #define SERVER_CAP_LARGE_WRITEX        0x00008000
1841 #define SERVER_CAP_UNIX                0x00800000
1842 #define SERVER_CAP_RESERVED            0x02000000
1843 #define SERVER_CAP_BULK_TRANSFER       0x20000000
1844 #define SERVER_CAP_COMPRESSED_DATA     0x40000000
1845 #define SERVER_CAP_EXTENDED_SECURITY   0x80000000
1846 static const true_false_string tfs_server_cap_raw_mode = {
1847         "Read Raw and Write Raw are supported",
1848         "Read Raw and Write Raw are not supported"
1849 };
1850 static const true_false_string tfs_server_cap_mpx_mode = {
1851         "Read Mpx and Write Mpx are supported",
1852         "Read Mpx and Write Mpx are not supported"
1853 };
1854 static const true_false_string tfs_server_cap_unicode = {
1855         "Unicode strings are supported",
1856         "Unicode strings are not supported"
1857 };
1858 static const true_false_string tfs_server_cap_large_files = {
1859         "Large files are supported",
1860         "Large files are not supported",
1861 };
1862 static const true_false_string tfs_server_cap_nt_smbs = {
1863         "NT SMBs are supported",
1864         "NT SMBs are not supported"
1865 };
1866 static const true_false_string tfs_server_cap_rpc_remote_apis = {
1867         "RPC remote APIs are supported",
1868         "RPC remote APIs are not supported"
1869 };
1870 static const true_false_string tfs_server_cap_nt_status = {
1871         "NT status codes are supported",
1872         "NT status codes are not supported"
1873 };
1874 static const true_false_string tfs_server_cap_level_ii_oplocks = {
1875         "Level 2 oplocks are supported",
1876         "Level 2 oplocks are not supported"
1877 };
1878 static const true_false_string tfs_server_cap_lock_and_read = {
1879         "Lock and Read is supported",
1880         "Lock and Read is not supported"
1881 };
1882 static const true_false_string tfs_server_cap_nt_find = {
1883         "NT Find is supported",
1884         "NT Find is not supported"
1885 };
1886 static const true_false_string tfs_server_cap_dfs = {
1887         "Dfs is supported",
1888         "Dfs is not supported"
1889 };
1890 static const true_false_string tfs_server_cap_infolevel_passthru = {
1891         "NT information level request passthrough is supported",
1892         "NT information level request passthrough is not supported"
1893 };
1894 static const true_false_string tfs_server_cap_large_readx = {
1895         "Large Read andX is supported",
1896         "Large Read andX is not supported"
1897 };
1898 static const true_false_string tfs_server_cap_large_writex = {
1899         "Large Write andX is supported",
1900         "Large Write andX is not supported"
1901 };
1902 static const true_false_string tfs_server_cap_unix = {
1903         "UNIX extensions are supported",
1904         "UNIX extensions are not supported"
1905 };
1906 static const true_false_string tfs_server_cap_reserved = {
1907         "Reserved",
1908         "Reserved"
1909 };
1910 static const true_false_string tfs_server_cap_bulk_transfer = {
1911         "Bulk Read and Bulk Write are supported",
1912         "Bulk Read and Bulk Write are not supported"
1913 };
1914 static const true_false_string tfs_server_cap_compressed_data = {
1915         "Compressed data transfer is supported",
1916         "Compressed data transfer is not supported"
1917 };
1918 static const true_false_string tfs_server_cap_extended_security = {
1919         "Extended security exchanges are supported",
1920         "Extended security exchanges are not supported"
1921 };
1922 static int
1923 dissect_negprot_capabilities(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1924 {
1925         guint32 mask;
1926         proto_item *item = NULL;
1927         proto_tree *tree = NULL;
1928
1929         mask = tvb_get_letohl(tvb, offset);
1930
1931         if(parent_tree){
1932                 item = proto_tree_add_text(parent_tree, tvb, offset, 4, "Capabilities: 0x%08x", mask);
1933                 tree = proto_item_add_subtree(item, ett_smb_capabilities);
1934         }
1935
1936         proto_tree_add_boolean(tree, hf_smb_server_cap_raw_mode,
1937                 tvb, offset, 4, mask);
1938         proto_tree_add_boolean(tree, hf_smb_server_cap_mpx_mode,
1939                 tvb, offset, 4, mask);
1940         proto_tree_add_boolean(tree, hf_smb_server_cap_unicode,
1941                 tvb, offset, 4, mask);
1942         proto_tree_add_boolean(tree, hf_smb_server_cap_large_files,
1943                 tvb, offset, 4, mask);
1944         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_smbs,
1945                 tvb, offset, 4, mask);
1946         proto_tree_add_boolean(tree, hf_smb_server_cap_rpc_remote_apis,
1947                 tvb, offset, 4, mask);
1948         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_status,
1949                 tvb, offset, 4, mask);
1950         proto_tree_add_boolean(tree, hf_smb_server_cap_level_ii_oplocks,
1951                 tvb, offset, 4, mask);
1952         proto_tree_add_boolean(tree, hf_smb_server_cap_lock_and_read,
1953                 tvb, offset, 4, mask);
1954         proto_tree_add_boolean(tree, hf_smb_server_cap_nt_find,
1955                 tvb, offset, 4, mask);
1956         proto_tree_add_boolean(tree, hf_smb_server_cap_dfs,
1957                 tvb, offset, 4, mask);
1958         proto_tree_add_boolean(tree, hf_smb_server_cap_infolevel_passthru,
1959                 tvb, offset, 4, mask);
1960         proto_tree_add_boolean(tree, hf_smb_server_cap_large_readx,
1961                 tvb, offset, 4, mask);
1962         proto_tree_add_boolean(tree, hf_smb_server_cap_large_writex,
1963                 tvb, offset, 4, mask);
1964         proto_tree_add_boolean(tree, hf_smb_server_cap_unix,
1965                 tvb, offset, 4, mask);
1966         proto_tree_add_boolean(tree, hf_smb_server_cap_reserved,
1967                 tvb, offset, 4, mask);
1968         proto_tree_add_boolean(tree, hf_smb_server_cap_bulk_transfer,
1969                 tvb, offset, 4, mask);
1970         proto_tree_add_boolean(tree, hf_smb_server_cap_compressed_data,
1971                 tvb, offset, 4, mask);
1972         proto_tree_add_boolean(tree, hf_smb_server_cap_extended_security,
1973                 tvb, offset, 4, mask);
1974
1975         return mask;
1976 }
1977
1978 #define RAWMODE_READ   0x01
1979 #define RAWMODE_WRITE  0x02
1980 static const true_false_string tfs_rm_read = {
1981         "Read Raw is supported",
1982         "Read Raw is not supported"
1983 };
1984 static const true_false_string tfs_rm_write = {
1985         "Write Raw is supported",
1986         "Write Raw is not supported"
1987 };
1988
1989 static int
1990 dissect_negprot_rawmode(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
1991 {
1992         guint16 mask;
1993         proto_item *item = NULL;
1994         proto_tree *tree = NULL;
1995
1996         mask = tvb_get_letohs(tvb, offset);
1997
1998         if(parent_tree){
1999                 item = proto_tree_add_text(parent_tree, tvb, offset, 2, "Raw Mode: 0x%04x", mask);
2000                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
2001         }
2002
2003         proto_tree_add_boolean(tree, hf_smb_rm_read, tvb, offset, 2, mask);
2004         proto_tree_add_boolean(tree, hf_smb_rm_write, tvb, offset, 2, mask);
2005
2006         offset += 2;
2007
2008         return offset;
2009 }
2010
2011 #define SECURITY_MODE_MODE             0x01
2012 #define SECURITY_MODE_PASSWORD         0x02
2013 #define SECURITY_MODE_SIGNATURES       0x04
2014 #define SECURITY_MODE_SIG_REQUIRED     0x08
2015 static const true_false_string tfs_sm_mode = {
2016         "USER security mode",
2017         "SHARE security mode"
2018 };
2019 static const true_false_string tfs_sm_password = {
2020         "ENCRYPTED password. Use challenge/response",
2021         "PLAINTEXT password"
2022 };
2023 static const true_false_string tfs_sm_signatures = {
2024         "Security signatures ENABLED",
2025         "Security signatures NOT enabled"
2026 };
2027 static const true_false_string tfs_sm_sig_required = {
2028         "Security signatures REQUIRED",
2029         "Security signatures NOT required"
2030 };
2031
2032 static int
2033 dissect_negprot_security_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int wc)
2034 {
2035         guint16 mask = 0;
2036         proto_item *item = NULL;
2037         proto_tree *tree = NULL;
2038
2039         switch(wc){
2040         case 13:
2041                 mask = tvb_get_letohs(tvb, offset);
2042                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2043                                 "Security Mode: 0x%04x", mask);
2044                 tree = proto_item_add_subtree(item, ett_smb_mode);
2045                 proto_tree_add_boolean(tree, hf_smb_sm_mode16, tvb, offset, 2, mask);
2046                 proto_tree_add_boolean(tree, hf_smb_sm_password16, tvb, offset, 2, mask);
2047                 offset += 2;
2048                 break;
2049
2050         case 17:
2051                 mask = tvb_get_guint8(tvb, offset);
2052                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
2053                                 "Security Mode: 0x%02x", mask);
2054                 tree = proto_item_add_subtree(item, ett_smb_mode);
2055                 proto_tree_add_boolean(tree, hf_smb_sm_mode, tvb, offset, 1, mask);
2056                 proto_tree_add_boolean(tree, hf_smb_sm_password, tvb, offset, 1, mask);
2057                 proto_tree_add_boolean(tree, hf_smb_sm_signatures, tvb, offset, 1, mask);
2058                 proto_tree_add_boolean(tree, hf_smb_sm_sig_required, tvb, offset, 1, mask);
2059                 offset += 1;
2060                 break;
2061         }
2062
2063         return offset;
2064 }
2065
2066 static int
2067 dissect_negprot_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2068 {
2069         proto_item *it = NULL;
2070         proto_tree *tr = NULL;
2071         guint16 bc;
2072         guint8 wc;
2073
2074         WORD_COUNT;
2075
2076         BYTE_COUNT;
2077
2078         if(tree){
2079                 it = proto_tree_add_text(tree, tvb, offset, bc,
2080                                 "Requested Dialects");
2081                 tr = proto_item_add_subtree(it, ett_smb_dialects);
2082         }
2083
2084         while(bc){
2085                 int len;
2086                 const guint8 *str;
2087                 proto_item *dit = NULL;
2088                 proto_tree *dtr = NULL;
2089
2090                 /* XXX - what if this runs past bc? */
2091                 len = tvb_strsize(tvb, offset+1);
2092                 str = tvb_get_ptr(tvb, offset+1, len);
2093
2094                 if(tr){
2095                         dit = proto_tree_add_text(tr, tvb, offset, len+1,
2096                                         "Dialect: %s", str);
2097                         dtr = proto_item_add_subtree(dit, ett_smb_dialect);
2098                 }
2099
2100                 /* Buffer Format */
2101                 CHECK_BYTE_COUNT(1);
2102                 proto_tree_add_item(dtr, hf_smb_buffer_format, tvb, offset, 1,
2103                         TRUE);
2104                 COUNT_BYTES(1);
2105
2106                 /*Dialect Name */
2107                 CHECK_BYTE_COUNT(len);
2108                 proto_tree_add_string(dtr, hf_smb_dialect_name, tvb, offset,
2109                         len, str);
2110                 COUNT_BYTES(len);
2111         }
2112
2113         END_OF_SMB
2114
2115         return offset;
2116 }
2117
2118 static int
2119 dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2120 {
2121         smb_info_t *si = pinfo->private_data;
2122         guint8 wc;
2123         guint16 dialect;
2124         const char *dn;
2125         int dn_len;
2126         guint16 bc;
2127         guint16 ekl=0;
2128         guint32 caps=0;
2129         gint16 tz;
2130
2131         WORD_COUNT;
2132
2133         /* Dialect Index */
2134         dialect = tvb_get_letohs(tvb, offset);
2135         switch(wc){
2136         case 1:
2137                 if(dialect==0xffff){
2138                         proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2139                                 tvb, offset, 2, dialect,
2140                                 "Selected Index: -1, PC NETWORK PROGRAM 1.0 choosen");
2141                 } else {
2142                         proto_tree_add_uint(tree, hf_smb_dialect_index,
2143                                 tvb, offset, 2, dialect);
2144                 }
2145                 break;
2146         case 13:
2147                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2148                         tvb, offset, 2, dialect,
2149                         "Dialect Index: %u, Greater than CORE PROTOCOL and up to LANMAN2.1", dialect);
2150                 break;
2151         case 17:
2152                 proto_tree_add_uint_format(tree, hf_smb_dialect_index,
2153                         tvb, offset, 2, dialect,
2154                         "Dialect Index: %u, greater than LANMAN2.1", dialect);
2155                 break;
2156         default:
2157                 proto_tree_add_text(tree, tvb, offset, wc*2,
2158                         "Words for unknown response format");
2159                 offset += wc*2;
2160                 goto bytecount;
2161         }
2162         offset += 2;
2163
2164         switch(wc){
2165         case 13:
2166                 /* Security Mode */
2167                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2168
2169                 /* Maximum Transmit Buffer Size */
2170                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2171                         tvb, offset, 2, TRUE);
2172                 offset += 2;
2173
2174                 /* Maximum Multiplex Count */
2175                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2176                         tvb, offset, 2, TRUE);
2177                 offset += 2;
2178
2179                 /* Maximum Vcs Number */
2180                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2181                         tvb, offset, 2, TRUE);
2182                 offset += 2;
2183
2184                 /* raw mode */
2185                 offset = dissect_negprot_rawmode(tvb, tree, offset);
2186
2187                 /* session key */
2188                 proto_tree_add_item(tree, hf_smb_session_key,
2189                         tvb, offset, 4, TRUE);
2190                 offset += 4;
2191
2192                 /* current time and date at server */
2193                 offset = dissect_smb_datetime(tvb, tree, offset, hf_smb_server_date_time, hf_smb_server_smb_date, hf_smb_server_smb_time,
2194                     TRUE);
2195
2196                 /* time zone */
2197                 tz = tvb_get_letohs(tvb, offset);
2198                 proto_tree_add_int_format(tree, hf_smb_server_timezone, tvb, offset, 2, tz, "Server Time Zone: %d min from UTC", tz);
2199                 offset += 2;
2200
2201                 /* encryption key length */
2202                 ekl = tvb_get_letohs(tvb, offset);
2203                 proto_tree_add_uint(tree, hf_smb_encryption_key_length, tvb, offset, 2, ekl);
2204                 offset += 2;
2205
2206                 /* 2 reserved bytes */
2207                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
2208                 offset += 2;
2209
2210                 break;
2211
2212         case 17:
2213                 /* Security Mode */
2214                 offset = dissect_negprot_security_mode(tvb, tree, offset, wc);
2215
2216                 /* Maximum Multiplex Count */
2217                 proto_tree_add_item(tree, hf_smb_max_mpx_count,
2218                         tvb, offset, 2, TRUE);
2219                 offset += 2;
2220
2221                 /* Maximum Vcs Number */
2222                 proto_tree_add_item(tree, hf_smb_max_vcs_num,
2223                         tvb, offset, 2, TRUE);
2224                 offset += 2;
2225
2226                 /* Maximum Transmit Buffer Size */
2227                 proto_tree_add_item(tree, hf_smb_max_trans_buf_size,
2228                         tvb, offset, 4, TRUE);
2229                 offset += 4;
2230
2231                 /* maximum raw buffer size */
2232                 proto_tree_add_item(tree, hf_smb_max_raw_buf_size,
2233                         tvb, offset, 4, TRUE);
2234                 offset += 4;
2235
2236                 /* session key */
2237                 proto_tree_add_item(tree, hf_smb_session_key,
2238                         tvb, offset, 4, TRUE);
2239                 offset += 4;
2240
2241                 /* server capabilities */
2242                 caps = dissect_negprot_capabilities(tvb, tree, offset);
2243                 offset += 4;
2244
2245                 /* system time */
2246                 offset = dissect_smb_64bit_time(tvb, tree, offset,
2247                                 hf_smb_system_time);
2248
2249                 /* time zone */
2250                 tz = tvb_get_letohs(tvb, offset);
2251                 proto_tree_add_int_format(tree, hf_smb_server_timezone,
2252                         tvb, offset, 2, tz,
2253                         "Server Time Zone: %d min from UTC", tz);
2254                 offset += 2;
2255
2256                 /* encryption key length */
2257                 ekl = tvb_get_guint8(tvb, offset);
2258                 proto_tree_add_uint(tree, hf_smb_encryption_key_length,
2259                         tvb, offset, 1, ekl);
2260                 offset += 1;
2261
2262                 break;
2263         }
2264
2265         BYTE_COUNT;
2266
2267         switch(wc){
2268         case 13:
2269                 /* challenge/response encryption key */
2270                 if(ekl){
2271                         CHECK_BYTE_COUNT(ekl);
2272                         proto_tree_add_item(tree, hf_smb_encryption_key, tvb, offset, ekl, TRUE);
2273                         COUNT_BYTES(ekl);
2274                 }
2275
2276                 /*
2277                  * Primary domain.
2278                  *
2279                  * XXX - not present if negotiated dialect isn't
2280                  * "DOS LANMAN 2.1" or "LANMAN2.1", but we'd either
2281                  * have to see the request, or assume what dialect strings
2282                  * were sent, to determine that.
2283                  *
2284                  * Is this something other than a primary domain if the
2285                  * negotiated dialect is Windows for Workgroups 3.1a?
2286                  * It appears to be 8 bytes of binary data in at least
2287                  * one capture - is that an encryption key or something
2288                  * such as that?
2289                  */
2290                 dn = get_unicode_or_ascii_string(tvb, &offset,
2291                         si->unicode, &dn_len, FALSE, FALSE, &bc);
2292                 if (dn == NULL)
2293                         goto endofcommand;
2294                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
2295                         offset, dn_len,dn);
2296                 COUNT_BYTES(dn_len);
2297                 break;
2298
2299         case 17:
2300                 if(!(caps&SERVER_CAP_EXTENDED_SECURITY)){
2301                         /* challenge/response encryption key */
2302                         /* XXX - is this aligned on an even boundary? */
2303                         if(ekl){
2304                                 CHECK_BYTE_COUNT(ekl);
2305                                 proto_tree_add_item(tree, hf_smb_encryption_key,
2306                                         tvb, offset, ekl, TRUE);
2307                                 COUNT_BYTES(ekl);
2308                         }
2309
2310                         /* domain */
2311                         /* this string is special, unicode is flagged in caps */
2312                         /* This string is NOT padded to be 16bit aligned.
2313                            (seen in actual capture)
2314                            XXX - I've seen a capture where it appears to be
2315                            so aligned, but I've also seen captures where
2316                            it is.  The captures where it appeared to be
2317                            aligned may have been from buggy servers. */
2318                         /* However, don't get rid of existing setting */
2319                         si->unicode = (caps&SERVER_CAP_UNICODE) ||
2320                           si->unicode;
2321
2322                         dn = get_unicode_or_ascii_string(tvb,
2323                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2324                                 &bc);
2325                         if (dn == NULL)
2326                                 goto endofcommand;
2327                         proto_tree_add_string(tree, hf_smb_primary_domain,
2328                                 tvb, offset, dn_len, dn);
2329                         COUNT_BYTES(dn_len);
2330
2331                         /* server name, seen in w2k pro capture */
2332                         dn = get_unicode_or_ascii_string(tvb,
2333                                 &offset, si->unicode, &dn_len, TRUE, FALSE,
2334                                 &bc);
2335                         if (dn == NULL)
2336                                 goto endofcommand;
2337                         proto_tree_add_string(tree, hf_smb_server,
2338                                 tvb, offset, dn_len, dn);
2339                         COUNT_BYTES(dn_len);
2340
2341                 } else {
2342                         proto_item *blob_item;
2343                         guint16 sbloblen;
2344
2345                         /* guid */
2346                         /* XXX - show it in the standard Microsoft format
2347                            for GUIDs? */
2348                         CHECK_BYTE_COUNT(16);
2349                         proto_tree_add_item(tree, hf_smb_server_guid,
2350                                 tvb, offset, 16, TRUE);
2351                         COUNT_BYTES(16);
2352
2353                         /* security blob */
2354                         /* If it runs past the end of the captured data, don't
2355                          * try to put all of it into the protocol tree as the
2356                          * raw security blob; we might get an exception on 
2357                          * short frames and then we will not see anything at all
2358                          * of the security blob.
2359                          */
2360                         sbloblen=bc;
2361                         if(sbloblen>tvb_length_remaining(tvb, offset)){
2362                                 sbloblen=tvb_length_remaining(tvb,offset);
2363                         }
2364                         blob_item = proto_tree_add_item(
2365                                 tree, hf_smb_security_blob,
2366                                 tvb, offset, sbloblen, TRUE);
2367
2368                         /* 
2369                          * If Extended security and BCC == 16, then raw 
2370                          * NTLMSSP is in use. We need to save this info
2371                          */
2372  
2373                         if(bc){
2374                                 tvbuff_t *gssapi_tvb;
2375                                 proto_tree *gssapi_tree;
2376
2377                                 gssapi_tree = proto_item_add_subtree(
2378                                         blob_item, ett_smb_secblob);
2379
2380                                 /*
2381                                  * Set the reported length of this to
2382                                  * the reported length of the blob,
2383                                  * rather than the amount of data
2384                                  * available from the blob, so that
2385                                  * we'll throw the right exception if
2386                                  * it's too short.
2387                                  */
2388                                 gssapi_tvb = tvb_new_subset(
2389                                         tvb, offset, sbloblen, bc);
2390
2391                                 call_dissector(
2392                                         gssapi_handle, gssapi_tvb, pinfo,
2393                                         gssapi_tree);
2394
2395                                 if (si->ct)
2396                                   si->ct->raw_ntlmssp = 0;
2397
2398                                 COUNT_BYTES(bc);
2399                         }
2400                         else { 
2401
2402                           /*
2403                            * There is no blob. We just have to make sure
2404                            * that subsequent routines know to call the 
2405                            * right things ...
2406                            */
2407
2408                           if (si->ct)
2409                             si->ct->raw_ntlmssp = 1;
2410
2411                         }
2412                 }
2413                 break;
2414         }
2415
2416         END_OF_SMB
2417
2418         return offset;
2419 }
2420
2421
2422 static int
2423 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2424 {
2425         smb_info_t *si = pinfo->private_data;
2426         int dn_len;
2427         const char *dn;
2428         guint8 wc;
2429         guint16 bc;
2430
2431         WORD_COUNT;
2432
2433         BYTE_COUNT;
2434
2435         /* buffer format */
2436         CHECK_BYTE_COUNT(1);
2437         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2438         COUNT_BYTES(1);
2439
2440         /* dir name */
2441         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2442                 FALSE, FALSE, &bc);
2443         if (dn == NULL)
2444                 goto endofcommand;
2445         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2446                 dn);
2447         COUNT_BYTES(dn_len);
2448
2449         if (check_col(pinfo->cinfo, COL_INFO)) {
2450                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2451         }
2452
2453         END_OF_SMB
2454
2455         return offset;
2456 }
2457
2458 static int
2459 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2460 {
2461         guint8 wc;
2462         guint16 bc;
2463
2464         WORD_COUNT;
2465
2466         BYTE_COUNT;
2467
2468         END_OF_SMB
2469
2470         return offset;
2471 }
2472
2473 static int
2474 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2475 {
2476         guint16 ec, bc;
2477         guint8 wc;
2478
2479         WORD_COUNT;
2480
2481         /* echo count */
2482         ec = tvb_get_letohs(tvb, offset);
2483         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2484         offset += 2;
2485
2486         BYTE_COUNT;
2487
2488         if (bc != 0) {
2489                 /* echo data */
2490                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2491                 COUNT_BYTES(bc);
2492         }
2493
2494         END_OF_SMB
2495
2496         return offset;
2497 }
2498
2499 static int
2500 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2501 {
2502         guint16 bc;
2503         guint8 wc;
2504
2505         WORD_COUNT;
2506
2507         /* echo sequence number */
2508         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2509         offset += 2;
2510
2511         BYTE_COUNT;
2512
2513         if (bc != 0) {
2514                 /* echo data */
2515                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2516                 COUNT_BYTES(bc);
2517         }
2518
2519         END_OF_SMB
2520
2521         return offset;
2522 }
2523
2524 static int
2525 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2526 {
2527         smb_info_t *si = pinfo->private_data;
2528         int an_len, pwlen;
2529         const char *an;
2530         guint8 wc;
2531         guint16 bc;
2532
2533         WORD_COUNT;
2534
2535         BYTE_COUNT;
2536
2537         /* buffer format */
2538         CHECK_BYTE_COUNT(1);
2539         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2540         COUNT_BYTES(1);
2541
2542         /* Path */
2543         an = get_unicode_or_ascii_string(tvb, &offset,
2544                 si->unicode, &an_len, FALSE, FALSE, &bc);
2545         if (an == NULL)
2546                 goto endofcommand;
2547         proto_tree_add_string(tree, hf_smb_path, tvb,
2548                 offset, an_len, an);
2549         COUNT_BYTES(an_len);
2550
2551         if (check_col(pinfo->cinfo, COL_INFO)) {
2552                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2553         }
2554
2555         /* buffer format */
2556         CHECK_BYTE_COUNT(1);
2557         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2558         COUNT_BYTES(1);
2559
2560         /* password, ANSI */
2561         /* XXX - what if this runs past bc? */
2562         pwlen = tvb_strsize(tvb, offset);
2563         CHECK_BYTE_COUNT(pwlen);
2564         proto_tree_add_item(tree, hf_smb_password,
2565                 tvb, offset, pwlen, TRUE);
2566         COUNT_BYTES(pwlen);
2567
2568         /* buffer format */
2569         CHECK_BYTE_COUNT(1);
2570         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2571         COUNT_BYTES(1);
2572
2573         /* Service */
2574         an = get_unicode_or_ascii_string(tvb, &offset,
2575                 si->unicode, &an_len, FALSE, FALSE, &bc);
2576         if (an == NULL)
2577                 goto endofcommand;
2578         proto_tree_add_string(tree, hf_smb_service, tvb,
2579                 offset, an_len, an);
2580         COUNT_BYTES(an_len);
2581
2582         END_OF_SMB
2583
2584         return offset;
2585 }
2586
2587 static int
2588 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2589 {
2590         guint8 wc;
2591         guint16 bc;
2592
2593         WORD_COUNT;
2594
2595         /* Maximum Buffer Size */
2596         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2597         offset += 2;
2598
2599         /* tid */
2600         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2601         offset += 2;
2602
2603         BYTE_COUNT;
2604
2605         END_OF_SMB
2606
2607         return offset;
2608 }
2609
2610
2611 static const true_false_string tfs_of_create = {
2612         "Create file if it does not exist",
2613         "Fail if file does not exist"
2614 };
2615 static const value_string of_open[] = {
2616         { 0,            "Fail if file exists"},
2617         { 1,            "Open file if it exists"},
2618         { 2,            "Truncate file if it exists"},
2619         {0, NULL}
2620 };
2621 static int
2622 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2623 {
2624         guint16 mask;
2625         proto_item *item = NULL;
2626         proto_tree *tree = NULL;
2627
2628         mask = tvb_get_letohs(tvb, offset);
2629
2630         if(parent_tree){
2631                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2632                         "Open Function: 0x%04x", mask);
2633                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2634         }
2635
2636         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2637                 tvb, offset, 2, mask);
2638         proto_tree_add_uint(tree, hf_smb_open_function_open,
2639                 tvb, offset, 2, mask);
2640
2641         offset += 2;
2642
2643         return offset;
2644 }
2645
2646
2647 static const true_false_string tfs_mf_file = {
2648         "Target must be a file",
2649         "Target needn't be a file"
2650 };
2651 static const true_false_string tfs_mf_dir = {
2652         "Target must be a directory",
2653         "Target needn't be a directory"
2654 };
2655 static const true_false_string tfs_mf_verify = {
2656         "MUST verify all writes",
2657         "Don't have to verify writes"
2658 };
2659 static int
2660 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2661 {
2662         guint16 mask;
2663         proto_item *item = NULL;
2664         proto_tree *tree = NULL;
2665
2666         mask = tvb_get_letohs(tvb, offset);
2667
2668         if(parent_tree){
2669                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2670                         "Flags: 0x%04x", mask);
2671                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2672         }
2673
2674         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2675                 tvb, offset, 2, mask);
2676         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2677                 tvb, offset, 2, mask);
2678         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2679                 tvb, offset, 2, mask);
2680
2681         offset += 2;
2682
2683         return offset;
2684 }
2685
2686 static const true_false_string tfs_cf_mode = {
2687         "ASCII",
2688         "Binary"
2689 };
2690 static const true_false_string tfs_cf_tree_copy = {
2691         "Copy is a tree copy",
2692         "Copy is a file copy"
2693 };
2694 static const true_false_string tfs_cf_ea_action = {
2695         "Fail copy",
2696         "Discard EAs"
2697 };
2698 static int
2699 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2700 {
2701         guint16 mask;
2702         proto_item *item = NULL;
2703         proto_tree *tree = NULL;
2704
2705         mask = tvb_get_letohs(tvb, offset);
2706
2707         if(parent_tree){
2708                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2709                         "Flags: 0x%04x", mask);
2710                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2711         }
2712
2713         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2714                 tvb, offset, 2, mask);
2715         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2716                 tvb, offset, 2, mask);
2717         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2718                 tvb, offset, 2, mask);
2719         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2720                 tvb, offset, 2, mask);
2721         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2722                 tvb, offset, 2, mask);
2723         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2724                 tvb, offset, 2, mask);
2725         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2726                 tvb, offset, 2, mask);
2727
2728         offset += 2;
2729
2730         return offset;
2731 }
2732
2733 static int
2734 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2735 {
2736         smb_info_t *si = pinfo->private_data;
2737         int fn_len;
2738         guint16 tid;
2739         guint16 bc;
2740         guint8 wc;
2741         const char *fn;
2742
2743         WORD_COUNT;
2744
2745         /* tid */
2746         tid = tvb_get_letohs(tvb, offset);
2747         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2748                 "TID (target): 0x%04x", tid);
2749         offset += 2;
2750
2751         /* open function */
2752         offset = dissect_open_function(tvb, tree, offset);
2753
2754         /* move flags */
2755         offset = dissect_move_flags(tvb, tree, offset);
2756
2757         BYTE_COUNT;
2758
2759         /* buffer format */
2760         CHECK_BYTE_COUNT(1);
2761         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2762         COUNT_BYTES(1);
2763
2764         /* file name */
2765         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2766                 FALSE, FALSE, &bc);
2767         if (fn == NULL)
2768                 goto endofcommand;
2769         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2770                 fn_len, fn, "Old File Name: %s", fn);
2771         COUNT_BYTES(fn_len);
2772
2773         if (check_col(pinfo->cinfo, COL_INFO)) {
2774                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2775         }
2776
2777         /* buffer format */
2778         CHECK_BYTE_COUNT(1);
2779         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2780         COUNT_BYTES(1);
2781
2782         /* file name */
2783         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2784                 FALSE, FALSE, &bc);
2785         if (fn == NULL)
2786                 goto endofcommand;
2787         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2788                 fn_len, fn, "New File Name: %s", fn);
2789         COUNT_BYTES(fn_len);
2790
2791         if (check_col(pinfo->cinfo, COL_INFO)) {
2792                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2793         }
2794
2795         END_OF_SMB
2796
2797         return offset;
2798 }
2799
2800 static int
2801 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2802 {
2803         smb_info_t *si = pinfo->private_data;
2804         int fn_len;
2805         guint16 tid;
2806         guint16 bc;
2807         guint8 wc;
2808         const char *fn;
2809
2810         WORD_COUNT;
2811
2812         /* tid */
2813         tid = tvb_get_letohs(tvb, offset);
2814         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2815                 "TID (target): 0x%04x", tid);
2816         offset += 2;
2817
2818         /* open function */
2819         offset = dissect_open_function(tvb, tree, offset);
2820
2821         /* copy flags */
2822         offset = dissect_copy_flags(tvb, tree, offset);
2823
2824         BYTE_COUNT;
2825
2826         /* buffer format */
2827         CHECK_BYTE_COUNT(1);
2828         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2829         COUNT_BYTES(1);
2830
2831         /* file name */
2832         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2833                 FALSE, FALSE, &bc);
2834         if (fn == NULL)
2835                 goto endofcommand;
2836         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2837                 fn_len, fn, "Source File Name: %s", fn);
2838         COUNT_BYTES(fn_len);
2839
2840         if (check_col(pinfo->cinfo, COL_INFO)) {
2841                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2842         }
2843
2844         /* buffer format */
2845         CHECK_BYTE_COUNT(1);
2846         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2847         COUNT_BYTES(1);
2848
2849         /* file name */
2850         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2851                 FALSE, FALSE, &bc);
2852         if (fn == NULL)
2853                 goto endofcommand;
2854         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2855                 fn_len, fn, "Destination File Name: %s", fn);
2856         COUNT_BYTES(fn_len);
2857
2858         if (check_col(pinfo->cinfo, COL_INFO)) {
2859                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2860         }
2861
2862         END_OF_SMB
2863
2864         return offset;
2865 }
2866
2867 static int
2868 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2869 {
2870         smb_info_t *si = pinfo->private_data;
2871         int fn_len;
2872         const char *fn;
2873         guint8 wc;
2874         guint16 bc;
2875
2876         WORD_COUNT;
2877
2878         /* # of files moved */
2879         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2880         offset += 2;
2881
2882         BYTE_COUNT;
2883
2884         /* buffer format */
2885         CHECK_BYTE_COUNT(1);
2886         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2887         COUNT_BYTES(1);
2888
2889         /* file name */
2890         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2891                 FALSE, FALSE, &bc);
2892         if (fn == NULL)
2893                 goto endofcommand;
2894         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2895                 fn);
2896         COUNT_BYTES(fn_len);
2897
2898         END_OF_SMB
2899
2900         return offset;
2901 }
2902
2903 static int
2904 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2905 {
2906         smb_info_t *si = pinfo->private_data;
2907         int fn_len;
2908         const char *fn;
2909         guint8 wc;
2910         guint16 bc;
2911
2912         WORD_COUNT;
2913
2914         /* desired access */
2915         offset = dissect_access(tvb, tree, offset, "Desired");
2916
2917         /* Search Attributes */
2918         offset = dissect_search_attributes(tvb, tree, offset);
2919
2920         BYTE_COUNT;
2921
2922         /* buffer format */
2923         CHECK_BYTE_COUNT(1);
2924         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2925         COUNT_BYTES(1);
2926
2927         /* file name */
2928         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2929                 FALSE, FALSE, &bc);
2930         if (fn == NULL)
2931                 goto endofcommand;
2932         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2933                 fn);
2934         COUNT_BYTES(fn_len);
2935
2936         if (check_col(pinfo->cinfo, COL_INFO)) {
2937                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2938         }
2939
2940         END_OF_SMB
2941
2942         return offset;
2943 }
2944
2945 void
2946 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2947     int len, guint16 fid)
2948 {
2949         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2950         if (check_col(pinfo->cinfo, COL_INFO))
2951                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2952 }
2953
2954 static int
2955 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2956 {
2957         guint8 wc;
2958         guint16 bc;
2959         guint16 fid;
2960
2961         WORD_COUNT;
2962
2963         /* fid */
2964         fid = tvb_get_letohs(tvb, offset);
2965         add_fid(tvb, pinfo, tree, offset, 2, fid);
2966         offset += 2;
2967
2968         /* File Attributes */
2969         offset = dissect_file_attributes(tvb, tree, offset, 2);
2970
2971         /* last write time */
2972         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2973
2974         /* File Size */
2975         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2976         offset += 4;
2977
2978         /* granted access */
2979         offset = dissect_access(tvb, tree, offset, "Granted");
2980
2981         BYTE_COUNT;
2982
2983         END_OF_SMB
2984
2985         return offset;
2986 }
2987
2988 static int
2989 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2990 {
2991         guint8 wc;
2992         guint16 bc;
2993         guint16 fid;
2994
2995         WORD_COUNT;
2996
2997         /* fid */
2998         fid = tvb_get_letohs(tvb, offset);
2999         add_fid(tvb, pinfo, tree, offset, 2, fid);
3000         offset += 2;
3001
3002         BYTE_COUNT;
3003
3004         END_OF_SMB
3005
3006         return offset;
3007 }
3008
3009 static int
3010 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3011 {
3012         smb_info_t *si = pinfo->private_data;
3013         int fn_len;
3014         const char *fn;
3015         guint8 wc;
3016         guint16 bc;
3017
3018         WORD_COUNT;
3019
3020         /* file attributes */
3021         offset = dissect_file_attributes(tvb, tree, offset, 2);
3022
3023         /* creation time */
3024         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3025
3026         BYTE_COUNT;
3027
3028         /* buffer format */
3029         CHECK_BYTE_COUNT(1);
3030         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3031         COUNT_BYTES(1);
3032
3033         /* File Name */
3034         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3035                 FALSE, FALSE, &bc);
3036         if (fn == NULL)
3037                 goto endofcommand;
3038         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3039                 fn);
3040         COUNT_BYTES(fn_len);
3041
3042         if (check_col(pinfo->cinfo, COL_INFO)) {
3043                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3044         }
3045
3046         END_OF_SMB
3047
3048         return offset;
3049 }
3050
3051 static int
3052 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3053 {
3054         guint8 wc;
3055         guint16 bc, fid;
3056
3057         WORD_COUNT;
3058
3059         /* fid */
3060         fid = tvb_get_letohs(tvb, offset);
3061         add_fid(tvb, pinfo, tree, offset, 2, fid);
3062         offset += 2;
3063
3064         /* last write time */
3065         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3066
3067         BYTE_COUNT;
3068
3069         END_OF_SMB
3070
3071         return offset;
3072 }
3073
3074 static int
3075 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3076 {
3077         smb_info_t *si = pinfo->private_data;
3078         int fn_len;
3079         const char *fn;
3080         guint8 wc;
3081         guint16 bc;
3082
3083         WORD_COUNT;
3084
3085         /* search attributes */
3086         offset = dissect_search_attributes(tvb, tree, offset);
3087
3088         BYTE_COUNT;
3089
3090         /* buffer format */
3091         CHECK_BYTE_COUNT(1);
3092         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3093         COUNT_BYTES(1);
3094
3095         /* file name */
3096         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3097                 FALSE, FALSE, &bc);
3098         if (fn == NULL)
3099                 goto endofcommand;
3100         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3101                 fn);
3102         COUNT_BYTES(fn_len);
3103
3104         if (check_col(pinfo->cinfo, COL_INFO)) {
3105                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3106         }
3107
3108         END_OF_SMB
3109
3110         return offset;
3111 }
3112
3113 static int
3114 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3115 {
3116         smb_info_t *si = pinfo->private_data;
3117         int fn_len;
3118         const char *fn;
3119         guint8 wc;
3120         guint16 bc;
3121
3122         WORD_COUNT;
3123
3124         /* search attributes */
3125         offset = dissect_search_attributes(tvb, tree, offset);
3126
3127         BYTE_COUNT;
3128
3129         /* buffer format */
3130         CHECK_BYTE_COUNT(1);
3131         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3132         COUNT_BYTES(1);
3133
3134         /* old file name */
3135         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3136                 FALSE, FALSE, &bc);
3137         if (fn == NULL)
3138                 goto endofcommand;
3139         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3140                 fn);
3141         COUNT_BYTES(fn_len);
3142
3143         if (check_col(pinfo->cinfo, COL_INFO)) {
3144                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3145         }
3146
3147         /* buffer format */
3148         CHECK_BYTE_COUNT(1);
3149         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3150         COUNT_BYTES(1);
3151
3152         /* file name */
3153         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3154                 FALSE, FALSE, &bc);
3155         if (fn == NULL)
3156                 goto endofcommand;
3157         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3158                 fn);
3159         COUNT_BYTES(fn_len);
3160
3161         if (check_col(pinfo->cinfo, COL_INFO)) {
3162                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3163         }
3164
3165         END_OF_SMB
3166
3167         return offset;
3168 }
3169
3170 static int
3171 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3172 {
3173         smb_info_t *si = pinfo->private_data;
3174         int fn_len;
3175         const char *fn;
3176         guint8 wc;
3177         guint16 bc;
3178
3179         WORD_COUNT;
3180
3181         /* search attributes */
3182         offset = dissect_search_attributes(tvb, tree, offset);
3183
3184         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3185         offset += 2;
3186
3187         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3188         offset += 4;
3189
3190         BYTE_COUNT;
3191
3192         /* buffer format */
3193         CHECK_BYTE_COUNT(1);
3194         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3195         COUNT_BYTES(1);
3196
3197         /* old file name */
3198         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3199                 FALSE, FALSE, &bc);
3200         if (fn == NULL)
3201                 goto endofcommand;
3202         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3203                 fn);
3204         COUNT_BYTES(fn_len);
3205
3206         if (check_col(pinfo->cinfo, COL_INFO)) {
3207                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3208         }
3209
3210         /* buffer format */
3211         CHECK_BYTE_COUNT(1);
3212         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3213         COUNT_BYTES(1);
3214
3215         /* file name */
3216         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3217                 FALSE, FALSE, &bc);
3218         if (fn == NULL)
3219                 goto endofcommand;
3220         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3221                 fn);
3222         COUNT_BYTES(fn_len);
3223
3224         if (check_col(pinfo->cinfo, COL_INFO)) {
3225                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3226         }
3227
3228         END_OF_SMB
3229
3230         return offset;
3231 }
3232
3233
3234 static int
3235 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3236 {
3237         smb_info_t *si = pinfo->private_data;
3238         guint16 bc;
3239         guint8 wc;
3240         const char *fn;
3241         int fn_len;
3242
3243         WORD_COUNT;
3244
3245         BYTE_COUNT;
3246
3247         /* Buffer Format */
3248         CHECK_BYTE_COUNT(1);
3249         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3250         COUNT_BYTES(1);
3251
3252         /* File Name */
3253         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3254                 FALSE, FALSE, &bc);
3255         if (fn == NULL)
3256                 goto endofcommand;
3257         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3258                 fn);
3259         COUNT_BYTES(fn_len);
3260
3261         if (check_col(pinfo->cinfo, COL_INFO)) {
3262                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3263         }
3264
3265         END_OF_SMB
3266
3267         return offset;
3268 }
3269
3270 static int
3271 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3272 {
3273         guint16 bc;
3274         guint8 wc;
3275
3276         WORD_COUNT;
3277
3278         /* File Attributes */
3279         offset = dissect_file_attributes(tvb, tree, offset, 2);
3280
3281         /* Last Write Time */
3282         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3283
3284         /* File Size */
3285         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3286         offset += 4;
3287
3288         /* 10 reserved bytes */
3289         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3290         offset += 10;
3291
3292         BYTE_COUNT;
3293
3294         END_OF_SMB
3295
3296         return offset;
3297 }
3298
3299 static int
3300 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3301 {
3302         smb_info_t *si = pinfo->private_data;
3303         int fn_len;
3304         const char *fn;
3305         guint8 wc;
3306         guint16 bc;
3307
3308         WORD_COUNT;
3309
3310         /* file attributes */
3311         offset = dissect_file_attributes(tvb, tree, offset, 2);
3312
3313         /* last write time */
3314         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3315
3316         /* 10 reserved bytes */
3317         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3318         offset += 10;
3319
3320         BYTE_COUNT;
3321
3322         /* buffer format */
3323         CHECK_BYTE_COUNT(1);
3324         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3325         COUNT_BYTES(1);
3326
3327         /* file name */
3328         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3329                 FALSE, FALSE, &bc);
3330         if (fn == NULL)
3331                 goto endofcommand;
3332         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3333                 fn);
3334         COUNT_BYTES(fn_len);
3335
3336         if (check_col(pinfo->cinfo, COL_INFO)) {
3337                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3338         }
3339
3340         END_OF_SMB
3341
3342         return offset;
3343 }
3344
3345 static int
3346 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3347 {
3348         guint8 wc;
3349         guint16 cnt=0, bc;
3350         guint32 ofs=0;
3351         smb_info_t *si;
3352         unsigned int fid;
3353
3354         WORD_COUNT;
3355
3356         /* fid */
3357         fid = tvb_get_letohs(tvb, offset);
3358         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
3359         offset += 2;
3360         if (!pinfo->fd->flags.visited) {
3361                 /* remember the FID for the processing of the response */
3362                 si = (smb_info_t *)pinfo->private_data;
3363                 si->sip->extra_info=(void *)fid;
3364         }
3365
3366         /* read count */
3367         cnt = tvb_get_letohs(tvb, offset);
3368         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3369         offset += 2;
3370
3371         /* offset */
3372         ofs = tvb_get_letohl(tvb, offset);
3373         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3374         offset += 4;
3375
3376         if (check_col(pinfo->cinfo, COL_INFO))
3377                 col_append_fstr(pinfo->cinfo, COL_INFO,
3378                                 ", %u byte%s at offset %u", cnt,
3379                                 (cnt == 1) ? "" : "s", ofs);
3380
3381         /* remaining */
3382         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3383         offset += 2;
3384
3385         BYTE_COUNT;
3386
3387         END_OF_SMB
3388
3389         return offset;
3390 }
3391
3392 int
3393 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3394 {
3395         int tvblen;
3396
3397         if(bc>datalen){
3398                 /* We have some initial padding bytes. */
3399                 /* XXX - use the data offset here instead? */
3400                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3401                         TRUE);
3402                 offset += bc-datalen;
3403                 bc = datalen;
3404         }
3405         tvblen = tvb_length_remaining(tvb, offset);
3406         if(bc>tvblen){
3407                 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);
3408                 offset += tvblen;
3409         } else {
3410                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3411                 offset += bc;
3412         }
3413         return offset;
3414 }
3415
3416 static int
3417 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3418     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3419 {
3420         int tvblen;
3421         tvbuff_t *dcerpc_tvb;
3422
3423         if(bc>datalen){
3424                 /* We have some initial padding bytes. */
3425                 /* XXX - use the data offset here instead? */
3426                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3427                         TRUE);
3428                 offset += bc-datalen;
3429                 bc = datalen;
3430         }
3431         tvblen = tvb_length_remaining(tvb, offset);
3432         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3433         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3434         if(bc>tvblen)
3435                 offset += tvblen;
3436         else
3437                 offset += bc;
3438         return offset;
3439 }
3440
3441 /*
3442  * transporting DCERPC over SMB seems to be implemented in various
3443  * ways. We might just assume it can be done by an almost random
3444  * mix of Trans/Read/Write calls
3445  *
3446  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3447  * and let him sort them out
3448  */
3449 static int
3450 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3451     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3452     guint16 datalen, guint32 ofs, guint16 fid)
3453 {
3454         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3455
3456         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3457                 /* dcerpc call */
3458                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3459                     top_tree, offset, bc, datalen, fid);
3460         } else {
3461                 /* ordinary file data */
3462                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3463         }
3464 }
3465
3466 static int
3467 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3468 {
3469         guint16 cnt=0, bc;
3470         guint8 wc;
3471         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3472         int fid=0;
3473
3474         WORD_COUNT;
3475
3476         /* read count */
3477         cnt = tvb_get_letohs(tvb, offset);
3478         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3479         offset += 2;
3480
3481         /* 8 reserved bytes */
3482         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3483         offset += 8;
3484
3485         /* If we have seen the request, then print which FID this refers to */
3486         /* first check if we have seen the request */
3487         if(si->sip != NULL && si->sip->frame_req>0){
3488                 fid=(int)si->sip->extra_info;
3489                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) fid);
3490         }
3491
3492         BYTE_COUNT;
3493
3494         /* buffer format */
3495         CHECK_BYTE_COUNT(1);
3496         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3497         COUNT_BYTES(1);
3498
3499         /* data len */
3500         CHECK_BYTE_COUNT(2);
3501         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3502         COUNT_BYTES(2);
3503
3504         /* file data, might be DCERPC on a pipe */
3505         if(bc){
3506                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3507                     top_tree, offset, bc, bc, 0, (guint16) fid);
3508                 bc = 0;
3509         }
3510
3511         END_OF_SMB
3512
3513         return offset;
3514 }
3515
3516 static int
3517 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3518 {
3519         guint16 cnt, bc;
3520         guint8 wc;
3521
3522         WORD_COUNT;
3523
3524         /* read count */
3525         cnt = tvb_get_letohs(tvb, offset);
3526         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3527         offset += 2;
3528
3529         /* 8 reserved bytes */
3530         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3531         offset += 8;
3532
3533         BYTE_COUNT;
3534
3535         /* buffer format */
3536         CHECK_BYTE_COUNT(1);
3537         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3538         COUNT_BYTES(1);
3539
3540         /* data len */
3541         CHECK_BYTE_COUNT(2);
3542         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3543         COUNT_BYTES(2);
3544
3545         END_OF_SMB
3546
3547         return offset;
3548 }
3549
3550
3551 static int
3552 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3553 {
3554         guint32 ofs=0;
3555         guint16 cnt=0, bc, fid=0;
3556         guint8 wc;
3557
3558         WORD_COUNT;
3559
3560         /* fid */
3561         fid = tvb_get_letohs(tvb, offset);
3562         add_fid(tvb, pinfo, tree, offset, 2, fid);
3563         offset += 2;
3564
3565         /* write count */
3566         cnt = tvb_get_letohs(tvb, offset);
3567         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3568         offset += 2;
3569
3570         /* offset */
3571         ofs = tvb_get_letohl(tvb, offset);
3572         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3573         offset += 4;
3574
3575         if (check_col(pinfo->cinfo, COL_INFO))
3576                 col_append_fstr(pinfo->cinfo, COL_INFO,
3577                                 ", %u byte%s at offset %u", cnt,
3578                                 (cnt == 1) ? "" : "s", ofs);
3579
3580         /* remaining */
3581         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3582         offset += 2;
3583
3584         BYTE_COUNT;
3585
3586         /* buffer format */
3587         CHECK_BYTE_COUNT(1);
3588         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3589         COUNT_BYTES(1);
3590
3591         /* data len */
3592         CHECK_BYTE_COUNT(2);
3593         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3594         COUNT_BYTES(2);
3595
3596         /* file data, might be DCERPC on a pipe */
3597         if (bc != 0) {
3598                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3599                     top_tree, offset, bc, bc, ofs, fid);
3600                 bc = 0;
3601         }
3602
3603         END_OF_SMB
3604
3605         return offset;
3606 }
3607
3608 static int
3609 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3610 {
3611         guint8 wc;
3612         guint16 bc, cnt;
3613
3614         WORD_COUNT;
3615
3616         /* write count */
3617         cnt = tvb_get_letohs(tvb, offset);
3618         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3619         offset += 2;
3620
3621         if (check_col(pinfo->cinfo, COL_INFO))
3622                 col_append_fstr(pinfo->cinfo, COL_INFO,
3623                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3624
3625         BYTE_COUNT;
3626
3627         END_OF_SMB
3628
3629         return offset;
3630 }
3631
3632 static int
3633 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3634 {
3635         guint8 wc;
3636         guint16 bc, fid;
3637
3638         WORD_COUNT;
3639
3640         /* fid */
3641         fid = tvb_get_letohs(tvb, offset);
3642         add_fid(tvb, pinfo, tree, offset, 2, fid);
3643         offset += 2;
3644
3645         /* lock count */
3646         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3647         offset += 4;
3648
3649         /* offset */
3650         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3651         offset += 4;
3652
3653         BYTE_COUNT;
3654
3655         END_OF_SMB
3656
3657         return offset;
3658 }
3659
3660 static int
3661 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3662 {
3663         smb_info_t *si = pinfo->private_data;
3664         int fn_len;
3665         const char *fn;
3666         guint8 wc;
3667         guint16 bc;
3668
3669         WORD_COUNT;
3670
3671         /* 2 reserved bytes */
3672         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3673         offset += 2;
3674
3675         /* Creation time */
3676         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3677
3678         BYTE_COUNT;
3679
3680         /* buffer format */
3681         CHECK_BYTE_COUNT(1);
3682         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3683         COUNT_BYTES(1);
3684
3685         /* directory name */
3686         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3687                 FALSE, FALSE, &bc);
3688         if (fn == NULL)
3689                 goto endofcommand;
3690         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3691                 fn);
3692         COUNT_BYTES(fn_len);
3693
3694         if (check_col(pinfo->cinfo, COL_INFO)) {
3695                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3696         }
3697
3698         END_OF_SMB
3699
3700         return offset;
3701 }
3702
3703 static int
3704 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3705 {
3706         smb_info_t *si = pinfo->private_data;
3707         int fn_len;
3708         const char *fn;
3709         guint8 wc;
3710         guint16 bc, fid;
3711
3712         WORD_COUNT;
3713
3714         /* fid */
3715         fid = tvb_get_letohs(tvb, offset);
3716         add_fid(tvb, pinfo, tree, offset, 2, fid);
3717         offset += 2;
3718
3719         BYTE_COUNT;
3720
3721         /* buffer format */
3722         CHECK_BYTE_COUNT(1);
3723         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3724         COUNT_BYTES(1);
3725
3726         /* file name */
3727         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3728                 FALSE, FALSE, &bc);
3729         if (fn == NULL)
3730                 goto endofcommand;
3731         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3732                 fn);
3733         COUNT_BYTES(fn_len);
3734
3735         END_OF_SMB
3736
3737         return offset;
3738 }
3739
3740 static const value_string seek_mode_vals[] = {
3741         {0,     "From Start Of File"},
3742         {1,     "From Current Position"},
3743         {2,     "From End Of File"},
3744         {0,     NULL}
3745 };
3746
3747 static int
3748 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3749 {
3750         guint8 wc;
3751         guint16 bc, fid;
3752
3753         WORD_COUNT;
3754
3755         /* fid */
3756         fid = tvb_get_letohs(tvb, offset);
3757         add_fid(tvb, pinfo, tree, offset, 2, fid);
3758         offset += 2;
3759
3760         /* Seek Mode */
3761         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3762         offset += 2;
3763
3764         /* offset */
3765         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3766         offset += 4;
3767
3768         BYTE_COUNT;
3769
3770         END_OF_SMB
3771
3772         return offset;
3773 }
3774
3775 static int
3776 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3777 {
3778         guint8 wc;
3779         guint16 bc;
3780
3781         WORD_COUNT;
3782
3783         /* offset */
3784         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3785         offset += 4;
3786
3787         BYTE_COUNT;
3788
3789         END_OF_SMB
3790
3791         return offset;
3792 }
3793
3794 static int
3795 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3796 {
3797         guint8 wc;
3798         guint16 bc, fid;
3799
3800         WORD_COUNT;
3801
3802         /* fid */
3803         fid = tvb_get_letohs(tvb, offset);
3804         add_fid(tvb, pinfo, tree, offset, 2, fid);
3805         offset += 2;
3806
3807         /* create time */
3808         offset = dissect_smb_datetime(tvb, tree, offset,
3809                 hf_smb_create_time,
3810                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3811
3812         /* access time */
3813         offset = dissect_smb_datetime(tvb, tree, offset,
3814                 hf_smb_access_time,
3815                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3816
3817         /* last write time */
3818         offset = dissect_smb_datetime(tvb, tree, offset,
3819                 hf_smb_last_write_time,
3820                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3821
3822         BYTE_COUNT;
3823
3824         END_OF_SMB
3825
3826         return offset;
3827 }
3828
3829 static int
3830 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3831 {
3832         guint8 wc;
3833         guint16 bc;
3834
3835         WORD_COUNT;
3836
3837         /* create time */
3838         offset = dissect_smb_datetime(tvb, tree, offset,
3839                 hf_smb_create_time,
3840                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3841
3842         /* access time */
3843         offset = dissect_smb_datetime(tvb, tree, offset,
3844                 hf_smb_access_time,
3845                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3846
3847         /* last write time */
3848         offset = dissect_smb_datetime(tvb, tree, offset,
3849                 hf_smb_last_write_time,
3850                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3851
3852         /* data size */
3853         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3854         offset += 4;
3855
3856         /* allocation size */
3857         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3858         offset += 4;
3859
3860         /* File Attributes */
3861         offset = dissect_file_attributes(tvb, tree, offset, 2);
3862
3863         BYTE_COUNT;
3864
3865         END_OF_SMB
3866
3867         return offset;
3868 }
3869
3870 static int
3871 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3872 {
3873         guint8 wc;
3874         guint16 cnt=0;
3875         guint16 bc, fid;
3876
3877         WORD_COUNT;
3878
3879         /* fid */
3880         fid = tvb_get_letohs(tvb, offset);
3881         add_fid(tvb, pinfo, tree, offset, 2, fid);
3882         offset += 2;
3883
3884         /* write count */
3885         cnt = tvb_get_letohs(tvb, offset);
3886         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3887         offset += 2;
3888
3889         /* offset */
3890         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3891         offset += 4;
3892
3893         /* last write time */
3894         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3895
3896         if(wc==12){
3897                 /* 12 reserved bytes */
3898                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3899                 offset += 12;
3900         }
3901
3902         BYTE_COUNT;
3903
3904         /* 1 pad byte */
3905         CHECK_BYTE_COUNT(1);
3906         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3907         COUNT_BYTES(1);
3908
3909         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3910         bc = 0; /* XXX */
3911
3912         END_OF_SMB
3913
3914         return offset;
3915 }
3916
3917 static int
3918 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3919 {
3920         guint8 wc;
3921         guint16 bc;
3922
3923         WORD_COUNT;
3924
3925         /* write count */
3926         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3927         offset += 2;
3928
3929         BYTE_COUNT;
3930
3931         END_OF_SMB
3932
3933         return offset;
3934 }
3935
3936 static int
3937 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3938 {
3939         guint8 wc;
3940         guint16 bc, fid;
3941         guint32 to;
3942
3943         WORD_COUNT;
3944
3945         /* fid */
3946         fid = tvb_get_letohs(tvb, offset);
3947         add_fid(tvb, pinfo, tree, offset, 2, fid);
3948         offset += 2;
3949
3950         /* offset */
3951         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3952         offset += 4;
3953
3954         /* max count */
3955         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3956         offset += 2;
3957
3958         /* min count */
3959         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3960         offset += 2;
3961
3962         /* timeout */
3963         to = tvb_get_letohl(tvb, offset);
3964         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3965         offset += 4;
3966
3967         /* 2 reserved bytes */
3968         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3969         offset += 2;
3970
3971         if(wc==10){
3972                 /* high offset */
3973                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3974                 offset += 4;
3975         }
3976
3977         BYTE_COUNT;
3978
3979         END_OF_SMB
3980
3981         return offset;
3982 }
3983
3984 static int
3985 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3986 {
3987         guint8 wc;
3988         guint16 bc;
3989
3990         WORD_COUNT;
3991
3992         /* units */
3993         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3994         offset += 2;
3995
3996         /* bpu */
3997         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3998         offset += 2;
3999
4000         /* block size */
4001         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
4002         offset += 2;
4003
4004         /* free units */
4005         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
4006         offset += 2;
4007
4008         /* 2 reserved bytes */
4009         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4010         offset += 2;
4011
4012         BYTE_COUNT;
4013
4014         END_OF_SMB
4015
4016         return offset;
4017 }
4018
4019 static int
4020 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4021 {
4022         guint8 wc;
4023         guint16 bc, fid;
4024
4025         WORD_COUNT;
4026
4027         /* fid */
4028         fid = tvb_get_letohs(tvb, offset);
4029         add_fid(tvb, pinfo, tree, offset, 2, fid);
4030         offset += 2;
4031
4032         /* offset */
4033         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4034         offset += 4;
4035
4036         /* max count */
4037         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4038         offset += 2;
4039
4040         /* min count */
4041         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4042         offset += 2;
4043
4044         /* 6 reserved bytes */
4045         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4046         offset += 6;
4047
4048         BYTE_COUNT;
4049
4050         END_OF_SMB
4051
4052         return offset;
4053 }
4054
4055 static int
4056 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4057 {
4058         guint16 datalen=0, bc;
4059         guint8 wc;
4060
4061         WORD_COUNT;
4062
4063         /* offset */
4064         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4065         offset += 4;
4066
4067         /* count */
4068         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4069         offset += 2;
4070
4071         /* 2 reserved bytes */
4072         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4073         offset += 2;
4074
4075         /* data compaction mode */
4076         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4077         offset += 2;
4078
4079         /* 2 reserved bytes */
4080         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4081         offset += 2;
4082
4083         /* data len */
4084         datalen = tvb_get_letohs(tvb, offset);
4085         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4086         offset += 2;
4087
4088         /* data offset */
4089         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4090         offset += 2;
4091
4092         BYTE_COUNT;
4093
4094         /* file data */
4095         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4096         bc = 0;
4097
4098         END_OF_SMB
4099
4100         return offset;
4101 }
4102
4103
4104 static const true_false_string tfs_write_mode_write_through = {
4105         "WRITE THROUGH requested",
4106         "Write through not requested"
4107 };
4108 static const true_false_string tfs_write_mode_return_remaining = {
4109         "RETURN REMAINING (pipe/dev) requested",
4110         "DON'T return remaining (pipe/dev)"
4111 };
4112 static const true_false_string tfs_write_mode_raw = {
4113         "Use WriteRawNamedPipe (pipe)",
4114         "DON'T use WriteRawNamedPipe (pipe)"
4115 };
4116 static const true_false_string tfs_write_mode_message_start = {
4117         "This is the START of a MESSAGE (pipe)",
4118         "This is NOT the start of a message (pipe)"
4119 };
4120 static const true_false_string tfs_write_mode_connectionless = {
4121         "CONNECTIONLESS mode requested",
4122         "Connectionless mode NOT requested"
4123 };
4124
4125 #define WRITE_MODE_CONNECTIONLESS       0x0080
4126 #define WRITE_MODE_MESSAGE_START        0x0008
4127 #define WRITE_MODE_RAW                  0x0004
4128 #define WRITE_MODE_RETURN_REMAINING     0x0002
4129 #define WRITE_MODE_WRITE_THROUGH        0x0001
4130
4131 static int
4132 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4133 {
4134         guint16 mask;
4135         proto_item *item = NULL;
4136         proto_tree *tree = NULL;
4137
4138         mask = tvb_get_letohs(tvb, offset);
4139
4140         if(parent_tree){
4141                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4142                         "Write Mode: 0x%04x", mask);
4143                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4144         }
4145
4146         if(bm&WRITE_MODE_CONNECTIONLESS){
4147                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4148                         tvb, offset, 2, mask);
4149         }
4150         if(bm&WRITE_MODE_MESSAGE_START){
4151                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4152                         tvb, offset, 2, mask);
4153         }
4154         if(bm&WRITE_MODE_RAW){
4155                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4156                         tvb, offset, 2, mask);
4157         }
4158         if(bm&WRITE_MODE_RETURN_REMAINING){
4159                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4160                         tvb, offset, 2, mask);
4161         }
4162         if(bm&WRITE_MODE_WRITE_THROUGH){
4163                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4164                         tvb, offset, 2, mask);
4165         }
4166
4167         offset += 2;
4168         return offset;
4169 }
4170
4171 static int
4172 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4173 {
4174         guint32 to;
4175         guint16 datalen=0, bc, fid;
4176         guint8 wc;
4177
4178         WORD_COUNT;
4179
4180         /* fid */
4181         fid = tvb_get_letohs(tvb, offset);
4182         add_fid(tvb, pinfo, tree, offset, 2, fid);
4183         offset += 2;
4184
4185         /* total data length */
4186         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4187         offset += 2;
4188
4189         /* 2 reserved bytes */
4190         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4191         offset += 2;
4192
4193         /* offset */
4194         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4195         offset += 4;
4196
4197         /* timeout */
4198         to = tvb_get_letohl(tvb, offset);
4199         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4200         offset += 4;
4201
4202         /* mode */
4203         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4204
4205         /* 4 reserved bytes */
4206         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4207         offset += 4;
4208
4209         /* data len */
4210         datalen = tvb_get_letohs(tvb, offset);
4211         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4212         offset += 2;
4213
4214         /* data offset */
4215         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4216         offset += 2;
4217
4218         BYTE_COUNT;
4219
4220         /* file data */
4221         /* XXX - use the data offset to determine where the data starts? */
4222         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4223         bc = 0;
4224
4225         END_OF_SMB
4226
4227         return offset;
4228 }
4229
4230 static int
4231 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4232 {
4233         guint8 wc;
4234         guint16 bc;
4235
4236         WORD_COUNT;
4237
4238         /* remaining */
4239         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4240         offset += 2;
4241
4242         BYTE_COUNT;
4243
4244         END_OF_SMB
4245
4246         return offset;
4247 }
4248
4249 static int
4250 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4251 {
4252         guint32 to;
4253         guint16 datalen=0, bc, fid;
4254         guint8 wc;
4255
4256         WORD_COUNT;
4257
4258         /* fid */
4259         fid = tvb_get_letohs(tvb, offset);
4260         add_fid(tvb, pinfo, tree, offset, 2, fid);
4261         offset += 2;
4262
4263         /* total data length */
4264         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4265         offset += 2;
4266
4267         /* 2 reserved bytes */
4268         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4269         offset += 2;
4270
4271         /* offset */
4272         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4273         offset += 4;
4274
4275         /* timeout */
4276         to = tvb_get_letohl(tvb, offset);
4277         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4278         offset += 4;
4279
4280         /* mode */
4281         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4282
4283         /* request mask */
4284         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4285         offset += 4;
4286
4287         /* data len */
4288         datalen = tvb_get_letohs(tvb, offset);
4289         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4290         offset += 2;
4291
4292         /* data offset */
4293         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4294         offset += 2;
4295
4296         BYTE_COUNT;
4297
4298         /* file data */
4299         /* XXX - use the data offset to determine where the data starts? */
4300         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4301         bc = 0;
4302
4303         END_OF_SMB
4304
4305         return offset;
4306 }
4307
4308 static int
4309 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4310 {
4311         guint8 wc;
4312         guint16 bc;
4313
4314         WORD_COUNT;
4315
4316         /* response mask */
4317         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4318         offset += 4;
4319
4320         BYTE_COUNT;
4321
4322         END_OF_SMB
4323
4324         return offset;
4325 }
4326
4327 static int
4328 dissect_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4329 {
4330         guint8 wc;
4331         guint16 bc;
4332
4333         WORD_COUNT;
4334
4335         /* sid */
4336         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4337         offset += 2;
4338
4339         BYTE_COUNT;
4340
4341         END_OF_SMB
4342
4343         return offset;
4344 }
4345
4346 static int
4347 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4348     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4349     gboolean has_find_id)
4350 {
4351         proto_item *item = NULL;
4352         proto_tree *tree = NULL;
4353         smb_info_t *si = pinfo->private_data;
4354         int fn_len;
4355         const char *fn;
4356         char fname[11+1];
4357
4358         if(parent_tree){
4359                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4360                         "Resume Key");
4361                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4362         }
4363
4364         /* reserved byte */
4365         CHECK_BYTE_COUNT_SUBR(1);
4366         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4367         COUNT_BYTES_SUBR(1);
4368
4369         /* file name */
4370         fn_len = 11;
4371         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4372                 TRUE, TRUE, bcp);
4373         CHECK_STRING_SUBR(fn);
4374         /* ensure that it's null-terminated */
4375         strncpy(fname, fn, 11);
4376         fname[11] = '\0';
4377         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4378                 fname);
4379         COUNT_BYTES_SUBR(fn_len);
4380
4381         if (has_find_id) {
4382                 CHECK_BYTE_COUNT_SUBR(1);
4383                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4384                 COUNT_BYTES_SUBR(1);
4385
4386                 /* server cookie */
4387                 CHECK_BYTE_COUNT_SUBR(4);
4388                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4389                 COUNT_BYTES_SUBR(4);
4390         } else {
4391                 /* server cookie */
4392                 CHECK_BYTE_COUNT_SUBR(5);
4393                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4394                 COUNT_BYTES_SUBR(5);
4395         }
4396
4397         /* client cookie */
4398         CHECK_BYTE_COUNT_SUBR(4);
4399         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4400         COUNT_BYTES_SUBR(4);
4401
4402         *trunc = FALSE;
4403         return offset;
4404 }
4405
4406 static int
4407 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4408     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4409     gboolean has_find_id)
4410 {
4411         proto_item *item = NULL;
4412         proto_tree *tree = NULL;
4413         smb_info_t *si = pinfo->private_data;
4414         int fn_len;
4415         const char *fn;
4416         char fname[13+1];
4417
4418         if(parent_tree){
4419                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4420                         "Directory Information");
4421                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4422         }
4423
4424         /* resume key */
4425         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4426             trunc, has_find_id);
4427         if (*trunc)
4428                 return offset;
4429
4430         /* File Attributes */
4431         CHECK_BYTE_COUNT_SUBR(1);
4432         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4433         *bcp -= 1;
4434
4435         /* last write time */
4436         CHECK_BYTE_COUNT_SUBR(4);
4437         offset = dissect_smb_datetime(tvb, tree, offset,
4438                 hf_smb_last_write_time,
4439                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4440                 TRUE);
4441         *bcp -= 4;
4442
4443         /* File Size */
4444         CHECK_BYTE_COUNT_SUBR(4);
4445         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4446         COUNT_BYTES_SUBR(4);
4447
4448         /* file name */
4449         fn_len = 13;
4450         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4451                 TRUE, TRUE, bcp);
4452         CHECK_STRING_SUBR(fn);
4453         /* ensure that it's null-terminated */
4454         strncpy(fname, fn, 13);
4455         fname[13] = '\0';
4456         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4457                 fname);
4458         COUNT_BYTES_SUBR(fn_len);
4459
4460         *trunc = FALSE;
4461         return offset;
4462 }
4463
4464
4465 static int
4466 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4467     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4468     gboolean has_find_id)
4469 {
4470         smb_info_t *si = pinfo->private_data;
4471         int fn_len;
4472         const char *fn;
4473         guint16 rkl;
4474         guint8 wc;
4475         guint16 bc;
4476         gboolean trunc;
4477
4478         WORD_COUNT;
4479
4480         /* max count */
4481         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4482         offset += 2;
4483
4484         /* Search Attributes */
4485         offset = dissect_search_attributes(tvb, tree, offset);
4486
4487         BYTE_COUNT;
4488
4489         /* buffer format */
4490         CHECK_BYTE_COUNT(1);
4491         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4492         COUNT_BYTES(1);
4493
4494         /* file name */
4495         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4496                 TRUE, FALSE, &bc);
4497         if (fn == NULL)
4498                 goto endofcommand;
4499         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4500                 fn);
4501         COUNT_BYTES(fn_len);
4502
4503         if (check_col(pinfo->cinfo, COL_INFO)) {
4504                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4505         }
4506
4507         /* buffer format */
4508         CHECK_BYTE_COUNT(1);
4509         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4510         COUNT_BYTES(1);
4511
4512         /* resume key length */
4513         CHECK_BYTE_COUNT(2);
4514         rkl = tvb_get_letohs(tvb, offset);
4515         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4516         COUNT_BYTES(2);
4517
4518         /* resume key */
4519         if(rkl){
4520                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4521                     &bc, &trunc, has_find_id);
4522                 if (trunc)
4523                         goto endofcommand;
4524         }
4525
4526         END_OF_SMB
4527
4528         return offset;
4529 }
4530
4531 static int
4532 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4533     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4534 {
4535         return dissect_search_find_request(tvb, pinfo, tree, offset,
4536             smb_tree, FALSE);
4537 }
4538
4539 static int
4540 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4541     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4542 {
4543         return dissect_search_find_request(tvb, pinfo, tree, offset,
4544             smb_tree, TRUE);
4545 }
4546
4547 static int
4548 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4549     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4550 {
4551         return dissect_search_find_request(tvb, pinfo, tree, offset,
4552             smb_tree, TRUE);
4553 }
4554
4555 static int
4556 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4557     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4558     gboolean has_find_id)
4559 {
4560         guint16 count=0;
4561         guint8 wc;
4562         guint16 bc;
4563         gboolean trunc;
4564
4565         WORD_COUNT;
4566
4567         /* count */
4568         count = tvb_get_letohs(tvb, offset);
4569         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4570         offset += 2;
4571
4572         BYTE_COUNT;
4573
4574         /* buffer format */
4575         CHECK_BYTE_COUNT(1);
4576         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4577         COUNT_BYTES(1);
4578
4579         /* data len */
4580         CHECK_BYTE_COUNT(2);
4581         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4582         COUNT_BYTES(2);
4583
4584         while(count--){
4585                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4586                     &bc, &trunc, has_find_id);
4587                 if (trunc)
4588                         goto endofcommand;
4589         }
4590
4591         END_OF_SMB
4592
4593         return offset;
4594 }
4595
4596 static int
4597 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4598 {
4599         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4600             FALSE);
4601 }
4602
4603 static int
4604 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4605 {
4606         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4607             TRUE);
4608 }
4609
4610 static int
4611 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4612     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4613 {
4614         guint8 wc;
4615         guint16 bc;
4616         guint16 data_len;
4617
4618         WORD_COUNT;
4619
4620         /* reserved */
4621         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4622         offset += 2;
4623
4624         BYTE_COUNT;
4625
4626         /* buffer format */
4627         CHECK_BYTE_COUNT(1);
4628         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4629         COUNT_BYTES(1);
4630
4631         /* data len */
4632         CHECK_BYTE_COUNT(2);
4633         data_len = tvb_get_ntohs(tvb, offset);
4634         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4635         COUNT_BYTES(2);
4636
4637         if (data_len != 0) {
4638                 CHECK_BYTE_COUNT(data_len);
4639                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4640                     data_len, TRUE);
4641                 COUNT_BYTES(data_len);
4642         }
4643
4644         END_OF_SMB
4645
4646         return offset;
4647 }
4648
4649 static const value_string locking_ol_vals[] = {
4650         {0,     "Client is not holding oplock on this file"},
4651         {1,     "Level 2 oplock currently held by client"},
4652         {0, NULL}
4653 };
4654
4655 static const true_false_string tfs_lock_type_large = {
4656         "Large file locking format requested",
4657         "Large file locking format not requested"
4658 };
4659 static const true_false_string tfs_lock_type_cancel = {
4660         "Cancel outstanding lock request",
4661         "Don't cancel outstanding lock request"
4662 };
4663 static const true_false_string tfs_lock_type_change = {
4664         "Change lock type",
4665         "Don't change lock type"
4666 };
4667 static const true_false_string tfs_lock_type_oplock = {
4668         "This is an oplock break notification/response",
4669         "This is not an oplock break notification/response"
4670 };
4671 static const true_false_string tfs_lock_type_shared = {
4672         "This is a shared lock",
4673         "This is an exclusive lock"
4674 };
4675 static int
4676 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4677 {
4678         guint8  wc, cmd=0xff, lt=0;
4679         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4680         guint32 to;
4681         proto_item *litem = NULL;
4682         proto_tree *ltree = NULL;
4683         proto_item *it = NULL;
4684         proto_tree *tr = NULL;
4685         int old_offset = offset;
4686
4687         WORD_COUNT;
4688
4689         /* next smb command */
4690         cmd = tvb_get_guint8(tvb, offset);
4691         if(cmd!=0xff){
4692                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4693         } else {
4694                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4695         }
4696         offset += 1;
4697
4698         /* reserved byte */
4699         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4700         offset += 1;
4701
4702         /* andxoffset */
4703         andxoffset = tvb_get_letohs(tvb, offset);
4704         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4705         offset += 2;
4706
4707         /* fid */
4708         fid = tvb_get_letohs(tvb, offset);
4709         add_fid(tvb, pinfo, tree, offset, 2, fid);
4710         offset += 2;
4711
4712         /* lock type */
4713         lt = tvb_get_guint8(tvb, offset);
4714         if(tree){
4715                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4716                         "Lock Type: 0x%02x", lt);
4717                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4718         }
4719         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4720                 tvb, offset, 1, lt);
4721         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4722                 tvb, offset, 1, lt);
4723         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4724                 tvb, offset, 1, lt);
4725         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4726                 tvb, offset, 1, lt);
4727         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4728                 tvb, offset, 1, lt);
4729         offset += 1;
4730
4731         /* oplock level */
4732         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4733         offset += 1;
4734
4735         /* timeout */
4736         to = tvb_get_letohl(tvb, offset);
4737         if (to == 0)
4738                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4739         else if (to == 0xffffffff)
4740                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4741         else
4742                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4743         offset += 4;
4744
4745         /* number of unlocks */
4746         un = tvb_get_letohs(tvb, offset);
4747         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4748         offset += 2;
4749
4750         /* number of locks */
4751         ln = tvb_get_letohs(tvb, offset);
4752         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4753         offset += 2;
4754
4755         BYTE_COUNT;
4756
4757         /* unlocks */
4758         if(un){
4759                 old_offset = offset;
4760
4761                 it = proto_tree_add_text(tree, tvb, offset, -1,
4762                         "Unlocks");
4763                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4764                 while(un--){
4765                         proto_item *litem = NULL;
4766                         proto_tree *ltree = NULL;
4767                         if(lt&0x10){
4768                                 guint8 buf[8];
4769                                 guint32 val;
4770
4771                                 /* large lock format */
4772                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4773                                         "Unlock");
4774                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4775
4776                                 /* PID */
4777                                 CHECK_BYTE_COUNT(2);
4778                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4779                                 COUNT_BYTES(2);
4780
4781                                 /* 2 reserved bytes */
4782                                 CHECK_BYTE_COUNT(2);
4783                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4784                                 COUNT_BYTES(2);
4785
4786                                 /* offset */
4787                                 CHECK_BYTE_COUNT(8);
4788                                 val=tvb_get_letohl(tvb, offset);
4789                                 buf[3]=(val>>24)&0xff;
4790                                 buf[2]=(val>>16)&0xff;
4791                                 buf[1]=(val>> 8)&0xff;
4792                                 buf[0]=(val    )&0xff;
4793                                 val=tvb_get_letohl(tvb, offset+4);
4794                                 buf[7]=(val>>24)&0xff;
4795                                 buf[6]=(val>>16)&0xff;
4796                                 buf[5]=(val>> 8)&0xff;
4797                                 buf[4]=(val    )&0xff;
4798                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4799                                 COUNT_BYTES(8);
4800
4801                                 /* length */
4802                                 CHECK_BYTE_COUNT(8);
4803                                 val=tvb_get_letohl(tvb, offset);
4804                                 buf[3]=(val>>24)&0xff;
4805                                 buf[2]=(val>>16)&0xff;
4806                                 buf[1]=(val>> 8)&0xff;
4807                                 buf[0]=(val    )&0xff;
4808                                 val=tvb_get_letohl(tvb, offset+4);
4809                                 buf[7]=(val>>24)&0xff;
4810                                 buf[6]=(val>>16)&0xff;
4811                                 buf[5]=(val>> 8)&0xff;
4812                                 buf[4]=(val    )&0xff;
4813                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4814                                 COUNT_BYTES(8);
4815                         } else {
4816                                 /* normal lock format */
4817                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4818                                         "Unlock");
4819                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4820
4821                                 /* PID */
4822                                 CHECK_BYTE_COUNT(2);
4823                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4824                                 COUNT_BYTES(2);
4825
4826                                 /* offset */
4827                                 CHECK_BYTE_COUNT(4);
4828                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4829                                 COUNT_BYTES(4);
4830
4831                                 /* lock count */
4832                                 CHECK_BYTE_COUNT(4);
4833                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4834                                 COUNT_BYTES(4);
4835                         }
4836                 }
4837                 proto_item_set_len(it, offset-old_offset);
4838                 it = NULL;
4839         }
4840
4841         /* locks */
4842         if(ln){
4843                 old_offset = offset;
4844
4845                 it = proto_tree_add_text(tree, tvb, offset, -1,
4846                         "Locks");
4847                 tr = proto_item_add_subtree(it, ett_smb_locks);
4848                 while(ln--){
4849                         proto_item *litem = NULL;
4850                         proto_tree *ltree = NULL;
4851                         if(lt&0x10){
4852                                 guint8 buf[8];
4853                                 guint32 val;
4854
4855                                 /* large lock format */
4856                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4857                                         "Lock");
4858                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4859
4860                                 /* PID */
4861                                 CHECK_BYTE_COUNT(2);
4862                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4863                                 COUNT_BYTES(2);
4864
4865                                 /* 2 reserved bytes */
4866                                 CHECK_BYTE_COUNT(2);
4867                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4868                                 COUNT_BYTES(2);
4869
4870                                 /* offset */
4871                                 CHECK_BYTE_COUNT(8);
4872                                 val=tvb_get_letohl(tvb, offset);
4873                                 buf[3]=(val    )&0xff;
4874                                 buf[2]=(val>> 8)&0xff;
4875                                 buf[1]=(val>>16)&0xff;
4876                                 buf[0]=(val>>24)&0xff;
4877                                 val=tvb_get_letohl(tvb, offset+4);
4878                                 buf[7]=(val    )&0xff;
4879                                 buf[6]=(val>> 8)&0xff;
4880                                 buf[5]=(val>>16)&0xff;
4881                                 buf[4]=(val>>24)&0xff;
4882                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4883                                 COUNT_BYTES(8);
4884
4885                                 /* length */
4886                                 CHECK_BYTE_COUNT(8);
4887                                 val=tvb_get_letohl(tvb, offset);
4888                                 buf[3]=(val    )&0xff;
4889                                 buf[2]=(val>> 8)&0xff;
4890                                 buf[1]=(val>>16)&0xff;
4891                                 buf[0]=(val>>24)&0xff;
4892                                 val=tvb_get_letohl(tvb, offset+4);
4893                                 buf[7]=(val    )&0xff;
4894                                 buf[6]=(val>> 8)&0xff;
4895                                 buf[5]=(val>>16)&0xff;
4896                                 buf[4]=(val>>24)&0xff;
4897                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4898                                 COUNT_BYTES(8);
4899                         } else {
4900                                 /* normal lock format */
4901                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4902                                         "Unlock");
4903                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4904
4905                                 /* PID */
4906                                 CHECK_BYTE_COUNT(2);
4907                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4908                                 COUNT_BYTES(2);
4909
4910                                 /* offset */
4911                                 CHECK_BYTE_COUNT(4);
4912                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4913                                 COUNT_BYTES(4);
4914
4915                                 /* lock count */
4916                                 CHECK_BYTE_COUNT(4);
4917                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4918                                 COUNT_BYTES(4);
4919                         }
4920                 }
4921                 proto_item_set_len(it, offset-old_offset);
4922                 it = NULL;
4923         }
4924
4925         END_OF_SMB
4926
4927         if (it != NULL) {
4928                 /*
4929                  * We ran out of byte count in the middle of dissecting
4930                  * the locks or the unlocks; set the site of the item
4931                  * we were dissecting.
4932                  */
4933                 proto_item_set_len(it, offset-old_offset);
4934         }
4935
4936         /* call AndXCommand (if there are any) */
4937         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4938
4939         return offset;
4940 }
4941
4942 static int
4943 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4944 {
4945         guint8  wc, cmd=0xff;
4946         guint16 andxoffset=0;
4947         guint16 bc;
4948
4949         WORD_COUNT;
4950
4951         /* next smb command */
4952         cmd = tvb_get_guint8(tvb, offset);
4953         if(cmd!=0xff){
4954                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4955         } else {
4956                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4957         }
4958         offset += 1;
4959
4960         /* reserved byte */
4961         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4962         offset += 1;
4963
4964         /* andxoffset */
4965         andxoffset = tvb_get_letohs(tvb, offset);
4966         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4967         offset += 2;
4968
4969         BYTE_COUNT;
4970
4971         END_OF_SMB
4972
4973         /* call AndXCommand (if there are any) */
4974         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4975
4976         return offset;
4977 }
4978
4979
4980 static const value_string oa_open_vals[] = {
4981         { 0,            "No action taken?"},
4982         { 1,            "The file existed and was opened"},
4983         { 2,            "The file did not exist but was created"},
4984         { 3,            "The file existed and was truncated"},
4985         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4986         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4987         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4988         {0,     NULL}
4989 };
4990 static const true_false_string tfs_oa_lock = {
4991         "File is currently opened only by this user",
4992         "File is opened by another user (or mode not supported by server)"
4993 };
4994 static int
4995 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4996 {
4997         guint16 mask;
4998         proto_item *item = NULL;
4999         proto_tree *tree = NULL;
5000
5001         mask = tvb_get_letohs(tvb, offset);
5002
5003         if(parent_tree){
5004                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5005                         "Action: 0x%04x", mask);
5006                 tree = proto_item_add_subtree(item, ett_smb_open_action);
5007         }
5008
5009         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
5010                 tvb, offset, 2, mask);
5011         proto_tree_add_uint(tree, hf_smb_open_action_open,
5012                 tvb, offset, 2, mask);
5013
5014         offset += 2;
5015
5016         return offset;
5017 }
5018
5019 static const true_false_string tfs_open_flags_add_info = {
5020         "Additional information requested",
5021         "Additional information not requested"
5022 };
5023 static const true_false_string tfs_open_flags_ex_oplock = {
5024         "Exclusive oplock requested",
5025         "Exclusive oplock not requested"
5026 };
5027 static const true_false_string tfs_open_flags_batch_oplock = {
5028         "Batch oplock requested",
5029         "Batch oplock not requested"
5030 };
5031 static const true_false_string tfs_open_flags_ealen = {
5032         "Total length of EAs requested",
5033         "Total length of EAs not requested"
5034 };
5035 static int
5036 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5037 {
5038         guint16 mask;
5039         proto_item *item = NULL;
5040         proto_tree *tree = NULL;
5041
5042         mask = tvb_get_letohs(tvb, offset);
5043
5044         if(parent_tree){
5045                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5046                         "Flags: 0x%04x", mask);
5047                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5048         }
5049
5050         if(bm&0x0001){
5051                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5052                         tvb, offset, 2, mask);
5053         }
5054         if(bm&0x0002){
5055                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5056                         tvb, offset, 2, mask);
5057         }
5058         if(bm&0x0004){
5059                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5060                         tvb, offset, 2, mask);
5061         }
5062         if(bm&0x0008){
5063                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5064                         tvb, offset, 2, mask);
5065         }
5066
5067         offset += 2;
5068
5069         return offset;
5070 }
5071
5072 static const value_string filetype_vals[] = {
5073         { 0,            "Disk file or directory"},
5074         { 1,            "Named pipe in byte mode"},
5075         { 2,            "Named pipe in message mode"},
5076         { 3,            "Spooled printer"},
5077         {0, NULL}
5078 };
5079 static int
5080 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5081 {
5082         guint8  wc, cmd=0xff;
5083         guint16 andxoffset=0, bc;
5084         smb_info_t *si = pinfo->private_data;
5085         int fn_len;
5086         const char *fn;
5087
5088         WORD_COUNT;
5089
5090         /* next smb command */
5091         cmd = tvb_get_guint8(tvb, offset);
5092         if(cmd!=0xff){
5093                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5094         } else {
5095                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5096         }
5097         offset += 1;
5098
5099         /* reserved byte */
5100         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5101         offset += 1;
5102
5103         /* andxoffset */
5104         andxoffset = tvb_get_letohs(tvb, offset);
5105         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5106         offset += 2;
5107
5108         /* open flags */
5109         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5110
5111         /* desired access */
5112         offset = dissect_access(tvb, tree, offset, "Desired");
5113
5114         /* Search Attributes */
5115         offset = dissect_search_attributes(tvb, tree, offset);
5116
5117         /* File Attributes */
5118         offset = dissect_file_attributes(tvb, tree, offset, 2);
5119
5120         /* creation time */
5121         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5122
5123         /* open function */
5124         offset = dissect_open_function(tvb, tree, offset);
5125
5126         /* allocation size */
5127         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5128         offset += 4;
5129
5130         /* 8 reserved bytes */
5131         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5132         offset += 8;
5133
5134         BYTE_COUNT;
5135
5136         /* file name */
5137         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5138                 FALSE, FALSE, &bc);
5139         if (fn == NULL)
5140                 goto endofcommand;
5141         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5142                 fn);
5143         COUNT_BYTES(fn_len);
5144
5145         if (check_col(pinfo->cinfo, COL_INFO)) {
5146                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5147         }
5148
5149         END_OF_SMB
5150
5151         /* call AndXCommand (if there are any) */
5152         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5153
5154         return offset;
5155 }
5156
5157 static const true_false_string tfs_ipc_state_nonblocking = {
5158         "Reads/writes return immediately if no data available",
5159         "Reads/writes block if no data available"
5160 };
5161 static const value_string ipc_state_endpoint_vals[] = {
5162         { 0,            "Consumer end of pipe"},
5163         { 1,            "Server end of pipe"},
5164         {0,     NULL}
5165 };
5166 static const value_string ipc_state_pipe_type_vals[] = {
5167         { 0,            "Byte stream pipe"},
5168         { 1,            "Message pipe"},
5169         {0,     NULL}
5170 };
5171 static const value_string ipc_state_read_mode_vals[] = {
5172         { 0,            "Read pipe as a byte stream"},
5173         { 1,            "Read messages from pipe"},
5174         {0,     NULL}
5175 };
5176
5177 int
5178 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5179     gboolean setstate)
5180 {
5181         guint16 mask;
5182         proto_item *item = NULL;
5183         proto_tree *tree = NULL;
5184
5185         mask = tvb_get_letohs(tvb, offset);
5186
5187         if(parent_tree){
5188                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5189                         "IPC State: 0x%04x", mask);
5190                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5191         }
5192
5193         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5194                 tvb, offset, 2, mask);
5195         if (!setstate) {
5196                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5197                         tvb, offset, 2, mask);
5198                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5199                         tvb, offset, 2, mask);
5200         }
5201         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5202                 tvb, offset, 2, mask);
5203         if (!setstate) {
5204                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5205                         tvb, offset, 2, mask);
5206         }
5207
5208         offset += 2;
5209
5210         return offset;
5211 }
5212
5213 static int
5214 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5215 {
5216         guint8  wc, cmd=0xff;
5217         guint16 andxoffset=0, bc;
5218         guint16 fid;
5219
5220         WORD_COUNT;
5221
5222         /* next smb command */
5223         cmd = tvb_get_guint8(tvb, offset);
5224         if(cmd!=0xff){
5225                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5226         } else {
5227                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5228         }
5229         offset += 1;
5230
5231         /* reserved byte */
5232         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5233         offset += 1;
5234
5235         /* andxoffset */
5236         andxoffset = tvb_get_letohs(tvb, offset);
5237         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5238         offset += 2;
5239
5240         /* fid */
5241         fid = tvb_get_letohs(tvb, offset);
5242         add_fid(tvb, pinfo, tree, offset, 2, fid);
5243         offset += 2;
5244
5245         /* File Attributes */
5246         offset = dissect_file_attributes(tvb, tree, offset, 2);
5247
5248         /* last write time */
5249         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5250
5251         /* File Size */
5252         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5253         offset += 4;
5254
5255         /* granted access */
5256         offset = dissect_access(tvb, tree, offset, "Granted");
5257
5258         /* File Type */
5259         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5260         offset += 2;
5261
5262         /* IPC State */
5263         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5264
5265         /* open_action */
5266         offset = dissect_open_action(tvb, tree, offset);
5267
5268         /* server fid */
5269         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5270         offset += 4;
5271
5272         /* 2 reserved bytes */
5273         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5274         offset += 2;
5275
5276         BYTE_COUNT;
5277
5278         END_OF_SMB
5279
5280         /* call AndXCommand (if there are any) */
5281         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5282
5283         return offset;
5284 }
5285
5286 static int
5287 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5288 {
5289         guint8  wc, cmd=0xff;
5290         guint16 andxoffset=0, bc, maxcnt_low;
5291         guint32 maxcnt_high;
5292         guint32 maxcnt=0;
5293         guint32 ofs = 0;
5294         smb_info_t *si;
5295         unsigned int fid;
5296
5297         WORD_COUNT;
5298
5299         /* next smb command */
5300         cmd = tvb_get_guint8(tvb, offset);
5301         if(cmd!=0xff){
5302                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5303         } else {
5304                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5305         }
5306         offset += 1;
5307
5308         /* reserved byte */
5309         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5310         offset += 1;
5311
5312         /* andxoffset */
5313         andxoffset = tvb_get_letohs(tvb, offset);
5314         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5315         offset += 2;
5316
5317         /* fid */
5318         fid = tvb_get_letohs(tvb, offset);
5319         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
5320         offset += 2;
5321         if (!pinfo->fd->flags.visited) {
5322                 /* remember the FID for the processing of the response */
5323                 si = (smb_info_t *)pinfo->private_data;
5324                 si->sip->extra_info=(void *)fid;
5325         }
5326
5327         /* offset */
5328         ofs = tvb_get_letohl(tvb, offset);
5329         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5330         offset += 4;
5331
5332         /* max count low */
5333         maxcnt_low = tvb_get_letohs(tvb, offset);
5334         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
5335         offset += 2;
5336
5337         /* min count */
5338         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5339         offset += 2;
5340
5341         /*
5342          * max count high
5343          *
5344          * XXX - we should really only do this in case we have seen
5345          * LARGE FILE being negotiated.  Unfortunately, we might not
5346          * have seen the negotiation phase in the capture....
5347          *
5348          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
5349          * it's 32 bits, but the description says "High 16 bits of
5350          * MaxCount if CAP_LARGE_READX".
5351          *
5352          * The SMB File Sharing Protocol Extensions Version 2.0,
5353          * Document Version 3.3 spec doesn't speak of an extra 16
5354          * bits in max count, but it does show a 32-bit timeout
5355          * after the min count field.
5356          *
5357          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
5358          * high count and a 16-bit reserved field.
5359          *
5360          * We fetch and display it as 32 bits.
5361          * 
5362          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
5363          * bytes and we just ignore it.
5364          */
5365         maxcnt_high = tvb_get_letohl(tvb, offset);
5366         if(maxcnt_high==0xffffffff){
5367                 maxcnt_high=0;
5368         } else {
5369                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5370         }
5371
5372         offset += 4;
5373
5374         maxcnt=maxcnt_high;
5375         maxcnt=(maxcnt<<16)|maxcnt_low;
5376
5377         if (check_col(pinfo->cinfo, COL_INFO))
5378                 col_append_fstr(pinfo->cinfo, COL_INFO,
5379                                 ", %u byte%s at offset %u", maxcnt,
5380                                 (maxcnt == 1) ? "" : "s", ofs);
5381
5382         /* remaining */
5383         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5384         offset += 2;
5385
5386         if(wc==12){
5387                 /* high offset */
5388                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5389                 offset += 4;
5390         }
5391
5392         BYTE_COUNT;
5393
5394         END_OF_SMB
5395
5396         /* call AndXCommand (if there are any) */
5397         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5398
5399         return offset;
5400 }
5401
5402 static int
5403 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5404 {
5405         guint8  wc, cmd=0xff;
5406         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
5407         guint32 datalen=0, datalen_high;
5408         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5409         int fid=0;
5410
5411         WORD_COUNT;
5412
5413         /* next smb command */
5414         cmd = tvb_get_guint8(tvb, offset);
5415         if(cmd!=0xff){
5416                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5417         } else {
5418                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5419         }
5420         offset += 1;
5421
5422         /* reserved byte */
5423         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5424         offset += 1;
5425
5426         /* andxoffset */
5427         andxoffset = tvb_get_letohs(tvb, offset);
5428         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5429         offset += 2;
5430
5431         /* If we have seen the request, then print which FID this refers to */
5432         /* first check if we have seen the request */
5433         if(si->sip != NULL && si->sip->frame_req>0){
5434                 fid=(int)si->sip->extra_info;
5435                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) fid);
5436         }
5437
5438         /* remaining */
5439         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5440         offset += 2;
5441
5442         /* data compaction mode */
5443         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5444         offset += 2;
5445
5446         /* 2 reserved bytes */
5447         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5448         offset += 2;
5449
5450         /* data len low */
5451         datalen_low = tvb_get_letohs(tvb, offset);
5452         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5453         offset += 2;
5454
5455         /* data offset */
5456         dataoffset=tvb_get_letohs(tvb, offset);
5457         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5458         offset += 2;
5459
5460         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5461         /* data length high */
5462         datalen_high = tvb_get_letohl(tvb, offset);
5463         if(datalen_high==0xffffffff){
5464                 datalen_high=0;
5465         } else {
5466                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
5467         }
5468         offset += 4;
5469
5470         datalen=datalen_high;
5471         datalen=(datalen<<16)|datalen_low;
5472
5473
5474         if (check_col(pinfo->cinfo, COL_INFO))
5475                 col_append_fstr(pinfo->cinfo, COL_INFO,
5476                                 ", %u byte%s", datalen,
5477                                 (datalen == 1) ? "" : "s");
5478
5479
5480         /* 6 reserved bytes */
5481         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
5482         offset += 6;
5483
5484         BYTE_COUNT;
5485
5486         /* file data, might be DCERPC on a pipe */
5487         if(bc){
5488                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5489                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
5490                 bc = 0;
5491         }
5492
5493         END_OF_SMB
5494
5495         /* call AndXCommand (if there are any) */
5496         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5497
5498         return offset;
5499 }
5500
5501 static int
5502 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5503 {
5504         guint32 ofs=0;
5505         guint8  wc, cmd=0xff;
5506         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
5507         guint32 datalen=0;
5508         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5509         unsigned int fid=0;
5510         guint16 mode = 0;
5511
5512         WORD_COUNT;
5513
5514         /* next smb command */
5515         cmd = tvb_get_guint8(tvb, offset);
5516         if(cmd!=0xff){
5517                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5518         } else {
5519                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5520         }
5521         offset += 1;
5522
5523         /* reserved byte */
5524         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5525         offset += 1;
5526
5527         /* andxoffset */
5528         andxoffset = tvb_get_letohs(tvb, offset);
5529         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5530         offset += 2;
5531
5532         /* fid */
5533         fid = tvb_get_letohs(tvb, offset);
5534         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
5535         offset += 2;
5536         if (!pinfo->fd->flags.visited) {
5537                 /* remember the FID for the processing of the response */
5538                 si->sip->extra_info=(void *)fid;
5539         }
5540
5541         /* offset */
5542         ofs = tvb_get_letohl(tvb, offset);
5543         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5544         offset += 4;
5545
5546         /* reserved */
5547         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5548         offset += 4;
5549
5550         /* mode */
5551         mode = tvb_get_letohs(tvb, offset);
5552         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5553
5554         /* remaining */
5555         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5556         offset += 2;
5557
5558         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5559         /* data length high */
5560         datalen_high = tvb_get_letohs(tvb, offset);
5561         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5562         offset += 2;
5563
5564         /* data len low */
5565         datalen_low = tvb_get_letohs(tvb, offset);
5566         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5567         offset += 2;
5568
5569         datalen=datalen_high;
5570         datalen=(datalen<<16)|datalen_low;
5571
5572         /* data offset */
5573         dataoffset=tvb_get_letohs(tvb, offset);
5574         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5575         offset += 2;
5576
5577         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5578         if (check_col(pinfo->cinfo, COL_INFO))
5579                 col_append_fstr(pinfo->cinfo, COL_INFO,
5580                                 ", %u byte%s at offset %u", datalen,
5581                                 (datalen == 1) ? "" : "s", ofs);
5582
5583         if(wc==14){
5584                 /* high offset */
5585                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5586                 offset += 4;
5587         }
5588
5589         BYTE_COUNT;
5590
5591         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5592            the first two bytes of the payload is the length of the data.
5593            Assume that all WriteAndX PDUs that have MESSAGE_START set to
5594            be over the IPC$ share and thus they all transport DCERPC.
5595            (if we didnt already know that from the TreeConnect call)
5596         */
5597         if(mode&WRITE_MODE_MESSAGE_START){
5598                 if(mode&WRITE_MODE_RAW){
5599                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5600                         offset += 2;
5601                         dataoffset += 2;
5602                         bc -= 2;
5603                         datalen -= 2;
5604                 }
5605                 if(!pinfo->fd->flags.visited){
5606                         /* In case we did not see the TreeConnect call,
5607                            store this TID here as well as a IPC TID 
5608                            so we know that future Read/Writes to this 
5609                            TID is (probably) DCERPC.
5610                         */
5611                         if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
5612                                 g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
5613                         }
5614                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
5615                 }
5616                 if(si->sip){
5617                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5618                 }
5619         }
5620
5621         /* file data, might be DCERPC on a pipe */
5622         if (bc != 0) {
5623                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5624                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
5625                 bc = 0;
5626         }
5627
5628         END_OF_SMB
5629
5630         /* call AndXCommand (if there are any) */
5631         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5632
5633         return offset;
5634 }
5635
5636 static int
5637 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5638 {
5639         guint8  wc, cmd=0xff;
5640         guint16 andxoffset=0, bc, count_low, count_high;
5641         guint32 count=0;
5642         smb_info_t *si;
5643
5644         WORD_COUNT;
5645
5646         /* next smb command */
5647         cmd = tvb_get_guint8(tvb, offset);
5648         if(cmd!=0xff){
5649                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5650         } else {
5651                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5652         }
5653         offset += 1;
5654
5655         /* reserved byte */
5656         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5657         offset += 1;
5658
5659         /* andxoffset */
5660         andxoffset = tvb_get_letohs(tvb, offset);
5661         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5662         offset += 2;
5663
5664         /* If we have seen the request, then print which FID this refers to */
5665         si = (smb_info_t *)pinfo->private_data;
5666         /* first check if we have seen the request */
5667         if(si->sip != NULL && si->sip->frame_req>0){
5668                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) GPOINTER_TO_UINT(si->sip->extra_info));
5669         }
5670
5671         /* write count low */
5672         count_low = tvb_get_letohs(tvb, offset);
5673         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
5674         offset += 2;
5675
5676         /* remaining */
5677         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5678         offset += 2;
5679
5680         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5681         /* write count high */
5682         count_high = tvb_get_letohs(tvb, offset);
5683         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
5684         offset += 2;
5685
5686         count=count_high;
5687         count=(count<<16)|count_low;
5688
5689         if (check_col(pinfo->cinfo, COL_INFO))
5690                 col_append_fstr(pinfo->cinfo, COL_INFO,
5691                                 ", %u byte%s", count,
5692                                 (count == 1) ? "" : "s");
5693
5694         /* 2 reserved bytes */
5695         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5696         offset += 2;
5697
5698         BYTE_COUNT;
5699
5700         END_OF_SMB
5701
5702         /* call AndXCommand (if there are any) */
5703         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5704
5705         return offset;
5706 }
5707
5708
5709 static const true_false_string tfs_setup_action_guest = {
5710         "Logged in as GUEST",
5711         "Not logged in as GUEST"
5712 };
5713 static int
5714 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5715 {
5716         guint16 mask;
5717         proto_item *item = NULL;
5718         proto_tree *tree = NULL;
5719
5720         mask = tvb_get_letohs(tvb, offset);
5721
5722         if(parent_tree){
5723                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5724                         "Action: 0x%04x", mask);
5725                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5726         }
5727
5728         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5729                 tvb, offset, 2, mask);
5730
5731         offset += 2;
5732
5733         return offset;
5734 }
5735
5736
5737 static int
5738 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5739 {
5740         guint8  wc, cmd=0xff;
5741         guint16 bc;
5742         guint16 andxoffset=0;
5743         smb_info_t *si = pinfo->private_data;
5744         int an_len;
5745         const char *an;
5746         int dn_len;
5747         const char *dn;
5748         guint16 pwlen=0;
5749         guint16 sbloblen=0, sbloblen_short;
5750         guint16 apwlen=0, upwlen=0;
5751         gboolean unicodeflag;
5752
5753         WORD_COUNT;
5754
5755         /* next smb command */
5756         cmd = tvb_get_guint8(tvb, offset);
5757         if(cmd!=0xff){
5758                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5759         } else {
5760                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5761         }
5762         offset += 1;
5763
5764         /* reserved byte */
5765         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5766         offset += 1;
5767
5768         /* andxoffset */
5769         andxoffset = tvb_get_letohs(tvb, offset);
5770         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5771         offset += 2;
5772
5773         /* Maximum Buffer Size */
5774         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5775         offset += 2;
5776
5777         /* Maximum Multiplex Count */
5778         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5779         offset += 2;
5780
5781         /* VC Number */
5782         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5783         offset += 2;
5784
5785         /* session key */
5786         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5787         offset += 4;
5788
5789         switch (wc) {
5790         case 10:
5791                 /* password length, ASCII*/
5792                 pwlen = tvb_get_letohs(tvb, offset);
5793                 proto_tree_add_uint(tree, hf_smb_password_len,
5794                         tvb, offset, 2, pwlen);
5795                 offset += 2;
5796
5797                 /* 4 reserved bytes */
5798                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5799                 offset += 4;
5800
5801                 break;
5802
5803         case 12:
5804                 /* security blob length */
5805                 sbloblen = tvb_get_letohs(tvb, offset);
5806                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5807                 offset += 2;
5808
5809                 /* 4 reserved bytes */
5810                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5811                 offset += 4;
5812
5813                 /* capabilities */
5814                 dissect_negprot_capabilities(tvb, tree, offset);
5815                 offset += 4;
5816
5817                 break;
5818
5819         case 13:
5820                 /* password length, ANSI*/
5821                 apwlen = tvb_get_letohs(tvb, offset);
5822                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5823                         tvb, offset, 2, apwlen);
5824                 offset += 2;
5825
5826                 /* password length, Unicode*/
5827                 upwlen = tvb_get_letohs(tvb, offset);
5828                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5829                         tvb, offset, 2, upwlen);
5830                 offset += 2;
5831
5832                 /* 4 reserved bytes */
5833                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5834                 offset += 4;
5835
5836                 /* capabilities */
5837                 dissect_negprot_capabilities(tvb, tree, offset);
5838                 offset += 4;
5839
5840                 break;
5841         }
5842
5843         BYTE_COUNT;
5844
5845         if (wc==12) {
5846                 proto_item *blob_item;
5847
5848                 /* security blob */
5849                 /* If it runs past the end of the captured data, don't
5850                  * try to put all of it into the protocol tree as the
5851                  * raw security blob; we might get an exception on 
5852                  * short frames and then we will not see anything at all
5853                  * of the security blob.
5854                  */
5855                 sbloblen_short = sbloblen;
5856                 if(sbloblen_short>tvb_length_remaining(tvb,offset)){
5857                         sbloblen_short=tvb_length_remaining(tvb,offset);
5858                 }
5859                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5860                                                 tvb, offset, sbloblen_short,
5861                                                 TRUE);
5862
5863                 /* As an optimization, because Windows is perverse,
5864                    we check to see if NTLMSSP is the first part of the 
5865                    blob, and if so, call the NTLMSSP dissector,
5866                    otherwise we call the GSS-API dissector. This is because
5867                    Windows can request RAW NTLMSSP, but will happily handle
5868                    a client that wraps NTLMSSP in SPNEGO
5869                 */
5870
5871                 if(sbloblen){
5872                         tvbuff_t *blob_tvb;
5873                         proto_tree *blob_tree;
5874
5875                         blob_tree = proto_item_add_subtree(blob_item, 
5876                                                            ett_smb_secblob);
5877                         CHECK_BYTE_COUNT(sbloblen);
5878
5879                         /*
5880                          * Set the reported length of this to the reported
5881                          * length of the blob, rather than the amount of
5882                          * data available from the blob, so that we'll
5883                          * throw the right exception if it's too short.
5884                          */
5885                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen_short,
5886                                                   sbloblen);
5887
5888                         if (si && si->ct && si->ct->raw_ntlmssp &&
5889                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
5890                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5891                                          blob_tree);
5892
5893                         }
5894                         else {
5895                           call_dissector(gssapi_handle, blob_tvb, 
5896                                          pinfo, blob_tree);
5897                         }
5898
5899                         COUNT_BYTES(sbloblen);
5900                 }
5901
5902                 /* OS
5903                  * Eventhough this field should honour the unicode flag
5904                  * some ms clients gets this wrong.
5905                  * At least XP SP1 sends this in ASCII
5906                  * even when the unicode flag is on.
5907                  * Test if the first three bytes are "Win"
5908                  * and if so just override the flag.
5909                  */
5910                 unicodeflag=si->unicode;
5911                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
5912                         unicodeflag=FALSE;
5913                 }
5914                 an = get_unicode_or_ascii_string(tvb, &offset,
5915                         unicodeflag, &an_len, FALSE, FALSE, &bc);
5916                 if (an == NULL)
5917                         goto endofcommand;
5918                 proto_tree_add_string(tree, hf_smb_os, tvb,
5919                         offset, an_len, an);
5920                 COUNT_BYTES(an_len);
5921
5922                 /* LANMAN */
5923                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5924                  * padding/null string/whatever in front of this. W2K doesn't
5925                  * appear to. I suspect that's a bug that got fixed; I also
5926                  * suspect that, in practice, nobody ever looks at that field
5927                  * because the bug didn't appear to get fixed until NT 5.0....
5928                  *
5929                  * Eventhough this field should honour the unicode flag
5930                  * some ms clients gets this wrong.
5931                  * At least XP SP1 sends this in ASCII
5932                  * even when the unicode flag is on.
5933                  * Test if the first three bytes are "Win"
5934                  * and if so just override the flag.
5935                  */
5936                 unicodeflag=si->unicode;
5937                 if( tvb_strneql(tvb, offset, "Win", 3) == 0 ){
5938                         unicodeflag=FALSE;
5939                 }
5940                 an = get_unicode_or_ascii_string(tvb, &offset,
5941                         unicodeflag, &an_len, FALSE, FALSE, &bc);
5942                 if (an == NULL)
5943                         goto endofcommand;
5944                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5945                         offset, an_len, an);
5946                 COUNT_BYTES(an_len);
5947
5948                 /* Primary domain */
5949                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5950                  * byte in front of this, at least if all the strings are
5951                  * ASCII and the account name is empty. Another bug?
5952                  */
5953                 dn = get_unicode_or_ascii_string(tvb, &offset,
5954                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5955                 if (dn == NULL)
5956                         goto endofcommand;
5957                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5958                         offset, dn_len, dn);
5959                 COUNT_BYTES(dn_len);
5960         } else {
5961                 switch (wc) {
5962
5963                 case 10:
5964                         if(pwlen){
5965                                 /* password, ASCII */
5966                                 CHECK_BYTE_COUNT(pwlen);
5967                                 proto_tree_add_item(tree, hf_smb_password,
5968                                         tvb, offset, pwlen, TRUE);
5969                                 COUNT_BYTES(pwlen);
5970                         }
5971
5972                         break;
5973
5974                 case 13:
5975                         if(apwlen){
5976                                 /* password, ANSI */
5977                                 CHECK_BYTE_COUNT(apwlen);
5978                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5979                                         tvb, offset, apwlen, TRUE);
5980                                 COUNT_BYTES(apwlen);
5981                         }
5982
5983                         if(upwlen){
5984                                 proto_item *item;
5985
5986                                 /* password, Unicode */
5987                                 CHECK_BYTE_COUNT(upwlen);
5988                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5989                                         tvb, offset, upwlen, TRUE);
5990
5991                                 if (upwlen > 24) {
5992                                         proto_tree *subtree;
5993
5994                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5995
5996                                         dissect_ntlmv2_response(
5997                                                 tvb, subtree, offset, upwlen);
5998                                 }
5999
6000                                 COUNT_BYTES(upwlen);
6001                         }
6002
6003                         break;
6004                 }
6005
6006                 /* Account Name */
6007                 an = get_unicode_or_ascii_string(tvb, &offset,
6008                         si->unicode, &an_len, FALSE, FALSE, &bc);
6009                 if (an == NULL)
6010                         goto endofcommand;
6011                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
6012                         an);
6013                 COUNT_BYTES(an_len);
6014
6015                 /* Primary domain */
6016                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
6017                  * byte in front of this, at least if all the strings are
6018                  * ASCII and the account name is empty. Another bug?
6019                  */
6020                 dn = get_unicode_or_ascii_string(tvb, &offset,
6021                         si->unicode, &dn_len, FALSE, FALSE, &bc);
6022                 if (dn == NULL)
6023                         goto endofcommand;
6024                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6025                         offset, dn_len, dn);
6026                 COUNT_BYTES(dn_len);
6027
6028                 if (check_col(pinfo->cinfo, COL_INFO)) {
6029                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
6030
6031                         if (!dn[0] && !an[0])
6032                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6033                                                 "anonymous");
6034                         else
6035                                 col_append_fstr(pinfo->cinfo, COL_INFO,
6036                                                 "%s\\%s", dn,an);
6037                 }
6038
6039                 /* OS */
6040                 an = get_unicode_or_ascii_string(tvb, &offset,
6041                         si->unicode, &an_len, FALSE, FALSE, &bc);
6042                 if (an == NULL)
6043                         goto endofcommand;
6044                 proto_tree_add_string(tree, hf_smb_os, tvb,
6045                         offset, an_len, an);
6046                 COUNT_BYTES(an_len);
6047
6048                 /* LANMAN */
6049                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
6050                  * padding/null string/whatever in front of this. W2K doesn't
6051                  * appear to. I suspect that's a bug that got fixed; I also
6052                  * suspect that, in practice, nobody ever looks at that field
6053                  * because the bug didn't appear to get fixed until NT 5.0....
6054                  */
6055                 an = get_unicode_or_ascii_string(tvb, &offset,
6056                         si->unicode, &an_len, FALSE, FALSE, &bc);
6057                 if (an == NULL)
6058                         goto endofcommand;
6059                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6060                         offset, an_len, an);
6061                 COUNT_BYTES(an_len);
6062         }
6063
6064         END_OF_SMB
6065
6066         /* call AndXCommand (if there are any) */
6067         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6068
6069         return offset;
6070 }
6071
6072 static int
6073 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6074 {
6075         guint8  wc, cmd=0xff;
6076         guint16 andxoffset=0, bc;
6077         guint16 sbloblen=0;
6078         smb_info_t *si = pinfo->private_data;
6079         int an_len;
6080         const char *an;
6081
6082         WORD_COUNT;
6083
6084         /* next smb command */
6085         cmd = tvb_get_guint8(tvb, offset);
6086         if(cmd!=0xff){
6087                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6088         } else {
6089                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6090         }
6091         offset += 1;
6092
6093         /* reserved byte */
6094         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6095         offset += 1;
6096
6097         /* andxoffset */
6098         andxoffset = tvb_get_letohs(tvb, offset);
6099         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6100         offset += 2;
6101
6102         /* flags */
6103         offset = dissect_setup_action(tvb, tree, offset);
6104
6105         if(wc==4){
6106                 /* security blob length */
6107                 sbloblen = tvb_get_letohs(tvb, offset);
6108                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6109                 offset += 2;
6110         }
6111
6112         BYTE_COUNT;
6113
6114         if(wc==4) {
6115                 proto_item *blob_item;
6116
6117                 /* security blob */
6118                 /* dont try to eat too much of we might get an exception on 
6119                  * short frames and then we will not see anything at all
6120                  * of the security blob.
6121                  */
6122                 if(sbloblen>tvb_length_remaining(tvb,offset)){
6123                         sbloblen=tvb_length_remaining(tvb,offset);
6124                 }
6125                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6126                                                 tvb, offset, sbloblen, TRUE);
6127
6128                 if(sbloblen){
6129                         tvbuff_t *blob_tvb;
6130                         proto_tree *blob_tree;
6131
6132                         blob_tree = proto_item_add_subtree(blob_item, 
6133                                                            ett_smb_secblob);
6134                         CHECK_BYTE_COUNT(sbloblen);
6135
6136                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6137                                                     sbloblen);
6138
6139                         if (si && si->ct && si->ct->raw_ntlmssp && 
6140                             tvb_strneql(tvb, offset, "NTLMSSP", 7) == 0) {
6141                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6142                                          blob_tree);
6143
6144                         }
6145                         else {
6146                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6147                                          blob_tree);
6148
6149                         }
6150
6151                         COUNT_BYTES(sbloblen);
6152                 }
6153         }
6154
6155         /* OS */
6156         an = get_unicode_or_ascii_string(tvb, &offset,
6157                 si->unicode, &an_len, FALSE, FALSE, &bc);
6158         if (an == NULL)
6159                 goto endofcommand;
6160         proto_tree_add_string(tree, hf_smb_os, tvb,
6161                 offset, an_len, an);
6162         COUNT_BYTES(an_len);
6163
6164         /* LANMAN */
6165         an = get_unicode_or_ascii_string(tvb, &offset,
6166                 si->unicode, &an_len, FALSE, FALSE, &bc);
6167         if (an == NULL)
6168                 goto endofcommand;
6169         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6170                 offset, an_len, an);
6171         COUNT_BYTES(an_len);
6172
6173         if(wc==3) {
6174                 /* Primary domain */
6175                 an = get_unicode_or_ascii_string(tvb, &offset,
6176                         si->unicode, &an_len, FALSE, FALSE, &bc);
6177                 if (an == NULL)
6178                         goto endofcommand;
6179                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6180                         offset, an_len, an);
6181                 COUNT_BYTES(an_len);
6182         }
6183
6184         END_OF_SMB
6185
6186         /* call AndXCommand (if there are any) */
6187         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6188
6189         return offset;
6190 }
6191
6192
6193 static int
6194 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6195 {
6196         guint8  wc, cmd=0xff;
6197         guint16 andxoffset=0;
6198         guint16 bc;
6199
6200         WORD_COUNT;
6201
6202         /* next smb command */
6203         cmd = tvb_get_guint8(tvb, offset);
6204         if(cmd!=0xff){
6205                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6206         } else {
6207                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6208         }
6209         offset += 1;
6210
6211         /* reserved byte */
6212         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6213         offset += 1;
6214
6215         /* andxoffset */
6216         andxoffset = tvb_get_letohs(tvb, offset);
6217         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6218         offset += 2;
6219
6220         BYTE_COUNT;
6221
6222         END_OF_SMB
6223
6224         /* call AndXCommand (if there are any) */
6225         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6226
6227         return offset;
6228 }
6229
6230
6231 static const true_false_string tfs_connect_support_search = {
6232         "Exclusive search bits supported",
6233         "Exclusive search bits not supported"
6234 };
6235 static const true_false_string tfs_connect_support_in_dfs = {
6236         "Share is in Dfs",
6237         "Share isn't in Dfs"
6238 };
6239
6240 static int
6241 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6242 {
6243         guint16 mask;
6244         proto_item *item = NULL;
6245         proto_tree *tree = NULL;
6246
6247         mask = tvb_get_letohs(tvb, offset);
6248
6249         if(parent_tree){
6250                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6251                         "Optional Support: 0x%04x", mask);
6252                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6253         }
6254
6255         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6256                 tvb, offset, 2, mask);
6257         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6258                 tvb, offset, 2, mask);
6259
6260         offset += 2;
6261
6262         return offset;
6263 }
6264
6265 static const true_false_string tfs_disconnect_tid = {
6266         "DISCONNECT TID",
6267         "Do NOT disconnect TID"
6268 };
6269
6270 static int
6271 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6272 {
6273         guint16 mask;
6274         proto_item *item = NULL;
6275         proto_tree *tree = NULL;
6276
6277         mask = tvb_get_letohs(tvb, offset);
6278
6279         if(parent_tree){
6280                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6281                         "Flags: 0x%04x", mask);
6282                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6283         }
6284
6285         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6286                 tvb, offset, 2, mask);
6287
6288         offset += 2;
6289
6290         return offset;
6291 }
6292
6293 static int
6294 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6295 {
6296         guint8  wc, cmd=0xff;
6297         guint16 bc;
6298         guint16 andxoffset=0, pwlen=0;
6299         smb_info_t *si = pinfo->private_data;
6300         int an_len;
6301         const char *an;
6302
6303         WORD_COUNT;
6304
6305         /* next smb command */
6306         cmd = tvb_get_guint8(tvb, offset);
6307         if(cmd!=0xff){
6308                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6309         } else {
6310                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6311         }
6312         offset += 1;
6313
6314         /* reserved byte */
6315         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6316         offset += 1;
6317
6318         /* andxoffset */
6319         andxoffset = tvb_get_letohs(tvb, offset);
6320         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6321         offset += 2;
6322
6323         /* flags */
6324         offset = dissect_connect_flags(tvb, tree, offset);
6325
6326         /* password length*/
6327         pwlen = tvb_get_letohs(tvb, offset);
6328         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6329         offset += 2;
6330
6331         BYTE_COUNT;
6332
6333         /* password */
6334         CHECK_BYTE_COUNT(pwlen);
6335         proto_tree_add_item(tree, hf_smb_password,
6336                 tvb, offset, pwlen, TRUE);
6337         COUNT_BYTES(pwlen);
6338
6339         /* Path */
6340         an = get_unicode_or_ascii_string(tvb, &offset,
6341                 si->unicode, &an_len, FALSE, FALSE, &bc);
6342         if (an == NULL)
6343                 goto endofcommand;
6344         proto_tree_add_string(tree, hf_smb_path, tvb,
6345                 offset, an_len, an);
6346         COUNT_BYTES(an_len);
6347
6348         if (check_col(pinfo->cinfo, COL_INFO)) {
6349                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6350         }
6351
6352         /*
6353          * NOTE: the Service string is always ASCII, even if the
6354          * "strings are Unicode" bit is set in the flags2 field
6355          * of the SMB.
6356          */
6357
6358         /* Service */
6359         /* XXX - what if this runs past bc? */
6360         an_len = tvb_strsize(tvb, offset);
6361         CHECK_BYTE_COUNT(an_len);
6362         an = tvb_get_ptr(tvb, offset, an_len);
6363         proto_tree_add_string(tree, hf_smb_service, tvb,
6364                 offset, an_len, an);
6365         COUNT_BYTES(an_len);
6366
6367         END_OF_SMB
6368
6369         /* call AndXCommand (if there are any) */
6370         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6371
6372         return offset;
6373 }
6374
6375
6376 static int
6377 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6378 {
6379         guint8  wc, wleft, cmd=0xff;
6380         guint16 andxoffset=0;
6381         guint16 bc;
6382         int an_len;
6383         const char *an;
6384         smb_info_t *si = pinfo->private_data;
6385
6386         WORD_COUNT;
6387
6388         wleft = wc;     /* this is at least 1 */
6389
6390         /* next smb command */
6391         cmd = tvb_get_guint8(tvb, offset);
6392         if(cmd!=0xff){
6393                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6394         } else {
6395                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6396         }
6397         offset += 1;
6398
6399         /* reserved byte */
6400         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6401         offset += 1;
6402
6403         wleft--;
6404         if (wleft == 0)
6405                 goto bytecount;
6406
6407         /* andxoffset */
6408         andxoffset = tvb_get_letohs(tvb, offset);
6409         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6410         offset += 2;
6411         wleft--;
6412         if (wleft == 0)
6413                 goto bytecount;
6414
6415         /* flags */
6416         offset = dissect_connect_support_bits(tvb, tree, offset);
6417         wleft--;
6418
6419         /* XXX - I've seen captures where this is 7, but I have no
6420            idea how to dissect it.  I'm guessing the third word
6421            contains connect support bits, which looks plausible
6422            from the values I've seen. */
6423
6424         while (wleft != 0) {
6425                 proto_tree_add_text(tree, tvb, offset, 2,
6426                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6427                 offset += 2;
6428                 wleft--;
6429         }
6430
6431         BYTE_COUNT;
6432
6433         /*
6434          * NOTE: even though the SNIA CIFS spec doesn't say there's
6435          * a "Service" string if there's a word count of 2, the
6436          * document at
6437          *
6438          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6439          *
6440          * (it's in an ugly format - text intended to be sent to a
6441          * printer, with backspaces and overstrikes used for boldfacing
6442          * and underlining; UNIX "col -b" can be used to strip the
6443          * overstrikes out) says there's a "Service" string there, and
6444          * some network traffic has it.
6445          */
6446
6447         /*
6448          * NOTE: the Service string is always ASCII, even if the
6449          * "strings are Unicode" bit is set in the flags2 field
6450          * of the SMB.
6451          */
6452
6453         /* Service */
6454         /* XXX - what if this runs past bc? */
6455         an_len = tvb_strsize(tvb, offset);
6456         CHECK_BYTE_COUNT(an_len);
6457         an = tvb_get_ptr(tvb, offset, an_len);
6458         proto_tree_add_string(tree, hf_smb_service, tvb,
6459                 offset, an_len, an);
6460         COUNT_BYTES(an_len);
6461
6462         /* Now when we know the service type, store it so that we know it for later commands down
6463            this tree */
6464         if(!pinfo->fd->flags.visited){
6465                 /* Remove any previous entry for this TID */
6466                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6467                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6468                 }
6469                 if(strcmp(an,"IPC") == 0){
6470                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6471                 } else {
6472                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6473                 }
6474         }
6475
6476
6477         if(wc==3){
6478                 if (bc != 0) {
6479                         /*
6480                          * Sometimes this isn't present.
6481                          */
6482
6483                         /* Native FS */
6484                         an = get_unicode_or_ascii_string(tvb, &offset,
6485                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6486                                 &bc);
6487                         if (an == NULL)
6488                                 goto endofcommand;
6489                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6490                                 offset, an_len, an);
6491                         COUNT_BYTES(an_len);
6492                 }
6493         }
6494
6495         END_OF_SMB
6496
6497         /* call AndXCommand (if there are any) */
6498         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6499
6500         return offset;
6501 }
6502
6503
6504
6505 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6506    NT Transaction command  begins here
6507    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6508 #define NT_TRANS_CREATE         1
6509 #define NT_TRANS_IOCTL          2
6510 #define NT_TRANS_SSD            3
6511 #define NT_TRANS_NOTIFY         4
6512 #define NT_TRANS_RENAME         5
6513 #define NT_TRANS_QSD            6
6514 #define NT_TRANS_GET_USER_QUOTA 7
6515 #define NT_TRANS_SET_USER_QUOTA 8
6516 const value_string nt_cmd_vals[] = {
6517         {NT_TRANS_CREATE,               "NT CREATE"},
6518         {NT_TRANS_IOCTL,                "NT IOCTL"},
6519         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6520         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6521         {NT_TRANS_RENAME,               "NT RENAME"},
6522         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6523         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6524         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6525         {0, NULL}
6526 };
6527
6528 static const value_string nt_ioctl_isfsctl_vals[] = {
6529         {0,     "Device IOCTL"},
6530         {1,     "FS control : FSCTL"},
6531         {0, NULL}
6532 };
6533
6534 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6535 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6536         "Apply the command to share root handle (MUST BE Dfs)",
6537         "Apply to this share",
6538 };
6539
6540 static const value_string nt_notify_action_vals[] = {
6541         {1,     "ADDED (object was added"},
6542         {2,     "REMOVED (object was removed)"},
6543         {3,     "MODIFIED (object was modified)"},
6544         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6545         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6546         {6,     "ADDED_STREAM (a stream was added)"},
6547         {7,     "REMOVED_STREAM (a stream was removed)"},
6548         {8,     "MODIFIED_STREAM (a stream was modified)"},
6549         {0, NULL}
6550 };
6551
6552 static const value_string watch_tree_vals[] = {
6553         {0,     "Current directory only"},
6554         {1,     "Subdirectories also"},
6555         {0, NULL}
6556 };
6557
6558 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6559 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6560 #define NT_NOTIFY_STREAM_NAME   0x00000200
6561 #define NT_NOTIFY_SECURITY      0x00000100
6562 #define NT_NOTIFY_EA            0x00000080
6563 #define NT_NOTIFY_CREATION      0x00000040
6564 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6565 #define NT_NOTIFY_LAST_WRITE    0x00000010
6566 #define NT_NOTIFY_SIZE          0x00000008
6567 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6568 #define NT_NOTIFY_DIR_NAME      0x00000002
6569 #define NT_NOTIFY_FILE_NAME     0x00000001
6570 static const true_false_string tfs_nt_notify_stream_write = {
6571         "Notify on changes to STREAM WRITE",
6572         "Do NOT notify on changes to stream write",
6573 };
6574 static const true_false_string tfs_nt_notify_stream_size = {
6575         "Notify on changes to STREAM SIZE",
6576         "Do NOT notify on changes to stream size",
6577 };
6578 static const true_false_string tfs_nt_notify_stream_name = {
6579         "Notify on changes to STREAM NAME",
6580         "Do NOT notify on changes to stream name",
6581 };
6582 static const true_false_string tfs_nt_notify_security = {
6583         "Notify on changes to SECURITY",
6584         "Do NOT notify on changes to security",
6585 };
6586 static const true_false_string tfs_nt_notify_ea = {
6587         "Notify on changes to EA",
6588         "Do NOT notify on changes to EA",
6589 };
6590 static const true_false_string tfs_nt_notify_creation = {
6591         "Notify on changes to CREATION TIME",
6592         "Do NOT notify on changes to creation time",
6593 };
6594 static const true_false_string tfs_nt_notify_last_access = {
6595         "Notify on changes to LAST ACCESS TIME",
6596         "Do NOT notify on changes to last access time",
6597 };
6598 static const true_false_string tfs_nt_notify_last_write = {
6599         "Notify on changes to LAST WRITE TIME",
6600         "Do NOT notify on changes to last write time",
6601 };
6602 static const true_false_string tfs_nt_notify_size = {
6603         "Notify on changes to SIZE",
6604         "Do NOT notify on changes to size",
6605 };
6606 static const true_false_string tfs_nt_notify_attributes = {
6607         "Notify on changes to ATTRIBUTES",
6608         "Do NOT notify on changes to attributes",
6609 };
6610 static const true_false_string tfs_nt_notify_dir_name = {
6611         "Notify on changes to DIR NAME",
6612         "Do NOT notify on changes to dir name",
6613 };
6614 static const true_false_string tfs_nt_notify_file_name = {
6615         "Notify on changes to FILE NAME",
6616         "Do NOT notify on changes to file name",
6617 };
6618
6619 static const value_string create_disposition_vals[] = {
6620         {0,     "Supersede (supersede existing file (if it exists))"},
6621         {1,     "Open (if file exists open it, else fail)"},
6622         {2,     "Create (if file exists fail, else create it)"},
6623         {3,     "Open If (if file exists open it, else create it)"},
6624         {4,     "Overwrite (if file exists overwrite, else fail)"},
6625         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6626         {0, NULL}
6627 };
6628
6629 static const value_string impersonation_level_vals[] = {
6630         {0,     "Anonymous"},
6631         {1,     "Identification"},
6632         {2,     "Impersonation"},
6633         {3,     "Delegation"},
6634         {0, NULL}
6635 };
6636
6637 static const true_false_string tfs_nt_security_flags_context_tracking = {
6638         "Security tracking mode is DYNAMIC",
6639         "Security tracking mode is STATIC",
6640 };
6641
6642 static const true_false_string tfs_nt_security_flags_effective_only = {
6643         "ONLY ENABLED aspects of the client's security context are available",
6644         "ALL aspects of the client's security context are available",
6645 };
6646
6647 static const true_false_string tfs_nt_create_bits_oplock = {
6648         "Requesting OPLOCK",
6649         "Does NOT request oplock"
6650 };
6651
6652 static const true_false_string tfs_nt_create_bits_boplock = {
6653         "Requesting BATCH OPLOCK",
6654         "Does NOT request batch oplock"
6655 };
6656
6657 /*
6658  * XXX - must be a directory, and can be a file, or can be a directory,
6659  * and must be a file?
6660  */
6661 static const true_false_string tfs_nt_create_bits_dir = {
6662         "Target of open MUST be a DIRECTORY",
6663         "Target of open can be a file"
6664 };
6665
6666 static const true_false_string tfs_nt_create_bits_ext_resp = {
6667   "Extended responses required",
6668   "Extended responses NOT required"
6669 };
6670
6671 static const true_false_string tfs_nt_access_mask_generic_read = {
6672         "GENERIC READ is set",
6673         "Generic read is NOT set"
6674 };
6675 static const true_false_string tfs_nt_access_mask_generic_write = {
6676         "GENERIC WRITE is set",
6677         "Generic write is NOT set"
6678 };
6679 static const true_false_string tfs_nt_access_mask_generic_execute = {
6680         "GENERIC EXECUTE is set",
6681         "Generic execute is NOT set"
6682 };
6683 static const true_false_string tfs_nt_access_mask_generic_all = {
6684         "GENERIC ALL is set",
6685         "Generic all is NOT set"
6686 };
6687 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6688         "MAXIMUM ALLOWED is set",
6689         "Maximum allowed is NOT set"
6690 };
6691 static const true_false_string tfs_nt_access_mask_system_security = {
6692         "SYSTEM SECURITY is set",
6693         "System security is NOT set"
6694 };
6695 static const true_false_string tfs_nt_access_mask_synchronize = {
6696         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6697         "Can NOT wait on handle to synchronize on completion of I/O"
6698 };
6699 static const true_false_string tfs_nt_access_mask_write_owner = {
6700         "Can WRITE OWNER (take ownership)",
6701         "Can NOT write owner (take ownership)"
6702 };
6703 static const true_false_string tfs_nt_access_mask_write_dac = {
6704         "OWNER may WRITE the DAC",
6705         "Owner may NOT write to the DAC"
6706 };
6707 static const true_false_string tfs_nt_access_mask_read_control = {
6708         "READ ACCESS to owner, group and ACL of the SID",
6709         "Read access is NOT granted to owner, group and ACL of the SID"
6710 };
6711 static const true_false_string tfs_nt_access_mask_delete = {
6712         "DELETE access",
6713         "NO delete access"
6714 };
6715 static const true_false_string tfs_nt_access_mask_write_attributes = {
6716         "WRITE ATTRIBUTES access",
6717         "NO write attributes access"
6718 };
6719 static const true_false_string tfs_nt_access_mask_read_attributes = {
6720         "READ ATTRIBUTES access",
6721         "NO read attributes access"
6722 };
6723 static const true_false_string tfs_nt_access_mask_delete_child = {
6724         "DELETE CHILD access",
6725         "NO delete child access"
6726 };
6727 static const true_false_string tfs_nt_access_mask_execute = {
6728         "EXECUTE access",
6729         "NO execute access"
6730 };
6731 static const true_false_string tfs_nt_access_mask_write_ea = {
6732         "WRITE EXTENDED ATTRIBUTES access",
6733         "NO write extended attributes access"
6734 };
6735 static const true_false_string tfs_nt_access_mask_read_ea = {
6736         "READ EXTENDED ATTRIBUTES access",
6737         "NO read extended attributes access"
6738 };
6739 static const true_false_string tfs_nt_access_mask_append = {
6740         "APPEND access",
6741         "NO append access"
6742 };
6743 static const true_false_string tfs_nt_access_mask_write = {
6744         "WRITE access",
6745         "NO write access"
6746 };
6747 static const true_false_string tfs_nt_access_mask_read = {
6748         "READ access",
6749         "NO read access"
6750 };
6751
6752 static const true_false_string tfs_nt_share_access_delete = {
6753         "Object can be shared for DELETE",
6754         "Object can NOT be shared for delete"
6755 };
6756 static const true_false_string tfs_nt_share_access_write = {
6757         "Object can be shared for WRITE",
6758         "Object can NOT be shared for write"
6759 };
6760 static const true_false_string tfs_nt_share_access_read = {
6761         "Object can be shared for READ",
6762         "Object can NOT be shared for read"
6763 };
6764
6765 static const value_string oplock_level_vals[] = {
6766         {0,     "No oplock granted"},
6767         {1,     "Exclusive oplock granted"},
6768         {2,     "Batch oplock granted"},
6769         {3,     "Level II oplock granted"},
6770         {0, NULL}
6771 };
6772
6773 static const value_string device_type_vals[] = {
6774         {0x00000001,    "Beep"},
6775         {0x00000002,    "CDROM"},
6776         {0x00000003,    "CDROM Filesystem"},
6777         {0x00000004,    "Controller"},
6778         {0x00000005,    "Datalink"},
6779         {0x00000006,    "Dfs"},
6780         {0x00000007,    "Disk"},
6781         {0x00000008,    "Disk Filesystem"},
6782         {0x00000009,    "Filesystem"},
6783         {0x0000000a,    "Inport Port"},
6784         {0x0000000b,    "Keyboard"},
6785         {0x0000000c,    "Mailslot"},
6786         {0x0000000d,    "MIDI-In"},
6787         {0x0000000e,    "MIDI-Out"},
6788         {0x0000000f,    "Mouse"},
6789         {0x00000010,    "Multi UNC Provider"},
6790         {0x00000011,    "Named Pipe"},
6791         {0x00000012,    "Network"},
6792         {0x00000013,    "Network Browser"},
6793         {0x00000014,    "Network Filesystem"},
6794         {0x00000015,    "NULL"},
6795         {0x00000016,    "Parallel Port"},
6796         {0x00000017,    "Physical card"},
6797         {0x00000018,    "Printer"},
6798         {0x00000019,    "Scanner"},
6799         {0x0000001a,    "Serial Mouse port"},
6800         {0x0000001b,    "Serial port"},
6801         {0x0000001c,    "Screen"},
6802         {0x0000001d,    "Sound"},
6803         {0x0000001e,    "Streams"},
6804         {0x0000001f,    "Tape"},
6805         {0x00000020,    "Tape Filesystem"},
6806         {0x00000021,    "Transport"},
6807         {0x00000022,    "Unknown"},
6808         {0x00000023,    "Video"},
6809         {0x00000024,    "Virtual Disk"},
6810         {0x00000025,    "WAVE-In"},
6811         {0x00000026,    "WAVE-Out"},
6812         {0x00000027,    "8042 Port"},
6813         {0x00000028,    "Network Redirector"},
6814         {0x00000029,    "Battery"},
6815         {0x0000002a,    "Bus Extender"},
6816         {0x0000002b,    "Modem"},
6817         {0x0000002c,    "VDM"},
6818         {0,     NULL}
6819 };
6820
6821 static const value_string is_directory_vals[] = {
6822         {0,     "This is NOT a directory"},
6823         {1,     "This is a DIRECTORY"},
6824         {0, NULL}
6825 };
6826
6827 typedef struct _nt_trans_data {
6828         int subcmd;
6829         guint32 sd_len;
6830         guint32 ea_len;
6831 } nt_trans_data;
6832
6833
6834
6835 static int
6836 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6837 {
6838         guint8 mask;
6839         proto_item *item = NULL;
6840         proto_tree *tree = NULL;
6841
6842         mask = tvb_get_guint8(tvb, offset);
6843
6844         if(parent_tree){
6845                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6846                         "Security Flags: 0x%02x", mask);
6847                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6848         }
6849
6850         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6851                 tvb, offset, 1, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6853                 tvb, offset, 1, mask);
6854
6855         offset += 1;
6856
6857         return offset;
6858 }
6859
6860 static int
6861 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6862 {
6863         guint32 mask;
6864         proto_item *item = NULL;
6865         proto_tree *tree = NULL;
6866
6867         mask = tvb_get_letohl(tvb, offset);
6868
6869         if(parent_tree){
6870                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6871                         "Share Access: 0x%08x", mask);
6872                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6873         }
6874
6875         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6876                 tvb, offset, 4, mask);
6877         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6878                 tvb, offset, 4, mask);
6879         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6880                 tvb, offset, 4, mask);
6881
6882         offset += 4;
6883
6884         return offset;
6885 }
6886
6887 /* FIXME: need to call dissect_nt_access_mask() instead */
6888
6889 static int
6890 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6891 {
6892         guint32 mask;
6893         proto_item *item = NULL;
6894         proto_tree *tree = NULL;
6895
6896         mask = tvb_get_letohl(tvb, offset);
6897
6898         if(parent_tree){
6899                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6900                         "Access Mask: 0x%08x", mask);
6901                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6902         }
6903
6904         /*
6905          * Some of these bits come from
6906          *
6907          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6908          *
6909          * and others come from the section on ZwOpenFile in "Windows(R)
6910          * NT(R)/2000 Native API Reference".
6911          */
6912         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6913                 tvb, offset, 4, mask);
6914         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6915                 tvb, offset, 4, mask);
6916         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6917                 tvb, offset, 4, mask);
6918         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6919                 tvb, offset, 4, mask);
6920         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6921                 tvb, offset, 4, mask);
6922         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6923                 tvb, offset, 4, mask);
6924         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6925                 tvb, offset, 4, mask);
6926         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6927                 tvb, offset, 4, mask);
6928         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6929                 tvb, offset, 4, mask);
6930         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6931                 tvb, offset, 4, mask);
6932         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6933                 tvb, offset, 4, mask);
6934         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6935                 tvb, offset, 4, mask);
6936         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6937                 tvb, offset, 4, mask);
6938         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6939                 tvb, offset, 4, mask);
6940         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6941                 tvb, offset, 4, mask);
6942         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6943                 tvb, offset, 4, mask);
6944         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6945                 tvb, offset, 4, mask);
6946         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6947                 tvb, offset, 4, mask);
6948         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6949                 tvb, offset, 4, mask);
6950         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6951                 tvb, offset, 4, mask);
6952
6953         offset += 4;
6954
6955         return offset;
6956 }
6957
6958 static int
6959 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6960 {
6961         guint32 mask;
6962         proto_item *item = NULL;
6963         proto_tree *tree = NULL;
6964
6965         mask = tvb_get_letohl(tvb, offset);
6966
6967         if(parent_tree){
6968                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6969                         "Create Flags: 0x%08x", mask);
6970                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6971         }
6972
6973         /*
6974          * XXX - it's 0x00000016 in at least one capture, but
6975          * Network Monitor doesn't say what the 0x00000010 bit is.
6976          * Does the Win32 API documentation, or NT Native API book,
6977          * suggest anything?
6978          *
6979          * That is the extended response desired bit ... RJS, from Samba
6980          * Well, maybe. Samba thinks it is, and uses it to encode
6981          * OpLock granted as the high order bit of the Action field
6982          * in the response. However, Windows does not do that. Or at least
6983          * Win2K doesn't.
6984          */
6985         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6986                                tvb, offset, 4, mask);
6987         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6988                 tvb, offset, 4, mask);
6989         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6990                 tvb, offset, 4, mask);
6991         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6992                 tvb, offset, 4, mask);
6993
6994         offset += 4;
6995
6996         return offset;
6997 }
6998
6999 /*
7000  * XXX - there are some more flags in the description of "ZwOpenFile()"
7001  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
7002  * the wire as well?  (The spec at
7003  *
7004  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7005  *
7006  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
7007  * via the SMB protocol.  The NT redirector should convert this option
7008  * to FILE_WRITE_THROUGH."
7009  *
7010  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
7011  * values one would infer from their position in the list of flags for
7012  * "ZwOpenFile()".  Most of the others probably have those values
7013  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
7014  * which might go over the wire (for the benefit of backup/restore software).
7015  */
7016 static const true_false_string tfs_nt_create_options_directory = {
7017         "File being created/opened must be a directory",
7018         "File being created/opened must not be a directory"
7019 };
7020 static const true_false_string tfs_nt_create_options_write_through = {
7021         "Writes should flush buffered data before completing",
7022         "Writes need not flush buffered data before completing"
7023 };
7024 static const true_false_string tfs_nt_create_options_sequential_only = {
7025         "The file will only be accessed sequentially",
7026         "The file might not only be accessed sequentially"
7027 };
7028 static const true_false_string tfs_nt_create_options_sync_io_alert = {
7029         "All operations SYNCHRONOUS, waits subject to termination from alert",
7030         "Operations NOT necessarily synchronous"
7031 };
7032 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
7033         "All operations SYNCHRONOUS, waits not subject to alert",
7034         "Operations NOT necessarily synchronous"
7035 };
7036 static const true_false_string tfs_nt_create_options_non_directory = {
7037         "File being created/opened must not be a directory",
7038         "File being created/opened must be a directory"
7039 };
7040 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
7041         "The client does not understand extended attributes",
7042         "The client understands extended attributes"
7043 };
7044 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
7045         "The client understands only 8.3 file names",
7046         "The client understands long file names"
7047 };
7048 static const true_false_string tfs_nt_create_options_random_access = {
7049         "The file will be accessed randomly",
7050         "The file will not be accessed randomly"
7051 };
7052 static const true_false_string tfs_nt_create_options_delete_on_close = {
7053         "The file should be deleted when it is closed",
7054         "The file should not be deleted when it is closed"
7055 };
7056
7057 static int
7058 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7059 {
7060         guint32 mask;
7061         proto_item *item = NULL;
7062         proto_tree *tree = NULL;
7063
7064         mask = tvb_get_letohl(tvb, offset);
7065
7066         if(parent_tree){
7067                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7068                         "Create Options: 0x%08x", mask);
7069                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
7070         }
7071
7072         /*
7073          * From
7074          *
7075          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7076          */
7077         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
7078                 tvb, offset, 4, mask);
7079         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
7080                 tvb, offset, 4, mask);
7081         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
7082                 tvb, offset, 4, mask);
7083         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
7084                 tvb, offset, 4, mask);
7085         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
7086                 tvb, offset, 4, mask);
7087         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
7088                 tvb, offset, 4, mask);
7089         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
7090                 tvb, offset, 4, mask);
7091         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
7092                 tvb, offset, 4, mask);
7093         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
7094                 tvb, offset, 4, mask);
7095         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
7096                 tvb, offset, 4, mask);
7097
7098         offset += 4;
7099
7100         return offset;
7101 }
7102
7103 static int
7104 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7105 {
7106         guint32 mask;
7107         proto_item *item = NULL;
7108         proto_tree *tree = NULL;
7109
7110         mask = tvb_get_letohl(tvb, offset);
7111
7112         if(parent_tree){
7113                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7114                         "Completion Filter: 0x%08x", mask);
7115                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7116         }
7117
7118         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7119                 tvb, offset, 4, mask);
7120         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7121                 tvb, offset, 4, mask);
7122         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7123                 tvb, offset, 4, mask);
7124         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7125                 tvb, offset, 4, mask);
7126         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7127                 tvb, offset, 4, mask);
7128         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7129                 tvb, offset, 4, mask);
7130         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7131                 tvb, offset, 4, mask);
7132         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7133                 tvb, offset, 4, mask);
7134         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7135                 tvb, offset, 4, mask);
7136         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7137                 tvb, offset, 4, mask);
7138         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7139                 tvb, offset, 4, mask);
7140         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7141                 tvb, offset, 4, mask);
7142
7143         offset += 4;
7144         return offset;
7145 }
7146
7147 static int
7148 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7149 {
7150         guint8 mask;
7151         proto_item *item = NULL;
7152         proto_tree *tree = NULL;
7153
7154         mask = tvb_get_guint8(tvb, offset);
7155
7156         if(parent_tree){
7157                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7158                         "Completion Filter: 0x%02x", mask);
7159                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7160         }
7161
7162         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7163                 tvb, offset, 1, mask);
7164
7165         offset += 1;
7166         return offset;
7167 }
7168
7169 /*
7170  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7171  * Native API Reference".
7172  */
7173 static const true_false_string tfs_nt_qsd_owner = {
7174         "Requesting OWNER security information",
7175         "NOT requesting owner security information",
7176 };
7177
7178 static const true_false_string tfs_nt_qsd_group = {
7179         "Requesting GROUP security information",
7180         "NOT requesting group security information",
7181 };
7182
7183 static const true_false_string tfs_nt_qsd_dacl = {
7184         "Requesting DACL security information",
7185         "NOT requesting DACL security information",
7186 };
7187
7188 static const true_false_string tfs_nt_qsd_sacl = {
7189         "Requesting SACL security information",
7190         "NOT requesting SACL security information",
7191 };
7192
7193 #define NT_QSD_OWNER    0x00000001
7194 #define NT_QSD_GROUP    0x00000002
7195 #define NT_QSD_DACL     0x00000004
7196 #define NT_QSD_SACL     0x00000008
7197
7198 static int
7199 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7200 {
7201         guint32 mask;
7202         proto_item *item = NULL;
7203         proto_tree *tree = NULL;
7204
7205         mask = tvb_get_letohl(tvb, offset);
7206
7207         if(parent_tree){
7208                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7209                         "Security Information: 0x%08x", mask);
7210                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7211         }
7212
7213         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7214                 tvb, offset, 4, mask);
7215         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7216                 tvb, offset, 4, mask);
7217         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7218                 tvb, offset, 4, mask);
7219         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7220                 tvb, offset, 4, mask);
7221
7222         offset += 4;
7223
7224         return offset;
7225 }
7226
7227 static void
7228 free_g_string(void *arg)
7229 {
7230         g_string_free(arg, TRUE);
7231 }
7232
7233 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7234    the SID in the 'sid_str' parameter which must be freed by the caller.
7235    hf_sid can be -1 if the caller doesnt care what name is used and then 
7236    "smb.sid" will be the default instead. If the caller wants a more
7237    appropriate hf field, it will just pass a FT_STRING hf field here
7238 */
7239
7240 int
7241 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7242                char **sid_str, int hf_sid)
7243 {
7244         proto_item *item = NULL;
7245         proto_tree *tree = NULL;
7246         int old_offset = offset, sa_offset = offset;
7247         gboolean rid_present;
7248         guint rid=0;
7249         int rid_offset=0;
7250         guint8 revision;
7251         int rev_offset;
7252         guint8 num_auth;
7253         int na_offset;
7254         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7255         int i;
7256         GString *gstr;
7257         char sid_string[245];
7258         char *sid_name;
7259
7260         if(hf_sid==-1){
7261                 hf_sid=hf_smb_sid;
7262         }
7263
7264         /* revision of sid */
7265         revision = tvb_get_guint8(tvb, offset);
7266         rev_offset = offset;
7267         offset += 1;
7268
7269         switch(revision){
7270         case 1:
7271         case 2:  /* Not sure what the different revision numbers mean */
7272           /* number of authorities*/
7273           num_auth = tvb_get_guint8(tvb, offset);
7274           na_offset = offset;
7275           offset += 1;
7276
7277           /* XXX perhaps we should have these thing searchable?
7278              a new FT_xxx thingie? SMB is quite common!*/
7279           /* identifier authorities */
7280
7281           for(i=0;i<6;i++){
7282             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7283
7284             offset++;
7285           }
7286
7287           sa_offset = offset;
7288
7289           gstr = g_string_new("");
7290
7291           CLEANUP_PUSH(free_g_string, gstr);
7292
7293           /* sub authorities, leave RID to last */
7294           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7295             /*
7296              * XXX should not be letohl but native byteorder according to
7297              * Samba header files.
7298              *
7299              * However, considering that there were never any NT ports
7300              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7301              * and IA-64 runs little-endian, as does x86-64), we can (?)
7302              * assume that non le byte encodings will be "uncommon"?
7303              */
7304              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7305                   tvb_get_letohl(tvb, offset));
7306              offset+=4;
7307           }
7308
7309
7310           if (num_auth > 4) {
7311             rid = tvb_get_letohl(tvb, offset);
7312             rid_present=TRUE;
7313             rid_offset=offset;
7314             offset+=4;
7315             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7316           } else {
7317             rid_present=FALSE;
7318             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7319           }
7320
7321           sid_name=NULL;
7322           if(sid_name_snooping){
7323             sid_name=find_sid_name(sid_string);
7324           }
7325
7326           if(parent_tree){
7327             if(sid_name){
7328               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s (%s)", name, sid_string, sid_name);
7329             } else {
7330               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7331             }
7332             tree = proto_item_add_subtree(item, ett_smb_sid);
7333           }
7334
7335           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7336           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7337           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7338           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7339
7340           if(rid_present){
7341             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7342           }
7343
7344           if(sid_str){
7345             if(sid_name){
7346               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7347             } else {
7348               *sid_str = g_strdup(sid_string);
7349             }
7350           }
7351
7352           CLEANUP_CALL_AND_POP;
7353         }
7354
7355
7356         return offset;
7357 }
7358
7359
7360 static const value_string ace_type_vals[] = {
7361   { 0, "Access Allowed"},
7362   { 1, "Access Denied"},
7363   { 2, "System Audit"},
7364   { 3, "System Alarm"},
7365   { 0, NULL}
7366 };
7367 static const true_false_string tfs_ace_flags_object_inherit = {
7368   "Subordinate files will inherit this ACE",
7369   "Subordinate files will not inherit this ACE"
7370 };
7371 static const true_false_string tfs_ace_flags_container_inherit = {
7372   "Subordinate containers will inherit this ACE",
7373   "Subordinate containers will not inherit this ACE"
7374 };
7375 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7376   "Subordinate object will not propagate the inherited ACE further",
7377   "Subordinate object will propagate the inherited ACE further"
7378 };
7379 static const true_false_string tfs_ace_flags_inherit_only = {
7380   "This ACE does not apply to the current object",
7381   "This ACE applies to the current object"
7382 };
7383 static const true_false_string tfs_ace_flags_inherited_ace = {
7384   "This ACE was inherited from its parent object",
7385   "This ACE was not inherited from its parent object"
7386 };
7387 static const true_false_string tfs_ace_flags_successful_access = {
7388   "Successful accesses will be audited",
7389   "Successful accesses will not be audited"
7390 };
7391 static const true_false_string tfs_ace_flags_failed_access = {
7392   "Failed accesses will be audited",
7393   "Failed accesses will not be audited"
7394 };
7395
7396 #define APPEND_ACE_TEXT(flag, item, string) \
7397         if(flag){                                                       \
7398                 if(item)                                                \
7399                         proto_item_append_text(item, string, sep);      \
7400                 sep = ", ";                                             \
7401         }
7402
7403 static int
7404 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7405                         guint8 *data)
7406 {
7407         proto_item *item = NULL;
7408         proto_tree *tree = NULL;
7409         guint8 mask;
7410         char *sep = " ";
7411
7412         mask = tvb_get_guint8(tvb, offset);
7413
7414         if (data)
7415                 *data = mask;
7416
7417
7418         if(parent_tree){
7419                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7420                                            "NT ACE Flags: 0x%02x", mask);
7421                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7422         }
7423
7424         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7425                        tvb, offset, 1, mask);
7426         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7427
7428         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7429                        tvb, offset, 1, mask);
7430         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7431
7432         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7433                        tvb, offset, 1, mask);
7434         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7435
7436         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7437                        tvb, offset, 1, mask);
7438         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7439
7440         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7441                        tvb, offset, 1, mask);
7442         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7443
7444         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7445                        tvb, offset, 1, mask);
7446         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7447
7448         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7449                        tvb, offset, 1, mask);
7450         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7451
7452
7453         offset += 1;
7454         return offset;
7455 }
7456
7457 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7458
7459 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7460
7461 */
7462
7463 static gint ett_nt_access_mask = -1;
7464 static gint ett_nt_access_mask_generic = -1;
7465 static gint ett_nt_access_mask_standard = -1;
7466 static gint ett_nt_access_mask_specific = -1;
7467
7468 static int hf_access_sacl = -1;
7469 static int hf_access_maximum_allowed = -1;
7470 static int hf_access_generic_read = -1;
7471 static int hf_access_generic_write = -1;
7472 static int hf_access_generic_execute = -1;
7473 static int hf_access_generic_all = -1;
7474 static int hf_access_standard_delete = -1;
7475 static int hf_access_standard_read_control = -1;
7476 static int hf_access_standard_synchronise = -1;
7477 static int hf_access_standard_write_dac = -1;
7478 static int hf_access_standard_write_owner = -1;
7479 static int hf_access_specific_15 = -1;
7480 static int hf_access_specific_14 = -1;
7481 static int hf_access_specific_13 = -1;
7482 static int hf_access_specific_12 = -1;
7483 static int hf_access_specific_11 = -1;
7484 static int hf_access_specific_10 = -1;
7485 static int hf_access_specific_9 = -1;
7486 static int hf_access_specific_8 = -1;
7487 static int hf_access_specific_7 = -1;
7488 static int hf_access_specific_6 = -1;
7489 static int hf_access_specific_5 = -1;
7490 static int hf_access_specific_4 = -1;
7491 static int hf_access_specific_3 = -1;
7492 static int hf_access_specific_2 = -1;
7493 static int hf_access_specific_1 = -1;
7494 static int hf_access_specific_0 = -1;
7495
7496 /* Map generic permissions to specific permissions */
7497
7498 static void map_generic_access(guint32 *access_mask, 
7499                                struct generic_mapping *mapping)
7500 {
7501         if (*access_mask & GENERIC_READ_ACCESS) {
7502                 *access_mask &= ~GENERIC_READ_ACCESS;
7503                 *access_mask |= mapping->generic_read;
7504         }
7505
7506         if (*access_mask & GENERIC_WRITE_ACCESS) {
7507                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7508                 *access_mask |= mapping->generic_write;
7509         }
7510
7511         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7512                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7513                 *access_mask |= mapping->generic_execute;
7514         }
7515
7516         if (*access_mask & GENERIC_ALL_ACCESS) {
7517                 *access_mask &= ~GENERIC_ALL_ACCESS;
7518                 *access_mask |= mapping->generic_all;
7519         }
7520 }
7521
7522 /* Map standard permissions to specific permissions */
7523
7524 static void map_standard_access(guint32 *access_mask,
7525                                 struct standard_mapping *mapping)
7526 {
7527         if (*access_mask & READ_CONTROL_ACCESS) {
7528                 *access_mask &= ~READ_CONTROL_ACCESS;
7529                 *access_mask |= mapping->std_read;
7530         }
7531
7532         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7533                             SYNCHRONIZE_ACCESS)) {
7534                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7535                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7536                 *access_mask |= mapping->std_all;
7537         }
7538
7539 }
7540
7541 int
7542 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7543                        proto_tree *tree, guint8 *drep, int hfindex,
7544                        struct access_mask_info *ami, guint32 *perms)
7545 {
7546         proto_item *item;
7547         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7548         guint32 access;
7549
7550         if (drep != NULL) {
7551                 /*
7552                  * Called from a DCE RPC protocol dissector, for a
7553                  * protocol where a 32-bit NDR integer contains
7554                  * an NT access mask; extract the access mask
7555                  * with an NDR call.
7556                  */
7557                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7558                                             hfindex, &access);
7559         } else {
7560                 /*
7561                  * Called from SMB, where the access mask is just a
7562                  * 4-byte little-endian quantity with no special
7563                  * NDR alignment requirement; extract it with
7564                  * "tvb_get_letohl()".
7565                  */
7566                 access = tvb_get_letohl(tvb, offset);
7567                 offset += 4;
7568         }
7569
7570         if (perms) {
7571           *perms = access;
7572         }
7573
7574         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7575
7576         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7577
7578         /* Generic access rights */
7579
7580         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7581                                    "Generic rights: 0x%08x",
7582                                    access & GENERIC_RIGHTS_MASK);
7583
7584         generic_tree = proto_item_add_subtree(
7585                 item, ett_nt_access_mask_generic);
7586
7587         proto_tree_add_boolean(
7588                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7589                 access);
7590
7591         proto_tree_add_boolean(
7592                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7593                 access);
7594
7595         proto_tree_add_boolean(
7596                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7597                 access);
7598
7599         proto_tree_add_boolean(
7600                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7601                 access);
7602
7603         /* Reserved (??) */
7604
7605         proto_tree_add_boolean(
7606                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7607                 access);
7608
7609         /* Access system security */
7610
7611         proto_tree_add_boolean(
7612                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7613                 access);
7614
7615         /* Standard access rights */
7616
7617         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7618                                    "Standard rights: 0x%08x",
7619                                    access & STANDARD_RIGHTS_MASK);
7620
7621         standard_tree = proto_item_add_subtree(
7622                 item, ett_nt_access_mask_standard);
7623
7624         proto_tree_add_boolean(
7625                 standard_tree, hf_access_standard_synchronise, tvb, 
7626                 offset - 4, 4, access);
7627
7628         proto_tree_add_boolean(
7629                 standard_tree, hf_access_standard_write_owner, tvb, 
7630                 offset - 4, 4, access);
7631
7632         proto_tree_add_boolean(
7633                 standard_tree, hf_access_standard_write_dac, tvb, 
7634                 offset - 4, 4, access);
7635
7636         proto_tree_add_boolean(
7637                 standard_tree, hf_access_standard_read_control, tvb, 
7638                 offset - 4, 4, access);
7639
7640         proto_tree_add_boolean(
7641                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7642                 access);
7643
7644         /* Specific access rights.  Call the specific_rights_fn
7645            pointer if we have one, otherwise just display bits 0-15 in
7646            boring fashion. */
7647
7648         if (ami && ami->specific_rights_name)
7649                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7650                                            "%s specific rights: 0x%08x",
7651                                            ami->specific_rights_name,
7652                                            access & SPECIFIC_RIGHTS_MASK);
7653         else
7654                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7655                                            "Specific rights: 0x%08x",
7656                                            access & SPECIFIC_RIGHTS_MASK);
7657
7658         specific_tree = proto_item_add_subtree(
7659                 item, ett_nt_access_mask_specific);
7660
7661         if (ami && ami->specific_rights_fn) {
7662                 guint32 mapped_access = access;
7663                 proto_tree *specific_mapped;
7664
7665                 specific_mapped = proto_item_add_subtree(
7666                         item, ett_nt_access_mask_specific);
7667
7668                 ami->specific_rights_fn(
7669                         tvb, offset - 4, specific_tree, access);
7670
7671                 if (ami->generic_mapping)
7672                         map_generic_access(&access, ami->generic_mapping);
7673                 
7674                 if (ami->standard_mapping)
7675                         map_standard_access(&access, ami->standard_mapping);
7676
7677                 if (access != mapped_access) {
7678                         ami->specific_rights_fn(
7679                                 tvb, offset - 4, specific_mapped, 
7680                                 mapped_access);
7681                 }
7682                 
7683                 return offset;
7684         }
7685
7686         proto_tree_add_boolean(
7687                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7688                 access);
7689
7690         proto_tree_add_boolean(
7691                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7692                 access);
7693
7694         proto_tree_add_boolean(
7695                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7696                 access);
7697
7698         proto_tree_add_boolean(
7699                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7700                 access);
7701
7702         proto_tree_add_boolean(
7703                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7704                 access);
7705
7706         proto_tree_add_boolean(
7707                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7708                 access);
7709
7710         proto_tree_add_boolean(
7711                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7712                 access);
7713
7714         proto_tree_add_boolean(
7715                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7716                 access);
7717
7718         proto_tree_add_boolean(
7719                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7720                 access);
7721
7722         proto_tree_add_boolean(
7723                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7724                 access);
7725
7726         proto_tree_add_boolean(
7727                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7728                 access);
7729
7730         proto_tree_add_boolean(
7731                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7732                 access);
7733
7734         proto_tree_add_boolean(
7735                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7736                 access);
7737
7738         proto_tree_add_boolean(
7739                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7740                 access);
7741
7742         proto_tree_add_boolean(
7743                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7744                 access);
7745
7746         proto_tree_add_boolean(
7747                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7748                 access);
7749
7750         return offset;
7751 }
7752
7753 static int hf_smb_access_mask = -1;
7754
7755 static int
7756 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7757                   proto_tree *parent_tree, guint8 *drep,
7758                   struct access_mask_info *ami)
7759 {
7760         proto_item *item = NULL;
7761         proto_tree *tree = NULL;
7762         int old_offset = offset;
7763         guint16 size;
7764         char *sid_str = NULL;
7765         guint8 type;
7766         guint8 flags;
7767         guint32 perms = 0;
7768
7769         if(parent_tree){
7770                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7771                                            "NT ACE: ");
7772                 tree = proto_item_add_subtree(item, ett_smb_ace);
7773         }
7774
7775         /* type */
7776         type = tvb_get_guint8(tvb, offset);
7777         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7778         offset += 1;
7779
7780         /* flags */
7781         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7782
7783         /* size */
7784         size = tvb_get_letohs(tvb, offset);
7785         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7786         offset += 2;
7787
7788         /* access mask */
7789         offset = dissect_nt_access_mask(
7790                 tvb, offset, pinfo, tree, drep, 
7791                 hf_smb_access_mask, ami, &perms);
7792
7793         /* SID */
7794         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7795
7796         if (item)
7797                 proto_item_append_text(
7798                         item, "%s, flags 0x%02x, %s, mask 0x%08x", sid_str, flags,
7799                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"),
7800                         perms);
7801
7802         g_free(sid_str);
7803
7804         proto_item_set_len(item, offset-old_offset);
7805
7806         /* Sometimes there is some spare space at the end of the ACE so use
7807            the size field to work out where the end is. */
7808
7809         return old_offset + size;
7810 }
7811
7812 static int
7813 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7814                proto_tree *parent_tree, guint8 *drep, char *name,
7815                struct access_mask_info *ami)
7816 {
7817         proto_item *item = NULL;
7818         proto_tree *tree = NULL;
7819         int old_offset = offset;
7820         guint8  revision;
7821         guint32 num_aces;
7822
7823         if(parent_tree){
7824                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7825                                            "NT %s ACL", name);
7826                 tree = proto_item_add_subtree(item, ett_smb_acl);
7827         }
7828
7829         /* revision */
7830         revision = tvb_get_guint8(tvb, offset);
7831         proto_tree_add_uint(tree, hf_smb_acl_revision,
7832                 tvb, offset, 1, revision);
7833         offset += 2;
7834
7835         switch(revision){
7836         case 2:  /* only version we will ever see of this structure?*/
7837         case 3:
7838           /* size */
7839           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7840           offset += 2;
7841
7842           /* number of ace structures */
7843           num_aces = tvb_get_letohl(tvb, offset);
7844           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7845                               tvb, offset, 4, num_aces);
7846           offset += 4;
7847
7848           while(num_aces--){
7849             offset=dissect_nt_v2_ace(
7850                     tvb, offset, pinfo, tree, drep, ami);
7851           }
7852         }
7853
7854         proto_item_set_len(item, offset-old_offset);
7855         return offset;
7856 }
7857
7858 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7859   "OWNER is DEFAULTED",
7860   "Owner is NOT defaulted"
7861 };
7862 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7863   "GROUP is DEFAULTED",
7864   "Group is NOT defaulted"
7865 };
7866 static const true_false_string tfs_sec_desc_type_dacl_present = {
7867   "DACL is PRESENT",
7868   "DACL is NOT present"
7869 };
7870 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7871   "DACL is DEFAULTED",
7872   "DACL is NOT defaulted"
7873 };
7874 static const true_false_string tfs_sec_desc_type_sacl_present = {
7875   "SACL is PRESENT",
7876   "SACL is NOT present"
7877 };
7878 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7879   "SACL is DEFAULTED",
7880   "SACL is NOT defaulted"
7881 };
7882 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7883   "DACL has AUTO INHERIT REQUIRED",
7884   "DACL does NOT require auto inherit"
7885 };
7886 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7887   "SACL has AUTO INHERIT REQUIRED",
7888   "SACL does NOT require auto inherit"
7889 };
7890 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7891   "DACL is AUTO INHERITED",
7892   "DACL is NOT auto inherited"
7893 };
7894 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7895   "SACL is AUTO INHERITED",
7896   "SACL is NOT auto inherited"
7897 };
7898 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7899   "The DACL is PROTECTED",
7900   "The DACL is NOT protected"
7901 };
7902 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7903   "The SACL is PROTECTED",
7904   "The SACL is NOT protected"
7905 };
7906 static const true_false_string tfs_sec_desc_type_self_relative = {
7907   "This SecDesc is SELF RELATIVE",
7908   "This SecDesc is NOT self relative"
7909 };
7910
7911
7912 static int
7913 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7914 {
7915         proto_item *item = NULL;
7916         proto_tree *tree = NULL;
7917         guint16 mask;
7918
7919         mask = tvb_get_letohs(tvb, offset);
7920         if(parent_tree){
7921                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7922                                            "Type: 0x%04x", mask);
7923                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7924         }
7925
7926         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7927                                tvb, offset, 2, mask);
7928         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7929                                tvb, offset, 2, mask);
7930         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7931                                tvb, offset, 2, mask);
7932         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7933                                tvb, offset, 2, mask);
7934         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7935                                tvb, offset, 2, mask);
7936         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7937                                tvb, offset, 2, mask);
7938         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7939                                tvb, offset, 2, mask);
7940         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7941                                tvb, offset, 2, mask);
7942         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7943                                tvb, offset, 2, mask);
7944         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7945                                tvb, offset, 2, mask);
7946         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7947                                tvb, offset, 2, mask);
7948         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7949                                tvb, offset, 2, mask);
7950         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7951                                tvb, offset, 2, mask);
7952
7953
7954         offset += 2;
7955         return offset;
7956 }
7957
7958 int
7959 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7960                     proto_tree *parent_tree, guint8 *drep, int len, 
7961                     struct access_mask_info *ami)
7962 {
7963         proto_item *item = NULL;
7964         proto_tree *tree = NULL;
7965         guint8 revision;
7966         int old_offset = offset;
7967         guint32 owner_sid_offset;
7968         guint32 group_sid_offset;
7969         guint32 sacl_offset;
7970         guint32 dacl_offset;
7971
7972         if(parent_tree){
7973                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7974                                            "NT Security Descriptor");
7975                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7976         }
7977
7978         /* revision */
7979         revision = tvb_get_guint8(tvb, offset);
7980         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7981                 tvb, offset, 1, revision);
7982         offset += 1;
7983
7984         /* next byte should be zero, for now just ignore it */
7985         offset += 1;
7986
7987
7988         switch(revision){
7989         case 1:  /* only version we will ever see of this structure?*/
7990           /* type */
7991           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7992
7993           /* offset to owner sid */
7994           owner_sid_offset = tvb_get_letohl(tvb, offset);
7995           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7996           offset += 4;
7997
7998           /* offset to group sid */
7999           group_sid_offset = tvb_get_letohl(tvb, offset);
8000           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
8001           offset += 4;
8002
8003           /* offset to sacl */
8004           sacl_offset = tvb_get_letohl(tvb, offset);
8005           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
8006           offset += 4;
8007
8008           /* offset to dacl */
8009           dacl_offset = tvb_get_letohl(tvb, offset);
8010           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
8011           offset += 4;
8012
8013           /*owner SID*/
8014           if(owner_sid_offset){
8015             if (len == -1)
8016               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
8017             else
8018               dissect_nt_sid(
8019                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
8020           }
8021
8022           /*group SID*/
8023           if(group_sid_offset){
8024             dissect_nt_sid(
8025                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
8026           }
8027
8028           /* sacl */
8029           if(sacl_offset){
8030             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
8031                            drep, "System (SACL)", ami);
8032           }
8033
8034           /* dacl */
8035           if(dacl_offset){
8036             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
8037                            drep, "User (DACL)", ami);
8038           }
8039
8040         }
8041
8042         return offset+len;
8043 }
8044
8045 static int
8046 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
8047 {
8048         int old_offset, old_sid_offset;
8049         guint32 qsize;
8050
8051         do {
8052                 old_offset=offset;
8053
8054                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8055                 qsize=tvb_get_letohl(tvb, offset);
8056                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
8057                 COUNT_BYTES_TRANS_SUBR(4);
8058
8059                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
8060                 /* length of SID */
8061                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8062                 COUNT_BYTES_TRANS_SUBR(4);
8063
8064                 /* 16 unknown bytes */
8065                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8066                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8067                             offset, 8, TRUE);
8068                 COUNT_BYTES_TRANS_SUBR(8);
8069
8070                 /* number of bytes for used quota */
8071                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8072                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
8073                 COUNT_BYTES_TRANS_SUBR(8);
8074
8075                 /* number of bytes for quota warning */
8076                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8077                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
8078                 COUNT_BYTES_TRANS_SUBR(8);
8079
8080                 /* number of bytes for quota limit */
8081                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8082                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
8083                 COUNT_BYTES_TRANS_SUBR(8);
8084
8085                 /* SID of the user */
8086                 old_sid_offset=offset;
8087                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8088                 *bcp -= (offset-old_sid_offset);
8089
8090                 if(qsize){
8091                         offset = old_offset+qsize;
8092                 }
8093         }while(qsize);
8094
8095
8096         return offset;
8097 }
8098
8099
8100 static int
8101 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
8102 {
8103         proto_item *item = NULL;
8104         proto_tree *tree = NULL;
8105         smb_info_t *si;
8106         int old_offset = offset;
8107         guint16 bcp=bc; /* XXX fixme */
8108
8109         si = (smb_info_t *)pinfo->private_data;
8110
8111         if(parent_tree){
8112                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8113                                 "%s Data",
8114                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8115                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8116         }
8117
8118         switch(ntd->subcmd){
8119         case NT_TRANS_CREATE:
8120                 /* security descriptor */
8121                 if(ntd->sd_len){
8122                         offset = dissect_nt_sec_desc(
8123                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
8124                                 NULL);
8125                 }
8126
8127                 /* extended attributes */
8128                 if(ntd->ea_len){
8129                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8130                         offset += ntd->ea_len;
8131                 }
8132
8133                 break;
8134         case NT_TRANS_IOCTL:
8135                 /* ioctl data */
8136                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
8137                 offset += bc;
8138
8139                 break;
8140         case NT_TRANS_SSD:
8141                 offset = dissect_nt_sec_desc(
8142                         tvb, offset, pinfo, tree, NULL, bc, NULL);
8143                 break;
8144         case NT_TRANS_NOTIFY:
8145                 break;
8146         case NT_TRANS_RENAME:
8147                 /* XXX not documented */
8148                 break;
8149         case NT_TRANS_QSD:
8150                 break;
8151         case NT_TRANS_GET_USER_QUOTA:
8152                 /* unknown 4 bytes */
8153                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8154                             offset, 4, TRUE);
8155                 offset += 4;
8156
8157                 /* length of SID */
8158                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8159                 offset +=4;
8160
8161                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8162                 break;
8163         case NT_TRANS_SET_USER_QUOTA:
8164                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8165                 break;
8166         }
8167
8168         /* ooops there were data we didnt know how to process */
8169         if((offset-old_offset) < bc){
8170                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8171                     bc - (offset-old_offset), TRUE);
8172                 offset += bc - (offset-old_offset);
8173         }
8174
8175         return offset;
8176 }
8177
8178 static int
8179 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)
8180 {
8181         proto_item *item = NULL;
8182         proto_tree *tree = NULL;
8183         smb_info_t *si;
8184         guint32 fn_len;
8185         const char *fn;
8186
8187         si = (smb_info_t *)pinfo->private_data;
8188
8189         if(parent_tree){
8190                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8191                                 "%s Parameters",
8192                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8193                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8194         }
8195
8196         switch(ntd->subcmd){
8197         case NT_TRANS_CREATE:
8198                 /* Create flags */
8199                 offset = dissect_nt_create_bits(tvb, tree, offset);
8200                 bc -= 4;
8201
8202                 /* root directory fid */
8203                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8204                 COUNT_BYTES(4);
8205
8206                 /* nt access mask */
8207                 offset = dissect_smb_access_mask(tvb, tree, offset);
8208                 bc -= 4;
8209
8210                 /* allocation size */
8211                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8212                 COUNT_BYTES(8);
8213
8214                 /* Extended File Attributes */
8215                 offset = dissect_file_ext_attr(tvb, tree, offset);
8216                 bc -= 4;
8217
8218                 /* share access */
8219                 offset = dissect_nt_share_access(tvb, tree, offset);
8220                 bc -= 4;
8221
8222                 /* create disposition */
8223                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8224                 COUNT_BYTES(4);
8225
8226                 /* create options */
8227                 offset = dissect_nt_create_options(tvb, tree, offset);
8228                 bc -= 4;
8229
8230                 /* sd length */
8231                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8232                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8233                 COUNT_BYTES(4);
8234
8235                 /* ea length */
8236                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8237                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8238                 COUNT_BYTES(4);
8239
8240                 /* file name len */
8241                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8242                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8243                 COUNT_BYTES(4);
8244
8245                 /* impersonation level */
8246                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8247                 COUNT_BYTES(4);
8248
8249                 /* security flags */
8250                 offset = dissect_nt_security_flags(tvb, tree, offset);
8251                 bc -= 1;
8252
8253                 /* file name */
8254                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8255                 if (fn != NULL) {
8256                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8257                                 fn);
8258                         COUNT_BYTES(fn_len);
8259                 }
8260
8261                 break;
8262         case NT_TRANS_IOCTL:
8263                 break;
8264         case NT_TRANS_SSD: {
8265                 guint16 fid;
8266
8267                 /* fid */
8268                 fid = tvb_get_letohs(tvb, offset);
8269                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8270                 offset += 2;
8271
8272                 /* 2 reserved bytes */
8273                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8274                 offset += 2;
8275
8276                 /* security information */
8277                 offset = dissect_security_information_mask(tvb, tree, offset);
8278                 break;
8279         }
8280         case NT_TRANS_NOTIFY:
8281                 break;
8282         case NT_TRANS_RENAME:
8283                 /* XXX not documented */
8284                 break;
8285         case NT_TRANS_QSD: {
8286                 guint16 fid;
8287
8288                 /* fid */
8289                 fid = tvb_get_letohs(tvb, offset);
8290                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8291                 offset += 2;
8292
8293                 /* 2 reserved bytes */
8294                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8295                 offset += 2;
8296
8297                 /* security information */
8298                 offset = dissect_security_information_mask(tvb, tree, offset);
8299                 break;
8300         }
8301         case NT_TRANS_GET_USER_QUOTA:
8302                 /* not decoded yet */
8303                 break;
8304         case NT_TRANS_SET_USER_QUOTA:
8305                 /* not decoded yet */
8306                 break;
8307         }
8308
8309         return offset;
8310 }
8311
8312 static int
8313 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8314 {
8315         proto_item *item = NULL;
8316         proto_tree *tree = NULL;
8317         smb_info_t *si;
8318         int old_offset = offset;
8319
8320         si = (smb_info_t *)pinfo->private_data;
8321
8322         if(parent_tree){
8323                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8324                                 "%s Setup",
8325                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8326                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8327         }
8328
8329         switch(ntd->subcmd){
8330         case NT_TRANS_CREATE:
8331                 break;
8332         case NT_TRANS_IOCTL: {
8333                 guint16 fid;
8334
8335                 /* function code */
8336                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8337                 offset += 4;
8338
8339                 /* fid */
8340                 fid = tvb_get_letohs(tvb, offset);
8341                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8342                 offset += 2;
8343
8344                 /* isfsctl */
8345                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8346                 offset += 1;
8347
8348                 /* isflags */
8349                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8350
8351                 break;
8352         }
8353         case NT_TRANS_SSD:
8354                 break;
8355         case NT_TRANS_NOTIFY: {
8356                 guint16 fid;
8357
8358                 /* completion filter */
8359                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8360
8361                 /* fid */
8362                 fid = tvb_get_letohs(tvb, offset);
8363                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8364                 offset += 2;
8365
8366                 /* watch tree */
8367                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8368                 offset += 1;
8369
8370                 /* reserved byte */
8371                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8372                 offset += 1;
8373
8374                 break;
8375         }
8376         case NT_TRANS_RENAME:
8377                 /* XXX not documented */
8378                 break;
8379         case NT_TRANS_QSD:
8380                 break;
8381         case NT_TRANS_GET_USER_QUOTA:
8382                 /* not decoded yet */
8383                 break;
8384         case NT_TRANS_SET_USER_QUOTA:
8385                 /* not decoded yet */
8386                 break;
8387         }
8388
8389         return old_offset+len;
8390 }
8391
8392
8393 static int
8394 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8395 {
8396         guint8 wc, sc;
8397         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8398         smb_info_t *si;
8399         smb_saved_info_t *sip;
8400         int subcmd;
8401         nt_trans_data ntd;
8402         guint16 bc;
8403         int padcnt;
8404         smb_nt_transact_info_t *nti;
8405
8406         si = (smb_info_t *)pinfo->private_data;
8407         sip = si->sip;
8408
8409         WORD_COUNT;
8410
8411         if(wc>=19){
8412                 /* primary request */
8413                 /* max setup count */
8414                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8415                 offset += 1;
8416
8417                 /* 2 reserved bytes */
8418                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8419                 offset += 2;
8420         } else {
8421                 /* secondary request */
8422                 /* 3 reserved bytes */
8423                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8424                 offset += 3;
8425         }
8426
8427
8428         /* total param count */
8429         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8430         offset += 4;
8431
8432         /* total data count */
8433         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8434         offset += 4;
8435
8436         if(wc>=19){
8437                 /* primary request */
8438                 /* max param count */
8439                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8440                 offset += 4;
8441
8442                 /* max data count */
8443                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8444                 offset += 4;
8445         }
8446
8447         /* param count */
8448         pc = tvb_get_letohl(tvb, offset);
8449         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8450         offset += 4;
8451
8452         /* param offset */
8453         po = tvb_get_letohl(tvb, offset);
8454         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8455         offset += 4;
8456
8457         /* param displacement */
8458         if(wc>=19){
8459                 /* primary request*/
8460                 pd = 0;
8461         } else {
8462                 /* secondary request */
8463                 pd = tvb_get_letohl(tvb, offset);
8464                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8465                 offset += 4;
8466         }
8467
8468         /* data count */
8469         dc = tvb_get_letohl(tvb, offset);
8470         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8471         offset += 4;
8472
8473         /* data offset */
8474         od = tvb_get_letohl(tvb, offset);
8475         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8476         offset += 4;
8477
8478         /* data displacement */
8479         if(wc>=19){
8480                 /* primary request */
8481                 dd = 0;
8482         } else {
8483                 /* secondary request */
8484                 dd = tvb_get_letohl(tvb, offset);
8485                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8486                 offset += 4;
8487         }
8488
8489         /* setup count */
8490         if(wc>=19){
8491                 /* primary request */
8492                 sc = tvb_get_guint8(tvb, offset);
8493                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8494                 offset += 1;
8495         } else {
8496                 /* secondary request */
8497                 sc = 0;
8498         }
8499
8500         /* function */
8501         if(wc>=19){
8502                 /* primary request */
8503                 subcmd = tvb_get_letohs(tvb, offset);
8504                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8505                 if(check_col(pinfo->cinfo, COL_INFO)){
8506                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8507                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8508                 }
8509                 ntd.subcmd = subcmd;
8510                 if (!si->unidir) {
8511                         if(!pinfo->fd->flags.visited){
8512                                 /*
8513                                  * Allocate a new smb_nt_transact_info_t
8514                                  * structure.
8515                                  */
8516                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8517                                 nti->subcmd = subcmd;
8518                                 sip->extra_info = nti;
8519                         }
8520                 }
8521         } else {
8522                 /* secondary request */
8523                 if(check_col(pinfo->cinfo, COL_INFO)){
8524                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8525                 }
8526         }
8527         offset += 2;
8528
8529         /* this is a padding byte */
8530         if(offset%1){
8531                 /* pad byte */
8532                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8533                 offset += 1;
8534         }
8535
8536         /* if there were any setup bytes, decode them */
8537         if(sc){
8538                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8539                 offset += sc*2;
8540         }
8541
8542         BYTE_COUNT;
8543
8544         /* parameters */
8545         if(po>(guint32)offset){
8546                 /* We have some initial padding bytes.
8547                 */
8548                 padcnt = po-offset;
8549                 if (padcnt > bc)
8550                         padcnt = bc;
8551                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8552                 COUNT_BYTES(padcnt);
8553         }
8554         if(pc){
8555                 CHECK_BYTE_COUNT(pc);
8556                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8557                 COUNT_BYTES(pc);
8558         }
8559
8560         /* data */
8561         if(od>(guint32)offset){
8562                 /* We have some initial padding bytes.
8563                 */
8564                 padcnt = od-offset;
8565                 if (padcnt > bc)
8566                         padcnt = bc;
8567                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8568                 COUNT_BYTES(padcnt);
8569         }
8570         if(dc){
8571                 CHECK_BYTE_COUNT(dc);
8572                 dissect_nt_trans_data_request(
8573                         tvb, pinfo, offset, tree, dc, &ntd);
8574                 COUNT_BYTES(dc);
8575         }
8576
8577         END_OF_SMB
8578
8579         return offset;
8580 }
8581
8582
8583
8584 static int
8585 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8586                                int offset, proto_tree *parent_tree, int len,
8587                                nt_trans_data *ntd _U_)
8588 {
8589         proto_item *item = NULL;
8590         proto_tree *tree = NULL;
8591         smb_info_t *si;
8592         smb_nt_transact_info_t *nti;
8593         guint16 bcp;
8594
8595         si = (smb_info_t *)pinfo->private_data;
8596         if (si->sip != NULL)
8597                 nti = si->sip->extra_info;
8598         else
8599                 nti = NULL;
8600
8601         if(parent_tree){
8602                 if(nti != NULL){
8603                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8604                                 "%s Data",
8605                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8606                 } else {
8607                         /*
8608                          * We never saw the request to which this is a
8609                          * response.
8610                          */
8611                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8612                                 "Unknown NT Transaction Data (matching request not seen)");
8613                 }
8614                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8615         }
8616
8617         if (nti == NULL) {
8618                 offset += len;
8619                 return offset;
8620         }
8621         switch(nti->subcmd){
8622         case NT_TRANS_CREATE:
8623                 break;
8624         case NT_TRANS_IOCTL:
8625                 /* ioctl data */
8626                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8627                 offset += len;
8628
8629                 break;
8630         case NT_TRANS_SSD:
8631                 break;
8632         case NT_TRANS_NOTIFY:
8633                 break;
8634         case NT_TRANS_RENAME:
8635                 /* XXX not documented */
8636                 break;
8637         case NT_TRANS_QSD: {
8638                 /*
8639                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8640                  * which may be documented in the Win32 documentation
8641                  * somewhere.
8642                  */
8643                 offset = dissect_nt_sec_desc(
8644                         tvb, offset, pinfo, tree, NULL, len, NULL);
8645                 break;
8646         }
8647         case NT_TRANS_GET_USER_QUOTA:
8648                 bcp=len;
8649                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8650                 break;
8651         case NT_TRANS_SET_USER_QUOTA:
8652                 /* not decoded yet */
8653                 break;
8654         }
8655
8656         return offset;
8657 }
8658
8659 static int
8660 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8661                                 int offset, proto_tree *parent_tree,
8662                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8663 {
8664         proto_item *item = NULL;
8665         proto_tree *tree = NULL;
8666         guint32 fn_len;
8667         const char *fn;
8668         smb_info_t *si;
8669         smb_nt_transact_info_t *nti;
8670         guint16 fid;
8671         int old_offset;
8672         guint32 neo;
8673         int padcnt;
8674
8675         si = (smb_info_t *)pinfo->private_data;
8676         if (si->sip != NULL)
8677                 nti = si->sip->extra_info;
8678         else
8679                 nti = NULL;
8680
8681         if(parent_tree){
8682                 if(nti != NULL){
8683                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8684                                 "%s Parameters",
8685                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8686                 } else {
8687                         /*
8688                          * We never saw the request to which this is a
8689                          * response.
8690                          */
8691                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8692                                 "Unknown NT Transaction Parameters (matching request not seen)");
8693                 }
8694                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8695         }
8696
8697         if (nti == NULL) {
8698                 offset += len;
8699                 return offset;
8700         }
8701         switch(nti->subcmd){
8702         case NT_TRANS_CREATE:
8703                 /* oplock level */
8704                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8705                 offset += 1;
8706
8707                 /* reserved byte */
8708                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8709                 offset += 1;
8710
8711                 /* fid */
8712                 fid = tvb_get_letohs(tvb, offset);
8713                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8714                 offset += 2;
8715
8716                 /* create action */
8717                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8718                 offset += 4;
8719
8720                 /* ea error offset */
8721                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8722                 offset += 4;
8723
8724                 /* create time */
8725                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8726                         hf_smb_create_time);
8727
8728                 /* access time */
8729                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8730                         hf_smb_access_time);
8731
8732                 /* last write time */
8733                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8734                         hf_smb_last_write_time);
8735
8736                 /* last change time */
8737                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8738                         hf_smb_change_time);
8739
8740                 /* Extended File Attributes */
8741                 offset = dissect_file_ext_attr(tvb, tree, offset);
8742
8743                 /* allocation size */
8744                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8745                 offset += 8;
8746
8747                 /* end of file */
8748                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8749                 offset += 8;
8750
8751                 /* File Type */
8752                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8753                 offset += 2;
8754
8755                 /* device state */
8756                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8757
8758                 /* is directory */
8759                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8760                 offset += 1;
8761                 break;
8762         case NT_TRANS_IOCTL:
8763                 break;
8764         case NT_TRANS_SSD:
8765                 break;
8766         case NT_TRANS_NOTIFY:
8767                 while(len){
8768                         old_offset = offset;
8769
8770                         /* next entry offset */
8771                         neo = tvb_get_letohl(tvb, offset);
8772                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8773                         COUNT_BYTES(4);
8774                         len -= 4;
8775                         /* broken implementations */
8776                         if(len<0)break;
8777
8778                         /* action */
8779                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8780                         COUNT_BYTES(4);
8781                         len -= 4;
8782                         /* broken implementations */
8783                         if(len<0)break;
8784
8785                         /* file name len */
8786                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8787                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8788                         COUNT_BYTES(4);
8789                         len -= 4;
8790                         /* broken implementations */
8791                         if(len<0)break;
8792
8793                         /* file name */
8794                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8795                         if (fn == NULL)
8796                                 break;
8797                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8798                                 fn);
8799                         COUNT_BYTES(fn_len);
8800                         len -= fn_len;
8801                         /* broken implementations */
8802                         if(len<0)break;
8803
8804                         if (neo == 0)
8805                                 break;  /* no more structures */
8806
8807                         /* skip to next structure */
8808                         padcnt = (old_offset + neo) - offset;
8809                         if (padcnt < 0) {
8810                                 /*
8811                                  * XXX - this is bogus; flag it?
8812                                  */
8813                                 padcnt = 0;
8814                         }
8815                         if (padcnt != 0) {
8816                                 COUNT_BYTES(padcnt);
8817                                 len -= padcnt;
8818                                 /* broken implementations */
8819                                 if(len<0)break;
8820                         }
8821                 }
8822                 break;
8823         case NT_TRANS_RENAME:
8824                 /* XXX not documented */
8825                 break;
8826         case NT_TRANS_QSD:
8827                 /*
8828                  * This appears to be the size of the security
8829                  * descriptor; the calling sequence of
8830                  * "ZwQuerySecurityObject()" suggests that it would
8831                  * be.  The actual security descriptor wouldn't
8832                  * follow if the max data count in the request
8833                  * was smaller; this lets the client know how
8834                  * big a buffer it needs to provide.
8835                  */
8836                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8837                 offset += 4;
8838                 break;
8839         case NT_TRANS_GET_USER_QUOTA:
8840                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8841                         tvb_get_letohl(tvb, offset));
8842                 offset += 4;
8843                 break;
8844         case NT_TRANS_SET_USER_QUOTA:
8845                 /* not decoded yet */
8846                 break;
8847         }
8848
8849         return offset;
8850 }
8851
8852 static int
8853 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8854                                 int offset, proto_tree *parent_tree,
8855                                 int len, nt_trans_data *ntd _U_)
8856 {
8857         proto_item *item = NULL;
8858         proto_tree *tree = NULL;
8859         smb_info_t *si;
8860         smb_nt_transact_info_t *nti;
8861
8862         si = (smb_info_t *)pinfo->private_data;
8863         if (si->sip != NULL)
8864                 nti = si->sip->extra_info;
8865         else
8866                 nti = NULL;
8867
8868         if(parent_tree){
8869                 if(nti != NULL){
8870                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8871                                 "%s Setup",
8872                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8873                 } else {
8874                         /*
8875                          * We never saw the request to which this is a
8876                          * response.
8877                          */
8878                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8879                                 "Unknown NT Transaction Setup (matching request not seen)");
8880                 }
8881                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8882         }
8883
8884         if (nti == NULL) {
8885                 offset += len;
8886                 return offset;
8887         }
8888         switch(nti->subcmd){
8889         case NT_TRANS_CREATE:
8890                 break;
8891         case NT_TRANS_IOCTL:
8892                 break;
8893         case NT_TRANS_SSD:
8894                 break;
8895         case NT_TRANS_NOTIFY:
8896                 break;
8897         case NT_TRANS_RENAME:
8898                 /* XXX not documented */
8899                 break;
8900         case NT_TRANS_QSD:
8901                 break;
8902         case NT_TRANS_GET_USER_QUOTA:
8903                 /* not decoded yet */
8904                 break;
8905         case NT_TRANS_SET_USER_QUOTA:
8906                 /* not decoded yet */
8907                 break;
8908         }
8909
8910         return offset;
8911 }
8912
8913 static int
8914 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8915 {
8916         guint8 wc, sc;
8917         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8918         guint32 td=0, tp=0;
8919         smb_info_t *si;
8920         smb_nt_transact_info_t *nti;
8921         static nt_trans_data ntd;
8922         guint16 bc;
8923         int padcnt;
8924         fragment_data *r_fd = NULL;
8925         tvbuff_t *pd_tvb=NULL;
8926         gboolean save_fragmented;
8927
8928         si = (smb_info_t *)pinfo->private_data;
8929         if (si->sip != NULL)
8930                 nti = si->sip->extra_info;
8931         else
8932                 nti = NULL;
8933
8934         /* primary request */
8935         if(nti != NULL){
8936                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8937                 if(check_col(pinfo->cinfo, COL_INFO)){
8938                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8939                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8940                 }
8941         } else {
8942                 proto_tree_add_text(tree, tvb, offset, 0,
8943                         "Function: <unknown function - could not find matching request>");
8944                 if(check_col(pinfo->cinfo, COL_INFO)){
8945                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8946                 }
8947         }
8948
8949         WORD_COUNT;
8950
8951         /* 3 reserved bytes */
8952         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8953         offset += 3;
8954
8955         /* total param count */
8956         tp = tvb_get_letohl(tvb, offset);
8957         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8958         offset += 4;
8959
8960         /* total data count */
8961         td = tvb_get_letohl(tvb, offset);
8962         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8963         offset += 4;
8964
8965         /* param count */
8966         pc = tvb_get_letohl(tvb, offset);
8967         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8968         offset += 4;
8969
8970         /* param offset */
8971         po = tvb_get_letohl(tvb, offset);
8972         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8973         offset += 4;
8974
8975         /* param displacement */
8976         pd = tvb_get_letohl(tvb, offset);
8977         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8978         offset += 4;
8979
8980         /* data count */
8981         dc = tvb_get_letohl(tvb, offset);
8982         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8983         offset += 4;
8984
8985         /* data offset */
8986         od = tvb_get_letohl(tvb, offset);
8987         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8988         offset += 4;
8989
8990         /* data displacement */
8991         dd = tvb_get_letohl(tvb, offset);
8992         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8993         offset += 4;
8994
8995         /* setup count */
8996         sc = tvb_get_guint8(tvb, offset);
8997         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8998         offset += 1;
8999
9000         /* setup data */
9001         if(sc){
9002                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
9003                 offset += sc*2;
9004         }
9005
9006         BYTE_COUNT;
9007
9008         /* reassembly of SMB NT Transaction data payload.
9009            In this section we do reassembly of both the data and parameters
9010            blocks of the SMB transaction command.
9011         */
9012         save_fragmented = pinfo->fragmented;
9013         /* do we need reassembly? */
9014         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
9015                 /* oh yeah, either data or parameter section needs
9016                    reassembly...
9017                 */
9018                 pinfo->fragmented = TRUE;
9019                 if(smb_trans_reassembly){
9020                         /* ...and we were told to do reassembly */
9021                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
9022                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9023                                                              po, pc, pd, td+tp);
9024
9025                         }
9026                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
9027                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
9028                                                              od, dc, dd+tp, td+tp);
9029                         }
9030                 }
9031         }
9032
9033         /* if we got a reassembled fd structure from the reassembly routine we
9034            must create pd_tvb from it
9035         */
9036         if(r_fd){
9037                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
9038                                              r_fd->datalen);
9039                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
9040                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
9041
9042                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
9043         }
9044
9045
9046         if(pd_tvb){
9047           /* we have reassembled data, grab param and data from there */
9048           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
9049                                           &ntd, (guint16) tvb_length(pd_tvb));
9050           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
9051         } else {
9052           /* we do not have reassembled data, just use what we have in the
9053              packet as well as we can */
9054           /* parameters */
9055           if(po>(guint32)offset){
9056             /* We have some initial padding bytes.
9057              */
9058             padcnt = po-offset;
9059             if (padcnt > bc)
9060               padcnt = bc;
9061             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9062             COUNT_BYTES(padcnt);
9063           }
9064           if(pc){
9065             CHECK_BYTE_COUNT(pc);
9066             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
9067             COUNT_BYTES(pc);
9068           }
9069
9070           /* data */
9071           if(od>(guint32)offset){
9072             /* We have some initial padding bytes.
9073              */
9074             padcnt = od-offset;
9075             if (padcnt > bc)
9076               padcnt = bc;
9077             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9078             COUNT_BYTES(padcnt);
9079           }
9080           if(dc){
9081             CHECK_BYTE_COUNT(dc);
9082             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
9083             COUNT_BYTES(dc);
9084           }
9085         }
9086         pinfo->fragmented = save_fragmented;
9087
9088         END_OF_SMB
9089
9090         return offset;
9091 }
9092
9093 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9094    NT Transaction command  ends here
9095    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9096
9097 static const value_string print_mode_vals[] = {
9098         {0,     "Text Mode"},
9099         {1,     "Graphics Mode"},
9100         {0, NULL}
9101 };
9102
9103 static int
9104 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9105 {
9106         smb_info_t *si = pinfo->private_data;
9107         int fn_len;
9108         const char *fn;
9109         guint8 wc;
9110         guint16 bc;
9111
9112         WORD_COUNT;
9113
9114         /* setup len */
9115         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9116         offset += 2;
9117
9118         /* print mode */
9119         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9120         offset += 2;
9121
9122         BYTE_COUNT;
9123
9124         /* buffer format */
9125         CHECK_BYTE_COUNT(1);
9126         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9127         COUNT_BYTES(1);
9128
9129         /* print identifier */
9130         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9131         if (fn == NULL)
9132                 goto endofcommand;
9133         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9134                 fn);
9135         COUNT_BYTES(fn_len);
9136
9137         END_OF_SMB
9138
9139         return offset;
9140 }
9141
9142
9143 static int
9144 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9145 {
9146         int cnt;
9147         guint8 wc;
9148         guint16 bc, fid;
9149
9150         WORD_COUNT;
9151
9152         /* fid */
9153         fid = tvb_get_letohs(tvb, offset);
9154         add_fid(tvb, pinfo, tree, offset, 2, fid);
9155         offset += 2;
9156
9157         BYTE_COUNT;
9158
9159         /* buffer format */
9160         CHECK_BYTE_COUNT(1);
9161         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9162         COUNT_BYTES(1);
9163
9164         /* data len */
9165         CHECK_BYTE_COUNT(2);
9166         cnt = tvb_get_letohs(tvb, offset);
9167         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9168         COUNT_BYTES(2);
9169
9170         /* file data */
9171         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9172
9173         END_OF_SMB
9174
9175         return offset;
9176 }
9177
9178
9179 static const value_string print_status_vals[] = {
9180         {1,     "Held or Stopped"},
9181         {2,     "Printing"},
9182         {3,     "Awaiting print"},
9183         {4,     "In intercept"},
9184         {5,     "File had error"},
9185         {6,     "Printer error"},
9186         {0, NULL}
9187 };
9188
9189 static int
9190 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9191 {
9192         guint8 wc;
9193         guint16 bc;
9194
9195         WORD_COUNT;
9196
9197         /* max count */
9198         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9199         offset += 2;
9200
9201         /* start index */
9202         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9203         offset += 2;
9204
9205         BYTE_COUNT;
9206
9207         END_OF_SMB
9208
9209         return offset;
9210 }
9211
9212 static int
9213 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9214     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9215 {
9216         proto_item *item = NULL;
9217         proto_tree *tree = NULL;
9218         smb_info_t *si = pinfo->private_data;
9219         int fn_len;
9220         const char *fn;
9221
9222         if(parent_tree){
9223                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9224                         "Queue entry");
9225                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9226         }
9227
9228         /* queued time */
9229         CHECK_BYTE_COUNT_SUBR(4);
9230         offset = dissect_smb_datetime(tvb, tree, offset,
9231                 hf_smb_print_queue_date,
9232                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9233         *bcp -= 4;
9234
9235         /* status */
9236         CHECK_BYTE_COUNT_SUBR(1);
9237         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9238         COUNT_BYTES_SUBR(1);
9239
9240         /* spool file number */
9241         CHECK_BYTE_COUNT_SUBR(2);
9242         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9243         COUNT_BYTES_SUBR(2);
9244
9245         /* spool file size */
9246         CHECK_BYTE_COUNT_SUBR(4);
9247         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9248         COUNT_BYTES_SUBR(4);
9249
9250         /* reserved byte */
9251         CHECK_BYTE_COUNT_SUBR(1);
9252         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9253         COUNT_BYTES_SUBR(1);
9254
9255         /* file name */
9256         fn_len = 16;
9257         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9258         CHECK_STRING_SUBR(fn);
9259         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9260                 fn);
9261         COUNT_BYTES_SUBR(fn_len);
9262
9263         *trunc = FALSE;
9264         return offset;
9265 }
9266
9267 static int
9268 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9269 {
9270         guint16 cnt=0, len;
9271         guint8 wc;
9272         guint16 bc;
9273         gboolean trunc;
9274
9275         WORD_COUNT;
9276
9277         /* count */
9278         cnt = tvb_get_letohs(tvb, offset);
9279         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9280         offset += 2;
9281
9282         /* restart index */
9283         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9284         offset += 2;
9285
9286         BYTE_COUNT;
9287
9288         /* buffer format */
9289         CHECK_BYTE_COUNT(1);
9290         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9291         COUNT_BYTES(1);
9292
9293         /* data len */
9294         CHECK_BYTE_COUNT(2);
9295         len = tvb_get_letohs(tvb, offset);
9296         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9297         COUNT_BYTES(2);
9298
9299         /* queue elements */
9300         while(cnt--){
9301                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9302                     &bc, &trunc);
9303                 if (trunc)
9304                         goto endofcommand;
9305         }
9306
9307         END_OF_SMB
9308
9309         return offset;
9310 }
9311
9312
9313 static int
9314 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9315 {
9316         int name_len;
9317         guint16 bc;
9318         guint8 wc;
9319         guint16 message_len;
9320
9321         WORD_COUNT;
9322
9323         BYTE_COUNT;
9324
9325         /* buffer format */
9326         CHECK_BYTE_COUNT(1);
9327         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9328         COUNT_BYTES(1);
9329
9330         /* originator name */
9331         /* XXX - what if this runs past bc? */
9332         name_len = tvb_strsize(tvb, offset);
9333         CHECK_BYTE_COUNT(name_len);
9334         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9335             name_len, TRUE);
9336         COUNT_BYTES(name_len);
9337
9338         /* buffer format */
9339         CHECK_BYTE_COUNT(1);
9340         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9341         COUNT_BYTES(1);
9342
9343         /* destination name */
9344         /* XXX - what if this runs past bc? */
9345         name_len = tvb_strsize(tvb, offset);
9346         CHECK_BYTE_COUNT(name_len);
9347         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9348             name_len, TRUE);
9349         COUNT_BYTES(name_len);
9350
9351         /* buffer format */
9352         CHECK_BYTE_COUNT(1);
9353         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9354         COUNT_BYTES(1);
9355
9356         /* message len */
9357         CHECK_BYTE_COUNT(2);
9358         message_len = tvb_get_letohs(tvb, offset);
9359         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9360             message_len);
9361         COUNT_BYTES(2);
9362
9363         /* message */
9364         CHECK_BYTE_COUNT(message_len);
9365         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9366             TRUE);
9367         COUNT_BYTES(message_len);
9368
9369         END_OF_SMB
9370
9371         return offset;
9372 }
9373
9374 static int
9375 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9376 {
9377         int name_len;
9378         guint16 bc;
9379         guint8 wc;
9380
9381         WORD_COUNT;
9382
9383         BYTE_COUNT;
9384
9385         /* buffer format */
9386         CHECK_BYTE_COUNT(1);
9387         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9388         COUNT_BYTES(1);
9389
9390         /* originator name */
9391         /* XXX - what if this runs past bc? */
9392         name_len = tvb_strsize(tvb, offset);
9393         CHECK_BYTE_COUNT(name_len);
9394         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9395             name_len, TRUE);
9396         COUNT_BYTES(name_len);
9397
9398         /* buffer format */
9399         CHECK_BYTE_COUNT(1);
9400         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9401         COUNT_BYTES(1);
9402
9403         /* destination name */
9404         /* XXX - what if this runs past bc? */
9405         name_len = tvb_strsize(tvb, offset);
9406         CHECK_BYTE_COUNT(name_len);
9407         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9408             name_len, TRUE);
9409         COUNT_BYTES(name_len);
9410
9411         END_OF_SMB
9412
9413         return offset;
9414 }
9415
9416 static int
9417 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9418 {
9419         guint16 bc;
9420         guint8 wc;
9421
9422         WORD_COUNT;
9423
9424         /* message group ID */
9425         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9426         offset += 2;
9427
9428         BYTE_COUNT;
9429
9430         END_OF_SMB
9431
9432         return offset;
9433 }
9434
9435 static int
9436 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9437 {
9438         guint16 bc;
9439         guint8 wc;
9440         guint16 message_len;
9441
9442         WORD_COUNT;
9443
9444         BYTE_COUNT;
9445
9446         /* buffer format */
9447         CHECK_BYTE_COUNT(1);
9448         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9449         COUNT_BYTES(1);
9450
9451         /* message len */
9452         CHECK_BYTE_COUNT(2);
9453         message_len = tvb_get_letohs(tvb, offset);
9454         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9455             message_len);
9456         COUNT_BYTES(2);
9457
9458         /* message */
9459         CHECK_BYTE_COUNT(message_len);
9460         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9461             TRUE);
9462         COUNT_BYTES(message_len);
9463
9464         END_OF_SMB
9465
9466         return offset;
9467 }
9468
9469 static int
9470 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9471 {
9472         int name_len;
9473         guint16 bc;
9474         guint8 wc;
9475
9476         WORD_COUNT;
9477
9478         BYTE_COUNT;
9479
9480         /* buffer format */
9481         CHECK_BYTE_COUNT(1);
9482         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9483         COUNT_BYTES(1);
9484
9485         /* forwarded name */
9486         /* XXX - what if this runs past bc? */
9487         name_len = tvb_strsize(tvb, offset);
9488         CHECK_BYTE_COUNT(name_len);
9489         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9490             name_len, TRUE);
9491         COUNT_BYTES(name_len);
9492
9493         END_OF_SMB
9494
9495         return offset;
9496 }
9497
9498 static int
9499 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9500 {
9501         int name_len;
9502         guint16 bc;
9503         guint8 wc;
9504
9505         WORD_COUNT;
9506
9507         BYTE_COUNT;
9508
9509         /* buffer format */
9510         CHECK_BYTE_COUNT(1);
9511         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9512         COUNT_BYTES(1);
9513
9514         /* machine name */
9515         /* XXX - what if this runs past bc? */
9516         name_len = tvb_strsize(tvb, offset);
9517         CHECK_BYTE_COUNT(name_len);
9518         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9519             name_len, TRUE);
9520         COUNT_BYTES(name_len);
9521
9522         END_OF_SMB
9523
9524         return offset;
9525 }
9526
9527
9528 static int
9529 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9530 {
9531         guint8  wc, cmd=0xff;
9532         guint16 andxoffset=0;
9533         guint16 bc;
9534         smb_info_t *si = pinfo->private_data;
9535         int fn_len;
9536         const char *fn;
9537
9538         WORD_COUNT;
9539
9540         /* next smb command */
9541         cmd = tvb_get_guint8(tvb, offset);
9542         if(cmd!=0xff){
9543                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9544         } else {
9545                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9546         }
9547         offset += 1;
9548
9549         /* reserved byte */
9550         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9551         offset += 1;
9552
9553         /* andxoffset */
9554         andxoffset = tvb_get_letohs(tvb, offset);
9555         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9556         offset += 2;
9557
9558         /* reserved byte */
9559         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9560         offset += 1;
9561
9562         /* file name len */
9563         fn_len = tvb_get_letohs(tvb, offset);
9564         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9565         offset += 2;
9566
9567         /* Create flags */
9568         offset = dissect_nt_create_bits(tvb, tree, offset);
9569
9570         /* root directory fid */
9571         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9572         offset += 4;
9573
9574         /* nt access mask */
9575         offset = dissect_smb_access_mask(tvb, tree, offset);
9576
9577         /* allocation size */
9578         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9579         offset += 8;
9580
9581         /* Extended File Attributes */
9582         offset = dissect_file_ext_attr(tvb, tree, offset);
9583
9584         /* share access */
9585         offset = dissect_nt_share_access(tvb, tree, offset);
9586
9587         /* create disposition */
9588         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9589         offset += 4;
9590
9591         /* create options */
9592         offset = dissect_nt_create_options(tvb, tree, offset);
9593
9594         /* impersonation level */
9595         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9596         offset += 4;
9597
9598         /* security flags */
9599         offset = dissect_nt_security_flags(tvb, tree, offset);
9600
9601         BYTE_COUNT;
9602
9603         /* file name */
9604         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9605         if (fn == NULL)
9606                 goto endofcommand;
9607         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9608                 fn);
9609         COUNT_BYTES(fn_len);
9610
9611         if (check_col(pinfo->cinfo, COL_INFO)) {
9612                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9613         }
9614
9615         END_OF_SMB
9616
9617         /* call AndXCommand (if there are any) */
9618         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9619
9620         return offset;
9621 }
9622
9623
9624 static int
9625 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9626 {
9627         guint8  wc, cmd=0xff;
9628         guint16 andxoffset=0;
9629         guint16 bc;
9630         guint16 fid;
9631
9632         WORD_COUNT;
9633
9634         /* next smb command */
9635         cmd = tvb_get_guint8(tvb, offset);
9636         if(cmd!=0xff){
9637                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9638         } else {
9639                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9640         }
9641         offset += 1;
9642
9643         /* reserved byte */
9644         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9645         offset += 1;
9646
9647         /* andxoffset */
9648         andxoffset = tvb_get_letohs(tvb, offset);
9649         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9650         offset += 2;
9651
9652         /* oplock level */
9653         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9654         offset += 1;
9655
9656         /* fid */
9657         fid = tvb_get_letohs(tvb, offset);
9658         add_fid(tvb, pinfo, tree, offset, 2, fid);
9659         offset += 2;
9660
9661         /* create action */
9662         /*XXX is this really the same as create disposition in the request? it looks so*/
9663         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9664         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9665         offset += 4;
9666
9667         /* create time */
9668         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9669
9670         /* access time */
9671         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9672
9673         /* last write time */
9674         offset = dissect_smb_64bit_time(tvb, tree, offset,
9675                 hf_smb_last_write_time);
9676
9677         /* last change time */
9678         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9679
9680         /* Extended File Attributes */
9681         offset = dissect_file_ext_attr(tvb, tree, offset);
9682
9683         /* allocation size */
9684         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9685         offset += 8;
9686
9687         /* end of file */
9688         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9689         offset += 8;
9690
9691         /* File Type */
9692         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9693         offset += 2;
9694
9695         /* IPC State */
9696         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9697
9698         /* is directory */
9699         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9700         offset += 1;
9701
9702         BYTE_COUNT;
9703
9704         END_OF_SMB
9705
9706         /* call AndXCommand (if there are any) */
9707         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9708
9709         return offset;
9710 }
9711
9712
9713 static int
9714 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9715 {
9716         guint8 wc;
9717         guint16 bc;
9718
9719         WORD_COUNT;
9720
9721         BYTE_COUNT;
9722
9723         END_OF_SMB
9724
9725         return offset;
9726 }
9727
9728 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9729    BEGIN Transaction/Transaction2 Primary and secondary requests
9730    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9731
9732
9733 const value_string trans2_cmd_vals[] = {
9734         { 0x00,         "OPEN2" },
9735         { 0x01,         "FIND_FIRST2" },
9736         { 0x02,         "FIND_NEXT2" },
9737         { 0x03,         "QUERY_FS_INFO" },
9738         { 0x04,         "SET_FS_QUOTA" },
9739         { 0x05,         "QUERY_PATH_INFO" },
9740         { 0x06,         "SET_PATH_INFO" },
9741         { 0x07,         "QUERY_FILE_INFO" },
9742         { 0x08,         "SET_FILE_INFO" },
9743         { 0x09,         "FSCTL" },
9744         { 0x0A,         "IOCTL2" },
9745         { 0x0B,         "FIND_NOTIFY_FIRST" },
9746         { 0x0C,         "FIND_NOTIFY_NEXT" },
9747         { 0x0D,         "CREATE_DIRECTORY" },
9748         { 0x0E,         "SESSION_SETUP" },
9749         { 0x10,         "GET_DFS_REFERRAL" },
9750         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9751         { 0,    NULL }
9752 };
9753
9754 static const true_false_string tfs_tf_dtid = {
9755         "Also DISCONNECT TID",
9756         "Do NOT disconnect TID"
9757 };
9758 static const true_false_string tfs_tf_owt = {
9759         "One Way Transaction (NO RESPONSE)",
9760         "Two way transaction"
9761 };
9762
9763 static const true_false_string tfs_ff2_backup = {
9764         "Find WITH backup intent",
9765         "No backup intent"
9766 };
9767 static const true_false_string tfs_ff2_continue = {
9768         "CONTINUE search from previous position",
9769         "New search, do NOT continue from previous position"
9770 };
9771 static const true_false_string tfs_ff2_resume = {
9772         "Return RESUME keys",
9773         "Do NOT return resume keys"
9774 };
9775 static const true_false_string tfs_ff2_close_eos = {
9776         "CLOSE search if END OF SEARCH is reached",
9777         "Do NOT close search if end of search reached"
9778 };
9779 static const true_false_string tfs_ff2_close = {
9780         "CLOSE search after this request",
9781         "Do NOT close search after this request"
9782 };
9783
9784 /* used by
9785    TRANS2_FIND_FIRST2
9786 */
9787 static const value_string ff2_il_vals[] = {
9788         { 1,            "Info Standard"},
9789         { 2,            "Info Query EA Size"},
9790         { 3,            "Info Query EAs From List"},
9791         { 0x0101,       "Find File Directory Info"},
9792         { 0x0102,       "Find File Full Directory Info"},
9793         { 0x0103,       "Find File Names Info"},
9794         { 0x0104,       "Find File Both Directory Info"},
9795         { 0x0202,       "Find File UNIX"},
9796         {0, NULL}
9797 };
9798
9799 /* values used by :
9800         TRANS2_QUERY_PATH_INFORMATION
9801         TRANS2_QUERY_FILE_INFORMATION
9802 */
9803 static const value_string qpi_loi_vals[] = {
9804         { 1,            "Info Standard"},
9805         { 2,            "Info Query EA Size"},
9806         { 3,            "Info Query EAs From List"},
9807         { 4,            "Info Query All EAs"},
9808         { 6,            "Info Is Name Valid"},
9809         { 0x0101,       "Query File Basic Info"},
9810         { 0x0102,       "Query File Standard Info"},
9811         { 0x0103,       "Query File EA Info"},
9812         { 0x0104,       "Query File Name Info"},
9813         { 0x0107,       "Query File All Info"},
9814         { 0x0108,       "Query File Alt Name Info"},
9815         { 0x0109,       "Query File Stream Info"},
9816         { 0x010b,       "Query File Compression Info"},
9817         { 0x0200,       "Query File Unix Basic"},
9818         { 0x0201,       "Query File Unix Link"},
9819         { 1004,         "Query File Basic Info"},
9820         { 1005,         "Query File Standard Info"},
9821         { 1006,         "Query File Internal Info"},
9822         { 1007,         "Query File EA Info"},
9823         { 1009,         "Query File Name Info"},
9824         { 1010,         "Query File Rename Info"},
9825         { 1011,         "Query File Link Info"},
9826         { 1012,         "Query File Names Info"},
9827         { 1013,         "Query File Disposition Info"},
9828         { 1014,         "Query File Position Info"},
9829         { 1015,         "Query File Full EA Info"},
9830         { 1016,         "Query File Mode Info"},
9831         { 1017,         "Query File Alignment Info"},
9832         { 1018,         "Query File All Info"},
9833         { 1019,         "Query File Allocation Info"},
9834         { 1020,         "Query File End of File Info"},
9835         { 1021,         "Query File Alt Name Info"},
9836         { 1022,         "Query File Stream Info"},
9837         { 1023,         "Query File Pipe Info"},
9838         { 1024,         "Query File Pipe Local Info"},
9839         { 1025,         "Query File Pipe Remote Info"},
9840         { 1026,         "Query File Mailslot Query Info"},
9841         { 1027,         "Query File Mailslot Set Info"},
9842         { 1028,         "Query File Compression Info"},
9843         { 1029,         "Query File ObjectID Info"},
9844         { 1030,         "Query File Completion Info"},
9845         { 1031,         "Query File Move Cluster Info"},
9846         { 1032,         "Query File Quota Info"},
9847         { 1033,         "Query File Reparsepoint Info"},
9848         { 1034,         "Query File Network Open Info"},
9849         { 1035,         "Query File Attribute Tag Info"},
9850         { 1036,         "Query File Tracking Info"},
9851         { 1037,         "Query File Maximum Info"},
9852         {0, NULL}
9853 };
9854
9855 /* values used by :
9856         TRANS2_SET_PATH_INFORMATION
9857         TRANS2_SET_FILE_INFORMATION
9858         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9859         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9860         well; note that they're different from the QUERY_PATH_INFORMATION
9861         and QUERY_FILE_INFORMATION values!)
9862 */
9863 static const value_string spi_loi_vals[] = {
9864         { 1,            "Info Standard"},
9865         { 2,            "Info Query EA Size"},
9866         { 4,            "Info Query All EAs"},
9867         { 0x0101,       "Set File Basic Info"},
9868         { 0x0102,       "Set File Disposition Info"},
9869         { 0x0103,       "Set File Allocation Info"},
9870         { 0x0104,       "Set File End Of File Info"},
9871         { 0x0200,       "Set File Unix Basic"},
9872         { 0x0201,       "Set File Unix Link"},
9873         { 0x0202,       "Set File Unix HardLink"},
9874         { 1004,         "Set File Basic Info"},
9875         { 1010,         "Set Rename Information"},
9876         { 1013,         "Set Disposition Information"},
9877         { 1014,         "Set Position Information"},
9878         { 1016,         "Set Mode Information"},
9879         { 1019,         "Set Allocation Information"},
9880         { 1020,         "Set EOF Information"},
9881         { 1023,         "Set File Pipe Information"},
9882         { 1025,         "Set File Pipe Remote Information"},
9883         { 1029,         "Set Copy On Write Information"},
9884         { 1032,         "Set OLE Class ID Information"},
9885         { 1039,         "Set Inherit Context Index Information"},
9886         { 1040,         "Set OLE Information (?)"},
9887         {0, NULL}
9888 };
9889
9890 static const value_string qfsi_vals[] = {
9891         { 1,            "Info Allocation"},
9892         { 2,            "Info Volume"},
9893         { 0x0101,       "Query FS Label Info"},
9894         { 0x0102,       "Query FS Volume Info"},
9895         { 0x0103,       "Query FS Size Info"},
9896         { 0x0104,       "Query FS Device Info"},
9897         { 0x0105,       "Query FS Attribute Info"},
9898         { 0x0200,       "Unix Query FS Info"},
9899         { 0x0301,       "Mac Query FS Info"},
9900         { 1001,         "Query FS Label Info"},
9901         { 1002,         "Query FS Volume Info"},
9902         { 1003,         "Query FS Size Info"},
9903         { 1004,         "Query FS Device Info"},
9904         { 1005,         "Query FS Attribute Info"},
9905         { 1006,         "Query FS Quota Info"},
9906         { 1007,         "Query Full FS Size Info"},
9907         { 1008,         "Object ID Information"},
9908         {0, NULL}
9909 };
9910
9911 static const value_string nt_rename_vals[] = {
9912         { 0x0103,       "Create Hard Link"},
9913         {0, NULL}
9914 };
9915
9916
9917 static const value_string delete_pending_vals[] = {
9918         {0,     "Normal, no pending delete"},
9919         {1,     "This object has DELETE PENDING"},
9920         {0, NULL}
9921 };
9922
9923 static const value_string alignment_vals[] = {
9924         {0,     "Byte alignment"},
9925         {1,     "Word (16bit) alignment"},
9926         {3,     "Long (32bit) alignment"},
9927         {7,     "8 byte boundary alignment"},
9928         {0x0f,  "16 byte boundary alignment"},
9929         {0x1f,  "32 byte boundary alignment"},
9930         {0x3f,  "64 byte boundary alignment"},
9931         {0x7f,  "128 byte boundary alignment"},
9932         {0xff,  "256 byte boundary alignment"},
9933         {0x1ff, "512 byte boundary alignment"},
9934         {0, NULL}
9935 };
9936
9937 static const true_false_string tfs_marked_for_deletion = {
9938         "File is MARKED FOR DELETION",
9939         "File is NOT marked for deletion"
9940 };
9941
9942 static const true_false_string tfs_get_dfs_server_hold_storage = {
9943         "Referral SERVER HOLDS STORAGE for the file",
9944         "Referral server does NOT hold storage for the file"
9945 };
9946 static const true_false_string tfs_get_dfs_fielding = {
9947         "The server in referral is FIELDING CAPABLE",
9948         "The server in referrals is NOT fielding capable"
9949 };
9950
9951 static const true_false_string tfs_dfs_referral_flags_strip = {
9952         "STRIP off pathconsumed characters before submitting",
9953         "Do NOT strip off any characters"
9954 };
9955
9956 static const value_string dfs_referral_server_type_vals[] = {
9957         {0,     "Don't know"},
9958         {1,     "SMB Server"},
9959         {2,     "Netware Server"},
9960         {3,     "Domain Server"},
9961         {0, NULL}
9962 };
9963
9964
9965 static const true_false_string tfs_device_char_removable = {
9966         "This is a REMOVABLE device",
9967         "This is NOT a removable device"
9968 };
9969 static const true_false_string tfs_device_char_read_only = {
9970         "This is a READ-ONLY device",
9971         "This is NOT a read-only device"
9972 };
9973 static const true_false_string tfs_device_char_floppy = {
9974         "This is a FLOPPY DISK device",
9975         "This is NOT a floppy disk device"
9976 };
9977 static const true_false_string tfs_device_char_write_once = {
9978         "This is a WRITE-ONCE device",
9979         "This is NOT a write-once device"
9980 };
9981 static const true_false_string tfs_device_char_remote = {
9982         "This is a REMOTE device",
9983         "This is NOT a remote device"
9984 };
9985 static const true_false_string tfs_device_char_mounted = {
9986         "This device is MOUNTED",
9987         "This device is NOT mounted"
9988 };
9989 static const true_false_string tfs_device_char_virtual = {
9990         "This is a VIRTUAL device",
9991         "This is NOT a virtual device"
9992 };
9993
9994
9995 static const true_false_string tfs_fs_attr_css = {
9996         "This FS supports CASE SENSITIVE SEARCHes",
9997         "This FS does NOT support case sensitive searches"
9998 };
9999 static const true_false_string tfs_fs_attr_cpn = {
10000         "This FS supports CASE PRESERVED NAMES",
10001         "This FS does NOT support case preserved names"
10002 };
10003 static const true_false_string tfs_fs_attr_pacls = {
10004         "This FS supports PERSISTENT ACLs",
10005         "This FS does NOT support persistent acls"
10006 };
10007 static const true_false_string tfs_fs_attr_fc = {
10008         "This FS supports COMPRESSED FILES",
10009         "This FS does NOT support compressed files"
10010 };
10011 static const true_false_string tfs_fs_attr_vq = {
10012         "This FS supports VOLUME QUOTAS",
10013         "This FS does NOT support volume quotas"
10014 };
10015 static const true_false_string tfs_fs_attr_dim = {
10016         "This FS is on a MOUNTED DEVICE",
10017         "This FS is NOT on a mounted device"
10018 };
10019 static const true_false_string tfs_fs_attr_vic = {
10020         "This FS is on a COMPRESSED VOLUME",
10021         "This FS is NOT on a compressed volume"
10022 };
10023
10024 #define FF2_RESUME      0x0004
10025
10026 static int
10027 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
10028 {
10029         guint16 mask;
10030         proto_item *item = NULL;
10031         proto_tree *tree = NULL;
10032         smb_info_t *si;
10033         smb_transact2_info_t *t2i;
10034
10035         mask = tvb_get_letohs(tvb, offset);
10036
10037         si = (smb_info_t *)pinfo->private_data;
10038         if (si->sip != NULL) {
10039                 t2i = si->sip->extra_info;
10040                 if (t2i != NULL) {
10041                         if (!pinfo->fd->flags.visited)
10042                                 t2i->resume_keys = (mask & FF2_RESUME);
10043                 }
10044         }
10045
10046         if(parent_tree){
10047                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10048                         "Flags: 0x%04x", mask);
10049                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
10050         }
10051
10052         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
10053                 tvb, offset, 2, mask);
10054         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
10055                 tvb, offset, 2, mask);
10056         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
10057                 tvb, offset, 2, mask);
10058         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
10059                 tvb, offset, 2, mask);
10060         proto_tree_add_boolean(tree, hf_smb_ff2_close,
10061                 tvb, offset, 2, mask);
10062
10063         offset += 2;
10064
10065         return offset;
10066 }
10067
10068 #if 0
10069 static int
10070 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10071 {
10072         guint16 mask;
10073         proto_item *item = NULL;
10074         proto_tree *tree = NULL;
10075
10076         mask = tvb_get_letohs(tvb, offset);
10077
10078         if(parent_tree){
10079                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10080                         "IO Flag: 0x%04x", mask);
10081                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10082         }
10083
10084         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10085                 tvb, offset, 2, mask);
10086         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10087                 tvb, offset, 2, mask);
10088
10089         offset += 2;
10090
10091         return offset;
10092 }
10093 #endif
10094
10095 static int
10096 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10097     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10098 {
10099         proto_item *item = NULL;
10100         proto_tree *tree = NULL;
10101         smb_info_t *si;
10102         smb_transact2_info_t *t2i;
10103         int fn_len;
10104         const char *fn;
10105
10106         si = (smb_info_t *)pinfo->private_data;
10107         if (si->sip != NULL)
10108                 t2i = si->sip->extra_info;
10109         else
10110                 t2i = NULL;
10111
10112         if(parent_tree){
10113                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10114                                 "%s Parameters",
10115                                 val_to_str(subcmd, trans2_cmd_vals,
10116                                            "Unknown (0x%02x)"));
10117                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10118         }
10119
10120         switch(subcmd){
10121         case 0x00:      /*TRANS2_OPEN2*/
10122                 /* open flags */
10123                 CHECK_BYTE_COUNT_TRANS(2);
10124                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10125                 bc -= 2;
10126
10127                 /* desired access */
10128                 CHECK_BYTE_COUNT_TRANS(2);
10129                 offset = dissect_access(tvb, tree, offset, "Desired");
10130                 bc -= 2;
10131
10132                 /* Search Attributes */
10133                 CHECK_BYTE_COUNT_TRANS(2);
10134                 offset = dissect_search_attributes(tvb, tree, offset);
10135                 bc -= 2;
10136
10137                 /* File Attributes */
10138                 CHECK_BYTE_COUNT_TRANS(2);
10139                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10140                 bc -= 2;
10141
10142                 /* create time */
10143                 CHECK_BYTE_COUNT_TRANS(4);
10144                 offset = dissect_smb_datetime(tvb, tree, offset,
10145                         hf_smb_create_time,
10146                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10147                         TRUE);
10148                 bc -= 4;
10149
10150                 /* open function */
10151                 CHECK_BYTE_COUNT_TRANS(2);
10152                 offset = dissect_open_function(tvb, tree, offset);
10153                 bc -= 2;
10154
10155                 /* allocation size */
10156                 CHECK_BYTE_COUNT_TRANS(4);
10157                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10158                 COUNT_BYTES_TRANS(4);
10159
10160                 /* 10 reserved bytes */
10161                 CHECK_BYTE_COUNT_TRANS(10);
10162                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10163                 COUNT_BYTES_TRANS(10);
10164
10165                 /* file name */
10166                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10167                 CHECK_STRING_TRANS(fn);
10168                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10169                         fn);
10170                 COUNT_BYTES_TRANS(fn_len);
10171
10172                 if (check_col(pinfo->cinfo, COL_INFO)) {
10173                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10174                         fn);
10175                 }
10176                 break;
10177         case 0x01:      /*TRANS2_FIND_FIRST2*/
10178                 /* Search Attributes */
10179                 CHECK_BYTE_COUNT_TRANS(2);
10180                 offset = dissect_search_attributes(tvb, tree, offset);
10181                 bc -= 2;
10182
10183                 /* search count */
10184                 CHECK_BYTE_COUNT_TRANS(2);
10185                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10186                 COUNT_BYTES_TRANS(2);
10187
10188                 /* Find First2 flags */
10189                 CHECK_BYTE_COUNT_TRANS(2);
10190                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10191                 bc -= 2;
10192
10193                 /* Find First2 information level */
10194                 CHECK_BYTE_COUNT_TRANS(2);
10195                 si->info_level = tvb_get_letohs(tvb, offset);
10196                 if (!pinfo->fd->flags.visited)
10197                         t2i->info_level = si->info_level;
10198                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10199                 COUNT_BYTES_TRANS(2);
10200
10201                 /* storage type */
10202                 CHECK_BYTE_COUNT_TRANS(4);
10203                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10204                 COUNT_BYTES_TRANS(4);
10205
10206                 /* search pattern */
10207                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10208                 CHECK_STRING_TRANS(fn);
10209                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10210                         fn);
10211                 COUNT_BYTES_TRANS(fn_len);
10212
10213                 if (check_col(pinfo->cinfo, COL_INFO)) {
10214                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10215                         fn);
10216                 }
10217
10218                 break;
10219         case 0x02:      /*TRANS2_FIND_NEXT2*/
10220                 /* sid */
10221                 CHECK_BYTE_COUNT_TRANS(2);
10222                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10223                 COUNT_BYTES_TRANS(2);
10224
10225                 /* search count */
10226                 CHECK_BYTE_COUNT_TRANS(2);
10227                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10228                 COUNT_BYTES_TRANS(2);
10229
10230                 /* Find First2 information level */
10231                 CHECK_BYTE_COUNT_TRANS(2);
10232                 si->info_level = tvb_get_letohs(tvb, offset);
10233                 if (!pinfo->fd->flags.visited)
10234                         t2i->info_level = si->info_level;
10235                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10236                 COUNT_BYTES_TRANS(2);
10237
10238                 /* resume key */
10239                 CHECK_BYTE_COUNT_TRANS(4);
10240                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10241                 COUNT_BYTES_TRANS(4);
10242
10243                 /* Find First2 flags */
10244                 CHECK_BYTE_COUNT_TRANS(2);
10245                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10246                 bc -= 2;
10247
10248                 /* file name */
10249                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10250                 CHECK_STRING_TRANS(fn);
10251                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10252                         fn);
10253                 COUNT_BYTES_TRANS(fn_len);
10254
10255                 if (check_col(pinfo->cinfo, COL_INFO)) {
10256                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10257                         fn);
10258                 }
10259
10260                 break;
10261         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10262                 /* level of interest */
10263                 CHECK_BYTE_COUNT_TRANS(2);
10264                 si->info_level = tvb_get_letohs(tvb, offset);
10265                 if (!pinfo->fd->flags.visited)
10266                         t2i->info_level = si->info_level;
10267                 proto_tree_add_uint(tree, hf_smb_qfsi_information_level, tvb, offset, 2, si->info_level);
10268                 COUNT_BYTES_TRANS(2);
10269
10270                 if (check_col(pinfo->cinfo, COL_INFO))
10271                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10272                                         val_to_str(si->info_level, qfsi_vals, 
10273                                                    "Unknown (0x%02x)"));
10274
10275                 break;
10276         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10277                 /* level of interest */
10278                 CHECK_BYTE_COUNT_TRANS(2);
10279                 si->info_level = tvb_get_letohs(tvb, offset);
10280                 if (!pinfo->fd->flags.visited)
10281                         t2i->info_level = si->info_level;
10282                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10283                 COUNT_BYTES_TRANS(2);
10284
10285                 if (check_col(pinfo->cinfo, COL_INFO)) {
10286                         col_append_fstr(
10287                                 pinfo->cinfo, COL_INFO, ", %s", 
10288                                 val_to_str(si->info_level, qpi_loi_vals, 
10289                                            "Unknown (%u)"));
10290                 }
10291
10292                 /* 4 reserved bytes */
10293                 CHECK_BYTE_COUNT_TRANS(4);
10294                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10295                 COUNT_BYTES_TRANS(4);
10296
10297                 /* file name */
10298                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10299                 CHECK_STRING_TRANS(fn);
10300                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10301                         fn);
10302                 COUNT_BYTES_TRANS(fn_len);
10303
10304                 if (check_col(pinfo->cinfo, COL_INFO)) {
10305                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10306                         fn);
10307                 }
10308
10309                 break;
10310         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10311                 /* level of interest */
10312                 CHECK_BYTE_COUNT_TRANS(2);
10313                 si->info_level = tvb_get_letohs(tvb, offset);
10314                 if (!pinfo->fd->flags.visited)
10315                         t2i->info_level = si->info_level;
10316                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10317                 COUNT_BYTES_TRANS(2);
10318
10319                 /* 4 reserved bytes */
10320                 CHECK_BYTE_COUNT_TRANS(4);
10321                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10322                 COUNT_BYTES_TRANS(4);
10323
10324                 /* file name */
10325                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10326                 CHECK_STRING_TRANS(fn);
10327                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10328                         fn);
10329                 COUNT_BYTES_TRANS(fn_len);
10330
10331                 if (check_col(pinfo->cinfo, COL_INFO)) {
10332                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10333                         fn);
10334                 }
10335
10336                 break;
10337         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10338                 guint16 fid;
10339
10340                 /* fid */
10341                 CHECK_BYTE_COUNT_TRANS(2);
10342                 fid = tvb_get_letohs(tvb, offset);
10343                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10344                 COUNT_BYTES_TRANS(2);
10345
10346                 /* level of interest */
10347                 CHECK_BYTE_COUNT_TRANS(2);
10348                 si->info_level = tvb_get_letohs(tvb, offset);
10349                 if (!pinfo->fd->flags.visited)
10350                         t2i->info_level = si->info_level;
10351                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10352                 COUNT_BYTES_TRANS(2);
10353
10354                 if (check_col(pinfo->cinfo, COL_INFO)) {
10355                         col_append_fstr(
10356                                 pinfo->cinfo, COL_INFO, ", %s", 
10357                                 val_to_str(si->info_level, qpi_loi_vals, 
10358                                            "Unknown (%u)"));
10359                 }
10360
10361                 break;
10362         }
10363         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10364                 guint16 fid;
10365
10366                 /* fid */
10367                 CHECK_BYTE_COUNT_TRANS(2);
10368                 fid = tvb_get_letohs(tvb, offset);
10369                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10370                 COUNT_BYTES_TRANS(2);
10371
10372                 /* level of interest */
10373                 CHECK_BYTE_COUNT_TRANS(2);
10374                 si->info_level = tvb_get_letohs(tvb, offset);
10375                 if (!pinfo->fd->flags.visited)
10376                         t2i->info_level = si->info_level;
10377                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10378                 COUNT_BYTES_TRANS(2);
10379
10380 #if 0
10381                 /*
10382                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10383                  * Extensions Version 3.0, Document Version 1.11,
10384                  * July 19, 1990" says this is I/O flags, but it's
10385                  * reserved in the SNIA spec, and some clients appear
10386                  * to leave junk in it.
10387                  *
10388                  * Is this some field used only if a particular
10389                  * dialect was negotiated, so that clients can feel
10390                  * safe not setting it if they haven't negotiated that
10391                  * dialect?  Or do the (non-OS/2) clients simply not care
10392                  * about that particular OS/2-oriented dialect?
10393                  */
10394
10395                 /* IO Flag */
10396                 CHECK_BYTE_COUNT_TRANS(2);
10397                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10398                 bc -= 2;
10399 #else
10400                 /* 2 reserved bytes */
10401                 CHECK_BYTE_COUNT_TRANS(2);
10402                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10403                 COUNT_BYTES_TRANS(2);
10404 #endif
10405
10406                 break;
10407         }
10408         case 0x09:      /*TRANS2_FSCTL*/
10409                 /* this call has no parameter block in the request */
10410
10411                 /*
10412                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10413                  * Extensions Version 3.0, Document Version 1.11,
10414                  * July 19, 1990" says this this contains a
10415                  * "File system specific parameter block".  (That means
10416                  * we may not be able to dissect it in any case.)
10417                  */
10418                 break;
10419         case 0x0a:      /*TRANS2_IOCTL2*/
10420                 /* this call has no parameter block in the request */
10421
10422                 /*
10423                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10424                  * Extensions Version 3.0, Document Version 1.11,
10425                  * July 19, 1990" says this this contains a
10426                  * "Device/function specific parameter block".  (That
10427                  * means we may not be able to dissect it in any case.)
10428                  */
10429                 break;
10430         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10431                 /* Search Attributes */
10432                 CHECK_BYTE_COUNT_TRANS(2);
10433                 offset = dissect_search_attributes(tvb, tree, offset);
10434                 bc -= 2;
10435
10436                 /* Number of changes to wait for */
10437                 CHECK_BYTE_COUNT_TRANS(2);
10438                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10439                 COUNT_BYTES_TRANS(2);
10440
10441                 /* Find Notify information level */
10442                 CHECK_BYTE_COUNT_TRANS(2);
10443                 si->info_level = tvb_get_letohs(tvb, offset);
10444                 if (!pinfo->fd->flags.visited)
10445                         t2i->info_level = si->info_level;
10446                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, offset, 2, si->info_level);
10447                 COUNT_BYTES_TRANS(2);
10448
10449                 /* 4 reserved bytes */
10450                 CHECK_BYTE_COUNT_TRANS(4);
10451                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10452                 COUNT_BYTES_TRANS(4);
10453
10454                 /* file name */
10455                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10456                 CHECK_STRING_TRANS(fn);
10457                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10458                         fn);
10459                 COUNT_BYTES_TRANS(fn_len);
10460
10461                 if (check_col(pinfo->cinfo, COL_INFO)) {
10462                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10463                         fn);
10464                 }
10465
10466                 break;
10467         }
10468         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10469                 /* Monitor handle */
10470                 CHECK_BYTE_COUNT_TRANS(2);
10471                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10472                 COUNT_BYTES_TRANS(2);
10473
10474                 /* Number of changes to wait for */
10475                 CHECK_BYTE_COUNT_TRANS(2);
10476                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10477                 COUNT_BYTES_TRANS(2);
10478
10479                 break;
10480         }
10481         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10482                 /* 4 reserved bytes */
10483                 CHECK_BYTE_COUNT_TRANS(4);
10484                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10485                 COUNT_BYTES_TRANS(4);
10486
10487                 /* dir name */
10488                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10489                         FALSE, FALSE, &bc);
10490                 CHECK_STRING_TRANS(fn);
10491                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10492                         fn);
10493                 COUNT_BYTES_TRANS(fn_len);
10494
10495                 if (check_col(pinfo->cinfo, COL_INFO)) {
10496                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10497                         fn);
10498                 }
10499                 break;
10500         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10501                 /* XXX unknown structure*/
10502                 break;
10503         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10504                 /* referral level */
10505                 CHECK_BYTE_COUNT_TRANS(2);
10506                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10507                 COUNT_BYTES_TRANS(2);
10508
10509                 /* file name */
10510                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10511                 CHECK_STRING_TRANS(fn);
10512                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10513                         fn);
10514                 COUNT_BYTES_TRANS(fn_len);
10515
10516                 if (check_col(pinfo->cinfo, COL_INFO)) {
10517                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10518                         fn);
10519                 }
10520
10521                 break;
10522         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
10523                 /* file name */
10524                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10525                 CHECK_STRING_TRANS(fn);
10526                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10527                         fn);
10528                 COUNT_BYTES_TRANS(fn_len);
10529
10530                 if (check_col(pinfo->cinfo, COL_INFO)) {
10531                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10532                         fn);
10533                 }
10534
10535                 break;
10536         }
10537
10538         /* ooops there were data we didnt know how to process */
10539         if(bc != 0){
10540                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10541                 offset += bc;
10542         }
10543
10544         return offset;
10545 }
10546
10547 /*
10548  * XXX - just use "dissect_connect_flags()" here?
10549  */
10550 static guint16
10551 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10552 {
10553         guint16 mask;
10554         proto_item *item = NULL;
10555         proto_tree *tree = NULL;
10556
10557         mask = tvb_get_letohs(tvb, offset);
10558
10559         if(parent_tree){
10560                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10561                         "Flags: 0x%04x", mask);
10562                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10563         }
10564
10565         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10566                 tvb, offset, 2, mask);
10567         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10568                 tvb, offset, 2, mask);
10569
10570         return mask;
10571 }
10572
10573
10574 static int
10575 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10576 {
10577         guint16 mask;
10578         proto_item *item = NULL;
10579         proto_tree *tree = NULL;
10580
10581         mask = tvb_get_letohs(tvb, offset);
10582
10583         if(parent_tree){
10584                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10585                         "Flags: 0x%04x", mask);
10586                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10587         }
10588
10589         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10590                 tvb, offset, 2, mask);
10591         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10592                 tvb, offset, 2, mask);
10593
10594         offset += 2;
10595         return offset;
10596 }
10597
10598 static int
10599 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10600 {
10601         guint16 mask;
10602         proto_item *item = NULL;
10603         proto_tree *tree = NULL;
10604
10605         mask = tvb_get_letohs(tvb, offset);
10606
10607         if(parent_tree){
10608                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10609                         "Flags: 0x%04x", mask);
10610                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10611         }
10612
10613         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10614                 tvb, offset, 2, mask);
10615
10616         offset += 2;
10617
10618         return offset;
10619 }
10620
10621
10622 /* dfs inconsistency data  (4.4.2)
10623 */
10624 static int
10625 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10626     proto_tree *tree, int offset, guint16 *bcp)
10627 {
10628         smb_info_t *si = pinfo->private_data;
10629         int fn_len;
10630         const char *fn;
10631
10632         /*XXX shouldn this data hold version and size? unclear from doc*/
10633         /* referral version */
10634         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10635         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10636         COUNT_BYTES_TRANS_SUBR(2);
10637
10638         /* referral size */
10639         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10640         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10641         COUNT_BYTES_TRANS_SUBR(2);
10642
10643         /* referral server type */
10644         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10645         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10646         COUNT_BYTES_TRANS_SUBR(2);
10647
10648         /* referral flags */
10649         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10650         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10651         *bcp -= 2;
10652
10653         /* node name */
10654         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10655         CHECK_STRING_TRANS_SUBR(fn);
10656         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10657                 fn);
10658         COUNT_BYTES_TRANS_SUBR(fn_len);
10659
10660         return offset;
10661 }
10662
10663 /* get dfs referral data  (4.4.1)
10664 */
10665 static int
10666 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10667     proto_tree *tree, int offset, guint16 *bcp)
10668 {
10669         smb_info_t *si = pinfo->private_data;
10670         guint16 numref;
10671         guint16 refsize;
10672         guint16 pathoffset;
10673         guint16 altpathoffset;
10674         guint16 nodeoffset;
10675         int fn_len;
10676         int stroffset;
10677         int offsetoffset;
10678         guint16 save_bc;
10679         const char *fn;
10680         int unklen;
10681         int ucstring_end;
10682         int ucstring_len;
10683
10684         /* path consumed */
10685         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10686         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10687         COUNT_BYTES_TRANS_SUBR(2);
10688
10689         /* num referrals */
10690         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10691         numref = tvb_get_letohs(tvb, offset);
10692         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10693         COUNT_BYTES_TRANS_SUBR(2);
10694
10695         /* get dfs flags */
10696         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10697         offset = dissect_get_dfs_flags(tvb, tree, offset);
10698         *bcp -= 2;
10699
10700         /* XXX - in at least one capture there appears to be 2 bytes
10701            of stuff after the Dfs flags, perhaps so that the header
10702            in front of the referral list is a multiple of 4 bytes long. */
10703         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10704         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10705         COUNT_BYTES_TRANS_SUBR(2);
10706
10707         /* if there are any referrals */
10708         if(numref){
10709                 proto_item *ref_item = NULL;
10710                 proto_tree *ref_tree = NULL;
10711                 int old_offset=offset;
10712
10713                 if(tree){
10714                         ref_item = proto_tree_add_text(tree,
10715                                 tvb, offset, *bcp, "Referrals");
10716                         ref_tree = proto_item_add_subtree(ref_item,
10717                                 ett_smb_dfs_referrals);
10718                 }
10719                 ucstring_end = -1;
10720
10721                 while(numref--){
10722                         proto_item *ri = NULL;
10723                         proto_tree *rt = NULL;
10724                         int old_offset=offset;
10725                         guint16 version;
10726
10727                         if(tree){
10728                                 ri = proto_tree_add_text(ref_tree,
10729                                         tvb, offset, *bcp, "Referral");
10730                                 rt = proto_item_add_subtree(ri,
10731                                         ett_smb_dfs_referral);
10732                         }
10733
10734                         /* referral version */
10735                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10736                         version = tvb_get_letohs(tvb, offset);
10737                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10738                                 tvb, offset, 2, version);
10739                         COUNT_BYTES_TRANS_SUBR(2);
10740
10741                         /* referral size */
10742                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10743                         refsize = tvb_get_letohs(tvb, offset);
10744                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10745                         COUNT_BYTES_TRANS_SUBR(2);
10746
10747                         /* referral server type */
10748                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10749                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10750                         COUNT_BYTES_TRANS_SUBR(2);
10751
10752                         /* referral flags */
10753                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10754                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10755                         *bcp -= 2;
10756
10757                         switch(version){
10758
10759                         case 1:
10760                                 /* node name */
10761                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10762                                 CHECK_STRING_TRANS_SUBR(fn);
10763                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10764                                         fn);
10765                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10766                                 break;
10767
10768                         case 2:
10769                         case 3: /* XXX - like version 2, but not identical;
10770                                    seen in a capture, but the format isn't
10771                                    documented */
10772                                 /* proximity */
10773                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10774                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10775                                 COUNT_BYTES_TRANS_SUBR(2);
10776
10777                                 /* ttl */
10778                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10779                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10780                                 COUNT_BYTES_TRANS_SUBR(2);
10781
10782                                 /* path offset */
10783                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10784                                 pathoffset = tvb_get_letohs(tvb, offset);
10785                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10786                                 COUNT_BYTES_TRANS_SUBR(2);
10787
10788                                 /* alt path offset */
10789                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10790                                 altpathoffset = tvb_get_letohs(tvb, offset);
10791                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10792                                 COUNT_BYTES_TRANS_SUBR(2);
10793
10794                                 /* node offset */
10795                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10796                                 nodeoffset = tvb_get_letohs(tvb, offset);
10797                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10798                                 COUNT_BYTES_TRANS_SUBR(2);
10799
10800                                 /* path */
10801                                 if (pathoffset != 0) {
10802                                         stroffset = old_offset + pathoffset;
10803                                         offsetoffset = stroffset - offset;
10804                                         if (offsetoffset > 0 &&
10805                                             *bcp > offsetoffset) {
10806                                                 save_bc = *bcp;
10807                                                 *bcp -= offsetoffset;
10808                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10809                                                 CHECK_STRING_TRANS_SUBR(fn);
10810                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10811                                                         fn);
10812                                                 stroffset += fn_len;
10813                                                 if (ucstring_end < stroffset)
10814                                                         ucstring_end = stroffset;
10815                                                 *bcp = save_bc;
10816                                         }
10817                                 }
10818
10819                                 /* alt path */
10820                                 if (altpathoffset != 0) {
10821                                         stroffset = old_offset + altpathoffset;
10822                                         offsetoffset = stroffset - offset;
10823                                         if (offsetoffset > 0 &&
10824                                             *bcp > offsetoffset) {
10825                                                 save_bc = *bcp;
10826                                                 *bcp -= offsetoffset;
10827                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10828                                                 CHECK_STRING_TRANS_SUBR(fn);
10829                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10830                                                         fn);
10831                                                 stroffset += fn_len;
10832                                                 if (ucstring_end < stroffset)
10833                                                         ucstring_end = stroffset;
10834                                                 *bcp = save_bc;
10835                                         }
10836                                 }
10837
10838                                 /* node */
10839                                 if (nodeoffset != 0) {
10840                                         stroffset = old_offset + nodeoffset;
10841                                         offsetoffset = stroffset - offset;
10842                                         if (offsetoffset > 0 &&
10843                                             *bcp > offsetoffset) {
10844                                                 save_bc = *bcp;
10845                                                 *bcp -= offsetoffset;
10846                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10847                                                 CHECK_STRING_TRANS_SUBR(fn);
10848                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10849                                                         fn);
10850                                                 stroffset += fn_len;
10851                                                 if (ucstring_end < stroffset)
10852                                                         ucstring_end = stroffset;
10853                                                 *bcp = save_bc;
10854                                         }
10855                                 }
10856                                 break;
10857                         }
10858
10859                         /*
10860                          * Show anything beyond the length of the referral
10861                          * as unknown data.
10862                          */
10863                         unklen = (old_offset + refsize) - offset;
10864                         if (unklen < 0) {
10865                                 /*
10866                                  * XXX - the length is bogus.
10867                                  */
10868                                 unklen = 0;
10869                         }
10870                         if (unklen != 0) {
10871                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10872                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10873                                     offset, unklen, TRUE);
10874                                 COUNT_BYTES_TRANS_SUBR(unklen);
10875                         }
10876
10877                         proto_item_set_len(ri, offset-old_offset);
10878                 }
10879
10880                 /*
10881                  * Treat the offset past the end of the last Unicode
10882                  * string after the referrals (if any) as the last
10883                  * offset.
10884                  */
10885                 if (ucstring_end > offset) {
10886                         ucstring_len = ucstring_end - offset;
10887                         if (*bcp < ucstring_len)
10888                                 ucstring_len = *bcp;
10889                         offset += ucstring_len;
10890                         *bcp -= ucstring_len;
10891                 }
10892                 proto_item_set_len(ref_item, offset-old_offset);
10893         }
10894
10895         return offset;
10896 }
10897
10898
10899 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10900    as described in 4.2.16.1
10901 */
10902 static int
10903 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10904     int offset, guint16 *bcp, gboolean *trunc)
10905 {
10906         /* create time */
10907         CHECK_BYTE_COUNT_SUBR(4);
10908         offset = dissect_smb_datetime(tvb, tree, offset,
10909                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10910                 FALSE);
10911         *bcp -= 4;
10912
10913         /* access time */
10914         CHECK_BYTE_COUNT_SUBR(4);
10915         offset = dissect_smb_datetime(tvb, tree, offset,
10916                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10917                 FALSE);
10918         *bcp -= 4;
10919
10920         /* last write time */
10921         CHECK_BYTE_COUNT_SUBR(4);
10922         offset = dissect_smb_datetime(tvb, tree, offset,
10923                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10924                 FALSE);
10925         *bcp -= 4;
10926
10927         /* data size */
10928         CHECK_BYTE_COUNT_SUBR(4);
10929         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10930         COUNT_BYTES_SUBR(4);
10931
10932         /* allocation size */
10933         CHECK_BYTE_COUNT_SUBR(4);
10934         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10935         COUNT_BYTES_SUBR(4);
10936
10937         /* File Attributes */
10938         CHECK_BYTE_COUNT_SUBR(2);
10939         offset = dissect_file_attributes(tvb, tree, offset, 2);
10940         *bcp -= 2;
10941
10942         /* ea length */
10943         CHECK_BYTE_COUNT_SUBR(4);
10944         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10945         COUNT_BYTES_SUBR(4);
10946
10947         *trunc = FALSE;
10948         return offset;
10949 }
10950
10951 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10952    as described in 4.2.16.2
10953 */
10954 static int
10955 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10956     int offset, guint16 *bcp, gboolean *trunc)
10957 {
10958         guint8 name_len;
10959         guint16 data_len;
10960         /* EA size */
10961
10962         CHECK_BYTE_COUNT_SUBR(4);
10963         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10964         COUNT_BYTES_SUBR(4);
10965
10966         while (*bcp > 0) {
10967                 proto_item *item;
10968                 proto_tree *subtree;
10969                 int start_offset = offset;
10970                 guint8 *name;
10971
10972                 item = proto_tree_add_text(
10973                         tree, tvb, offset, 0, "Extended Attribute");
10974                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10975
10976                 /* EA flags */
10977                 
10978                 CHECK_BYTE_COUNT_SUBR(1);
10979                 proto_tree_add_item(
10980                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10981                 COUNT_BYTES_SUBR(1);
10982
10983                 /* EA name length */
10984                 
10985                 name_len = tvb_get_guint8(tvb, offset);
10986
10987                 CHECK_BYTE_COUNT_SUBR(1);
10988                 proto_tree_add_item(
10989                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10990                 COUNT_BYTES_SUBR(1);
10991
10992                 /* EA data length */
10993
10994                 data_len = tvb_get_letohs(tvb, offset);
10995                 
10996                 CHECK_BYTE_COUNT_SUBR(2);
10997                 proto_tree_add_item(
10998                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10999                 COUNT_BYTES_SUBR(2);
11000
11001                 /* EA name */
11002
11003                 name = tvb_get_string(tvb, offset, name_len);
11004                 proto_item_append_text(item, ": %s", name);
11005                 g_free(name);
11006
11007                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
11008                 proto_tree_add_item(
11009                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
11010                         TRUE);
11011                 COUNT_BYTES_SUBR(name_len + 1);
11012
11013                 /* EA data */
11014                 
11015                 CHECK_BYTE_COUNT_SUBR(data_len);
11016                 proto_tree_add_item(
11017                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
11018                 COUNT_BYTES_SUBR(data_len);
11019
11020                 proto_item_set_len(item, offset - start_offset);
11021         }
11022
11023         *trunc = FALSE;
11024         return offset;
11025 }
11026
11027 /* this dissects the SMB_INFO_IS_NAME_VALID
11028    as described in 4.2.16.3
11029 */
11030 static int
11031 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11032     int offset, guint16 *bcp, gboolean *trunc)
11033 {
11034         smb_info_t *si = pinfo->private_data;
11035         int fn_len;
11036         const char *fn;
11037
11038         /* file name */
11039         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11040         CHECK_STRING_SUBR(fn);
11041         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11042                 fn);
11043         COUNT_BYTES_SUBR(fn_len);
11044
11045         *trunc = FALSE;
11046         return offset;
11047 }
11048
11049 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
11050    as described in 4.2.16.4
11051 */
11052 static int
11053 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11054     int offset, guint16 *bcp, gboolean *trunc)
11055 {
11056         /* create time */
11057         CHECK_BYTE_COUNT_SUBR(8);
11058         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
11059         *bcp -= 8;
11060
11061         /* access time */
11062         CHECK_BYTE_COUNT_SUBR(8);
11063         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
11064         *bcp -= 8;
11065
11066         /* last write time */
11067         CHECK_BYTE_COUNT_SUBR(8);
11068         offset = dissect_smb_64bit_time(tvb, tree, offset,
11069                 hf_smb_last_write_time);
11070         *bcp -= 8;
11071
11072         /* last change time */
11073         CHECK_BYTE_COUNT_SUBR(8);
11074         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11075         *bcp -= 8;
11076
11077         /* File Attributes */
11078         CHECK_BYTE_COUNT_SUBR(4);
11079         offset = dissect_file_attributes(tvb, tree, offset, 4);
11080         *bcp -= 4;
11081
11082         *trunc = FALSE;
11083         return offset;
11084 }
11085
11086 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11087    as described in 4.2.16.5
11088 */
11089 static int
11090 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11091     int offset, guint16 *bcp, gboolean *trunc)
11092 {
11093         /* allocation size */
11094         CHECK_BYTE_COUNT_SUBR(8);
11095         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11096         COUNT_BYTES_SUBR(8);
11097
11098         /* end of file */
11099         CHECK_BYTE_COUNT_SUBR(8);
11100         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11101         COUNT_BYTES_SUBR(8);
11102
11103         /* number of links */
11104         CHECK_BYTE_COUNT_SUBR(4);
11105         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11106         COUNT_BYTES_SUBR(4);
11107
11108         /* delete pending */
11109         CHECK_BYTE_COUNT_SUBR(1);
11110         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11111         COUNT_BYTES_SUBR(1);
11112
11113         /* is directory */
11114         CHECK_BYTE_COUNT_SUBR(1);
11115         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11116         COUNT_BYTES_SUBR(1);
11117
11118         *trunc = FALSE;
11119         return offset;
11120 }
11121
11122 /* this dissects the SMB_QUERY_FILE_EA_INFO
11123    as described in 4.2.16.6
11124 */
11125 static int
11126 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11127     int offset, guint16 *bcp, gboolean *trunc)
11128 {
11129         /* ea length */
11130         CHECK_BYTE_COUNT_SUBR(4);
11131         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11132         COUNT_BYTES_SUBR(4);
11133
11134         *trunc = FALSE;
11135         return offset;
11136 }
11137
11138 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11139    as described in 4.2.16.7
11140    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11141    as described in 4.2.16.9
11142 */
11143 static int
11144 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11145     int offset, guint16 *bcp, gboolean *trunc)
11146 {
11147         smb_info_t *si = pinfo->private_data;
11148         int fn_len;
11149         const char *fn;
11150
11151         /* file name len */
11152         CHECK_BYTE_COUNT_SUBR(4);
11153         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11154         COUNT_BYTES_SUBR(4);
11155
11156         /* file name */
11157         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11158         CHECK_STRING_SUBR(fn);
11159         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11160                 fn);
11161         COUNT_BYTES_SUBR(fn_len);
11162
11163         *trunc = FALSE;
11164         return offset;
11165 }
11166
11167 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11168    as described in 4.2.16.8
11169 */
11170 static int
11171 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11172     int offset, guint16 *bcp, gboolean *trunc)
11173 {
11174
11175         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
11176         if (*trunc) {
11177                 return offset;
11178         }
11179         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
11180         if (*trunc) {
11181                 return offset;
11182         }
11183
11184         /* index number */
11185         CHECK_BYTE_COUNT_SUBR(8);
11186         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11187         COUNT_BYTES_SUBR(8);
11188
11189         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11190         if (*trunc)
11191                 return offset;
11192
11193         /* access flags */
11194         CHECK_BYTE_COUNT_SUBR(4);
11195         offset = dissect_smb_access_mask(tvb, tree, offset);
11196         COUNT_BYTES_SUBR(4);
11197
11198         /* index number */
11199         CHECK_BYTE_COUNT_SUBR(8);
11200         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11201         COUNT_BYTES_SUBR(8);
11202
11203         /* current offset */
11204         CHECK_BYTE_COUNT_SUBR(8);
11205         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
11206         COUNT_BYTES_SUBR(8);
11207
11208         /* mode */
11209         CHECK_BYTE_COUNT_SUBR(4);
11210         offset = dissect_nt_create_options(tvb, tree, offset);
11211         *bcp -= 4;
11212
11213         /* alignment */
11214         CHECK_BYTE_COUNT_SUBR(4);
11215         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11216         COUNT_BYTES_SUBR(4);
11217
11218         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11219
11220         return offset;
11221 }
11222
11223 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11224    as described in 4.2.16.10
11225 */
11226 static int
11227 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11228     int offset, guint16 *bcp, gboolean *trunc)
11229 {
11230         proto_item *item;
11231         proto_tree *tree;
11232         int old_offset;
11233         guint32 neo;
11234         smb_info_t *si = pinfo->private_data;
11235         int fn_len;
11236         const char *fn;
11237         int padcnt;
11238
11239         for (;;) {
11240                 old_offset = offset;
11241
11242                 /* next entry offset */
11243                 CHECK_BYTE_COUNT_SUBR(4);
11244                 if(parent_tree){
11245                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11246                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11247                 } else {
11248                         item = NULL;
11249                         tree = NULL;
11250                 }
11251
11252                 neo = tvb_get_letohl(tvb, offset);
11253                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11254                 COUNT_BYTES_SUBR(4);
11255
11256                 /* stream name len */
11257                 CHECK_BYTE_COUNT_SUBR(4);
11258                 fn_len = tvb_get_letohl(tvb, offset);
11259                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11260                 COUNT_BYTES_SUBR(4);
11261
11262                 /* stream size */
11263                 CHECK_BYTE_COUNT_SUBR(8);
11264                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11265                 COUNT_BYTES_SUBR(8);
11266
11267                 /* allocation size */
11268                 CHECK_BYTE_COUNT_SUBR(8);
11269                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11270                 COUNT_BYTES_SUBR(8);
11271
11272                 /* stream name */
11273                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11274                 CHECK_STRING_SUBR(fn);
11275                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11276                         fn);
11277                 COUNT_BYTES_SUBR(fn_len);
11278
11279                 proto_item_append_text(item, ": %s", fn);
11280                 proto_item_set_len(item, offset-old_offset);
11281
11282                 if (neo == 0)
11283                         break;  /* no more structures */
11284
11285                 /* skip to next structure */
11286                 padcnt = (old_offset + neo) - offset;
11287                 if (padcnt < 0) {
11288                         /*
11289                          * XXX - this is bogus; flag it?
11290                          */
11291                         padcnt = 0;
11292                 }
11293                 if (padcnt != 0) {
11294                         CHECK_BYTE_COUNT_SUBR(padcnt);
11295                         COUNT_BYTES_SUBR(padcnt);
11296                 }
11297         }
11298
11299         *trunc = FALSE;
11300         return offset;
11301 }
11302
11303 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11304    as described in 4.2.16.11
11305 */
11306 static int
11307 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11308     int offset, guint16 *bcp, gboolean *trunc)
11309 {
11310         /* compressed file size */
11311         CHECK_BYTE_COUNT_SUBR(8);
11312         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11313         COUNT_BYTES_SUBR(8);
11314
11315         /* compression format */
11316         CHECK_BYTE_COUNT_SUBR(2);
11317         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11318         COUNT_BYTES_SUBR(2);
11319
11320         /* compression unit shift */
11321         CHECK_BYTE_COUNT_SUBR(1);
11322         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11323         COUNT_BYTES_SUBR(1);
11324
11325         /* compression chunk shift */
11326         CHECK_BYTE_COUNT_SUBR(1);
11327         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11328         COUNT_BYTES_SUBR(1);
11329
11330         /* compression cluster shift */
11331         CHECK_BYTE_COUNT_SUBR(1);
11332         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11333         COUNT_BYTES_SUBR(1);
11334
11335         /* 3 reserved bytes */
11336         CHECK_BYTE_COUNT_SUBR(3);
11337         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11338         COUNT_BYTES_SUBR(3);
11339
11340         *trunc = FALSE;
11341         return offset;
11342 }
11343
11344 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11345
11346 static const value_string unix_file_type_vals[] = {
11347         { 0, "File" },
11348         { 1, "Directory" },
11349         { 2, "Symbolic link" },
11350         { 3, "Character device" },
11351         { 4, "Block device" },
11352         { 5, "FIFO" },
11353         { 6, "Socket" },
11354         { 0, NULL }
11355 };
11356
11357 static int
11358 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11359                   int offset, guint16 *bcp, gboolean *trunc)
11360 {
11361         /* End of file (file size) */
11362         CHECK_BYTE_COUNT_SUBR(8);
11363         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11364         COUNT_BYTES_SUBR(8);
11365
11366         /* Number of bytes */
11367         CHECK_BYTE_COUNT_SUBR(8);
11368         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11369         COUNT_BYTES_SUBR(8);
11370
11371         /* Last status change */
11372         CHECK_BYTE_COUNT_SUBR(8);
11373         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11374         *bcp -= 8;              /* dissect_smb_64bit_time() increments offset */
11375
11376         /* Last access time */
11377         CHECK_BYTE_COUNT_SUBR(8);
11378         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11379         *bcp -= 8;
11380
11381         /* Last modification time */
11382         CHECK_BYTE_COUNT_SUBR(8);
11383         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11384         *bcp -= 8;
11385
11386         /* File owner uid */
11387         CHECK_BYTE_COUNT_SUBR(8);
11388         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11389         COUNT_BYTES_SUBR(8);
11390
11391         /* File group gid */
11392         CHECK_BYTE_COUNT_SUBR(8);
11393         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11394         COUNT_BYTES_SUBR(8);
11395
11396         /* File type */
11397         CHECK_BYTE_COUNT_SUBR(4);
11398         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11399         COUNT_BYTES_SUBR(4);
11400
11401         /* Major device number */
11402         CHECK_BYTE_COUNT_SUBR(8);
11403         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11404         COUNT_BYTES_SUBR(8);
11405
11406         /* Minor device number */
11407         CHECK_BYTE_COUNT_SUBR(8);
11408         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11409         COUNT_BYTES_SUBR(8);
11410
11411         /* Unique id */
11412         CHECK_BYTE_COUNT_SUBR(8);
11413         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11414         COUNT_BYTES_SUBR(8);
11415
11416         /* Permissions */
11417         CHECK_BYTE_COUNT_SUBR(8);
11418         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11419         COUNT_BYTES_SUBR(8);
11420
11421         /* Nlinks */
11422         CHECK_BYTE_COUNT_SUBR(8);
11423         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11424         COUNT_BYTES_SUBR(8);
11425
11426         /* Sometimes there is one extra byte in the data field which I
11427            guess could be padding, but we are only using 4 or 8 byte
11428            data types so this is a bit confusing. -tpot */
11429
11430         *trunc = FALSE;
11431         return offset;
11432 }
11433
11434 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11435
11436 static int
11437 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11438                   int offset, guint16 *bcp, gboolean *trunc)
11439 {
11440         smb_info_t *si = pinfo->private_data;
11441         const char *fn;
11442         int fn_len;
11443
11444         /* Link destination */
11445
11446         fn = get_unicode_or_ascii_string(
11447                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11448
11449         CHECK_STRING_SUBR(fn);
11450         proto_tree_add_string(
11451                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11452         COUNT_BYTES_SUBR(fn_len);
11453
11454         *trunc = FALSE;
11455         return offset;
11456 }
11457
11458 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11459    as described in 4.2.19.2
11460 */
11461 static int
11462 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11463     int offset, guint16 *bcp, gboolean *trunc)
11464 {
11465         /* marked for deletion? */
11466         CHECK_BYTE_COUNT_SUBR(1);
11467         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11468         COUNT_BYTES_SUBR(1);
11469
11470         *trunc = FALSE;
11471         return offset;
11472 }
11473
11474 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11475    as described in 4.2.19.3
11476 */
11477 static int
11478 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11479     int offset, guint16 *bcp, gboolean *trunc)
11480 {
11481         /* file allocation size */
11482         CHECK_BYTE_COUNT_SUBR(8);
11483         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11484         COUNT_BYTES_SUBR(8);
11485
11486         *trunc = FALSE;
11487         return offset;
11488 }
11489
11490 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11491    as described in 4.2.19.4
11492 */
11493 static int
11494 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11495     int offset, guint16 *bcp, gboolean *trunc)
11496 {
11497         /* file end of file offset */
11498         CHECK_BYTE_COUNT_SUBR(8);
11499         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11500         COUNT_BYTES_SUBR(8);
11501
11502         *trunc = FALSE;
11503         return offset;
11504 }
11505
11506 /* Set File Rename Info */
11507
11508 static const true_false_string tfs_smb_replace = {
11509         "Remove target file if it exists",
11510         "Do NOT remove target file if it exists",
11511 };
11512
11513 static int
11514 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11515                     int offset, guint16 *bcp, gboolean *trunc)
11516 {
11517         smb_info_t *si = pinfo->private_data;
11518         const char *fn;
11519         guint32 target_name_len;
11520         int fn_len;
11521
11522         /* Replace flag */
11523         CHECK_BYTE_COUNT_SUBR(4);
11524         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
11525         COUNT_BYTES_SUBR(4);
11526
11527         /* Root directory handle */
11528         CHECK_BYTE_COUNT_SUBR(4);
11529         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
11530         COUNT_BYTES_SUBR(4);
11531
11532         /* Target name length */
11533         CHECK_BYTE_COUNT_SUBR(4);
11534         target_name_len = tvb_get_letohl(tvb, offset);
11535         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
11536         COUNT_BYTES_SUBR(4);
11537
11538         /* Target name */
11539         fn_len = target_name_len;
11540         fn = get_unicode_or_ascii_string(
11541                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11542
11543         CHECK_STRING_SUBR(fn);
11544         proto_tree_add_string(
11545                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
11546         COUNT_BYTES_SUBR(fn_len);
11547
11548         *trunc = FALSE;
11549         return offset;
11550 }
11551
11552 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11553   TRANS2_QUERY_FILE_INFORMATION*/
11554 static int
11555 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11556     int offset, guint16 *bcp)
11557 {
11558         smb_info_t *si;
11559         gboolean trunc;
11560
11561         if(!*bcp){
11562                 return offset;
11563         }
11564
11565         si = (smb_info_t *)pinfo->private_data;
11566         switch(si->info_level){
11567         case 1:         /*Info Standard*/
11568                 
11569         case 2:         /*Info Query EA Size*/
11570                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11571                     &trunc);
11572                 break;
11573         case 3:         /*Info Query EAs From List*/
11574         case 4:         /*Info Query All EAs*/
11575                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11576                     &trunc);
11577                 break;
11578         case 6:         /*Info Is Name Valid*/
11579                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11580                     &trunc);
11581                 break;
11582         case 0x0101:    /*Query File Basic Info*/
11583         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11584                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11585                     &trunc);
11586                 break;
11587         case 0x0102:    /*Query File Standard Info*/
11588         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11589                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11590                     &trunc);
11591                 break;
11592         case 0x0103:    /*Query File EA Info*/
11593         case 1007:      /* SMB_FILE_EA_INFORMATION */
11594                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11595                     &trunc);
11596                 break;
11597         case 0x0104:    /*Query File Name Info*/
11598         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11599                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11600                     &trunc);
11601                 break;
11602         case 0x0107:    /*Query File All Info*/
11603         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11604                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11605                     &trunc);
11606                 break;
11607         case 0x0108:    /*Query File Alt File Info*/
11608         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11609                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11610                     &trunc);
11611                 break;
11612         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11613                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11614         case 0x0109:    /*Query File Stream Info*/
11615                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11616                     &trunc);
11617                 break;
11618         case 0x010b:    /*Query File Compression Info*/
11619         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11620                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11621                     &trunc);
11622                 break;
11623         case 0x0200:    /* Query File Unix Basic*/
11624                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11625                                            &trunc);
11626                 break;
11627         case 0x0201:    /* Query File Unix Link*/
11628                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11629                                            &trunc);
11630                 break;
11631         case 0x0202:    /* Query File Unix HardLink*/
11632                 /* XXX add this from the SNIA doc */
11633                 break;
11634         }
11635
11636         return offset;
11637 }
11638
11639 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11640   TRANS2_SET_FILE_INFORMATION*/
11641 static int
11642 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11643     int offset, guint16 *bcp)
11644 {
11645         smb_info_t *si;
11646         gboolean trunc;
11647
11648         if(!*bcp){
11649                 return offset;
11650         }
11651
11652         si = (smb_info_t *)pinfo->private_data;
11653         switch(si->info_level){
11654         case 1:         /*Info Standard*/
11655                 
11656         case 2:         /*Info Query EA Size*/
11657                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11658                     &trunc);
11659                 break;
11660         case 4:         /*Info Query All EAs*/
11661                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11662                     &trunc);
11663                 break;
11664         case 0x0101:    /*Set File Basic Info*/
11665         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11666                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11667                     &trunc);
11668                 break;
11669         case 0x0102:    /*Set File Disposition Info*/
11670                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11671                     &trunc);
11672                 break;
11673         case 0x0103:    /*Set File Allocation Info*/
11674                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11675                     &trunc);
11676                 break;
11677         case 0x0104:    /*Set End Of File Info*/
11678                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11679                     &trunc);
11680                 break;
11681         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11682                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11683                     &trunc);
11684                 break;
11685         case 0x0201:    /*Set File Unix Link.  Same as query. */
11686                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11687                     &trunc);
11688                 break;
11689         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11690                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11691                     &trunc);
11692                 break;
11693         case 1010:      /* Set File Rename */
11694                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
11695                     &trunc);
11696                 break;
11697         case 1013:
11698         case 1014:
11699         case 1016:
11700         case 1019:
11701         case 1020:
11702         case 1023:
11703         case 1025:
11704         case 1029:
11705         case 1032:
11706         case 1039:
11707         case 1040:
11708                 /* XXX: TODO, extra levels discovered by tridge */
11709                 break;
11710         }
11711
11712         return offset;
11713 }
11714
11715
11716 static const true_false_string tfs_quota_flags_deny_disk = {
11717         "DENY DISK SPACE for users exceeding quota limit",
11718         "Do NOT deny disk space for users exceeding quota limit"
11719 };
11720 static const true_false_string tfs_quota_flags_log_limit = {
11721         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11722         "Do NOT log event when a user exceeds their quota limit"
11723 };
11724 static const true_false_string tfs_quota_flags_log_warning = {
11725         "LOG EVENT when a user exceeds their WARNING LEVEL",
11726         "Do NOT log event when a user exceeds their warning level"
11727 };
11728 static const true_false_string tfs_quota_flags_enabled = {
11729         "Quotas are ENABLED of this fs",
11730         "Quotas are NOT enabled on this fs"
11731 };
11732 static void
11733 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11734 {
11735         guint8 mask;
11736         proto_item *item = NULL;
11737         proto_tree *tree = NULL;
11738
11739         mask = tvb_get_guint8(tvb, offset);
11740
11741         if(parent_tree){
11742                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11743                         "Quota Flags: 0x%02x %s", mask,
11744                         mask?"Enabled":"Disabled");
11745                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11746         }
11747
11748         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11749                 tvb, offset, 1, mask);
11750         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11751                 tvb, offset, 1, mask);
11752         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11753                 tvb, offset, 1, mask);
11754
11755         if(mask && (!(mask&0x01))){
11756                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11757                         tvb, offset, 1, 0x01);
11758         } else {
11759                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11760                         tvb, offset, 1, mask);
11761         }
11762
11763 }
11764
11765 static int
11766 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11767 {
11768         /* first 24 bytes are unknown */
11769         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11770         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11771                     offset, 24, TRUE);
11772         COUNT_BYTES_TRANS_SUBR(24);
11773
11774         /* number of bytes for quota warning */
11775         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11776         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11777         COUNT_BYTES_TRANS_SUBR(8);
11778
11779         /* number of bytes for quota limit */
11780         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11781         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11782         COUNT_BYTES_TRANS_SUBR(8);
11783
11784         /* one byte of quota flags */
11785         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11786         dissect_quota_flags(tvb, tree, offset);
11787         COUNT_BYTES_TRANS_SUBR(1);
11788
11789         /* these 7 bytes are unknown */
11790         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11791         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11792                     offset, 7, TRUE);
11793         COUNT_BYTES_TRANS_SUBR(7);
11794
11795         return offset;
11796 }
11797
11798 static int
11799 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11800     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11801 {
11802         proto_item *item = NULL;
11803         proto_tree *tree = NULL;
11804         smb_info_t *si;
11805
11806         si = (smb_info_t *)pinfo->private_data;
11807
11808         if(parent_tree){
11809                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11810                                 "%s Data",
11811                                 val_to_str(subcmd, trans2_cmd_vals,
11812                                                 "Unknown (0x%02x)"));
11813                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11814         }
11815
11816         switch(subcmd){
11817         case 0x00:      /*TRANS2_OPEN2*/
11818                 /* XXX dont know how to decode FEAList */
11819                 break;
11820         case 0x01:      /*TRANS2_FIND_FIRST2*/
11821                 /* XXX dont know how to decode FEAList */
11822                 break;
11823         case 0x02:      /*TRANS2_FIND_NEXT2*/
11824                 /* XXX dont know how to decode FEAList */
11825                 break;
11826         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11827                 /* no data field in this request */
11828                 break;
11829         case 0x04:      /* TRANS2_SET_QUOTA */
11830                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11831                 break;
11832         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11833                 /* no data field in this request */
11834                 /*
11835                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11836                  * Extensions Version 3.0, Document Version 1.11,
11837                  * July 19, 1990" says there may be "Additional
11838                  * FileInfoLevel dependent information" here.
11839                  *
11840                  * Was that just a cut-and-pasteo?
11841                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11842                  * here.
11843                  */
11844                 break;
11845         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11846                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11847                 break;
11848         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11849                 /* no data field in this request */
11850                 /*
11851                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11852                  * Extensions Version 3.0, Document Version 1.11,
11853                  * July 19, 1990" says there may be "Additional
11854                  * FileInfoLevel dependent information" here.
11855                  *
11856                  * Was that just a cut-and-pasteo?
11857                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11858                  * here.
11859                  */
11860                 break;
11861         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11862                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11863                 break;
11864         case 0x09:      /*TRANS2_FSCTL*/
11865                 /*XXX dont know how to decode this yet */
11866
11867                 /*
11868                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11869                  * Extensions Version 3.0, Document Version 1.11,
11870                  * July 19, 1990" says this this contains a
11871                  * "File system specific data block".  (That means we
11872                  * may not be able to dissect it in any case.)
11873                  */
11874                 break;
11875         case 0x0a:      /*TRANS2_IOCTL2*/
11876                 /*XXX dont know how to decode this yet */
11877
11878                 /*
11879                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11880                  * Extensions Version 3.0, Document Version 1.11,
11881                  * July 19, 1990" says this this contains a
11882                  * "Device/function specific data block".  (That
11883                  * means we may not be able to dissect it in any case.)
11884                  */
11885                 break;
11886         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11887                 /*XXX dont know how to decode this yet */
11888
11889                 /*
11890                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11891                  * Extensions Version 3.0, Document Version 1.11,
11892                  * July 19, 1990" says this this contains "additional
11893                  * level dependent match data".
11894                  */
11895                 break;
11896         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11897                 /*XXX dont know how to decode this yet */
11898
11899                 /*
11900                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11901                  * Extensions Version 3.0, Document Version 1.11,
11902                  * July 19, 1990" says this this contains "additional
11903                  * level dependent monitor information".
11904                  */
11905                 break;
11906         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11907                 /* XXX optional FEAList, unknown what FEAList looks like*/
11908                 break;
11909         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11910                 /*XXX dont know how to decode this yet */
11911                 break;
11912         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11913                 /* no data field in this request */
11914                 break;
11915         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11916                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11917                 break;
11918         }
11919
11920         /* ooops there were data we didnt know how to process */
11921         if(dc != 0){
11922                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11923                 offset += dc;
11924         }
11925
11926         return offset;
11927 }
11928
11929
11930 static void
11931 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11932     proto_tree *tree)
11933 {
11934         int i;
11935         int offset;
11936         guint length;
11937
11938         /*
11939          * Show the setup words.
11940          */
11941         if (s_tvb != NULL) {
11942                 length = tvb_reported_length(s_tvb);
11943                 for (i = 0, offset = 0; length >= 2;
11944                     i++, offset += 2, length -= 2) {
11945                         /*
11946                          * XXX - add a setup word filterable field?
11947                          */
11948                         proto_tree_add_text(tree, s_tvb, offset, 2,
11949                             "Setup Word %d: 0x%04x", i,
11950                             tvb_get_letohs(s_tvb, offset));
11951                 }
11952         }
11953
11954         /*
11955          * Show the parameters, if any.
11956          */
11957         if (p_tvb != NULL) {
11958                 length = tvb_reported_length(p_tvb);
11959                 if (length != 0) {
11960                         proto_tree_add_text(tree, p_tvb, 0, length,
11961                             "Parameters: %s",
11962                             tvb_bytes_to_str(p_tvb, 0, length));
11963                 }
11964         }
11965
11966         /*
11967          * Show the data, if any.
11968          */
11969         if (d_tvb != NULL) {
11970                 length = tvb_reported_length(d_tvb);
11971                 if (length != 0) {
11972                         proto_tree_add_text(tree, d_tvb, 0, length,
11973                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11974                 }
11975         }
11976 }
11977
11978 /* This routine handles the following 4 calls
11979    Transaction  0x25
11980    Transaction Secondary 0x26
11981    Transaction2 0x32
11982    Transaction2 Secondary 0x33
11983 */
11984 static int
11985 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11986 {
11987         guint8 wc, sc=0;
11988         int so=offset;
11989         int sl=0;
11990         int spo=offset;
11991         int spc=0;
11992         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11993         int subcmd = -1;
11994         guint32 to;
11995         int an_len;
11996         const char *an = NULL;
11997         smb_info_t *si;
11998         smb_transact2_info_t *t2i;
11999         smb_transact_info_t *tri;
12000         guint16 bc;
12001         int padcnt;
12002         gboolean dissected_trans;
12003
12004         si = (smb_info_t *)pinfo->private_data;
12005
12006         WORD_COUNT;
12007
12008         if(wc==8){
12009                 /*secondary client request*/
12010
12011                 /* total param count, only a 16bit integer here*/
12012                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12013                 offset += 2;
12014
12015                 /* total data count , only 16bit integer here*/
12016                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12017                 offset += 2;
12018
12019                 /* param count */
12020                 pc = tvb_get_letohs(tvb, offset);
12021                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12022                 offset += 2;
12023
12024                 /* param offset */
12025                 po = tvb_get_letohs(tvb, offset);
12026                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12027                 offset += 2;
12028
12029                 /* param disp */
12030                 pd = tvb_get_letohs(tvb, offset);
12031                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
12032                 offset += 2;
12033
12034                 /* data count */
12035                 dc = tvb_get_letohs(tvb, offset);
12036                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12037                 offset += 2;
12038
12039                 /* data offset */
12040                 od = tvb_get_letohs(tvb, offset);
12041                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12042                 offset += 2;
12043
12044                 /* data disp */
12045                 dd = tvb_get_letohs(tvb, offset);
12046                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
12047                 offset += 2;
12048
12049                 if(si->cmd==SMB_COM_TRANSACTION2){
12050                         guint16 fid;
12051
12052                         /* fid */
12053                         fid = tvb_get_letohs(tvb, offset);
12054                         add_fid(tvb, pinfo, tree, offset, 2, fid);
12055
12056                         offset += 2;
12057                 }
12058
12059                 /* There are no setup words. */
12060                 so = offset;
12061                 sc = 0;
12062                 sl = 0;
12063         } else {
12064                 /* it is not a secondary request */
12065
12066                 /* total param count , only a 16 bit integer here*/
12067                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12068                 offset += 2;
12069
12070                 /* total data count , only 16bit integer here*/
12071                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12072                 offset += 2;
12073
12074                 /* max param count , only 16bit integer here*/
12075                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12076                 offset += 2;
12077
12078                 /* max data count, only 16bit integer here*/
12079                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12080                 offset += 2;
12081
12082                 /* max setup count, only 16bit integer here*/
12083                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12084                 offset += 1;
12085
12086                 /* reserved byte */
12087                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12088                 offset += 1;
12089
12090                 /* transaction flags */
12091                 tf = dissect_transaction_flags(tvb, tree, offset);
12092                 offset += 2;
12093
12094                 /* timeout */
12095                 to = tvb_get_letohl(tvb, offset);
12096                 if (to == 0)
12097                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
12098                 else if (to == 0xffffffff)
12099                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
12100                 else
12101                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
12102                 offset += 4;
12103
12104                 /* 2 reserved bytes */
12105                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12106                 offset += 2;
12107
12108                 /* param count */
12109                 pc = tvb_get_letohs(tvb, offset);
12110                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12111                 offset += 2;
12112
12113                 /* param offset */
12114                 po = tvb_get_letohs(tvb, offset);
12115                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12116                 offset += 2;
12117
12118                 /* param displacement is zero here */
12119                 pd = 0;
12120
12121                 /* data count */
12122                 dc = tvb_get_letohs(tvb, offset);
12123                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12124                 offset += 2;
12125
12126                 /* data offset */
12127                 od = tvb_get_letohs(tvb, offset);
12128                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12129                 offset += 2;
12130
12131                 /* data displacement is zero here */
12132                 dd = 0;
12133
12134                 /* setup count */
12135                 sc = tvb_get_guint8(tvb, offset);
12136                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12137                 offset += 1;
12138
12139                 /* reserved byte */
12140                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12141                 offset += 1;
12142
12143                 /* this is where the setup bytes, if any start */
12144                 so = offset;
12145                 sl = sc*2;
12146
12147                 /* if there were any setup bytes, decode them */
12148                 if(sc){
12149                         switch(si->cmd){
12150
12151                         case SMB_COM_TRANSACTION2:
12152                                 /* TRANSACTION2 only has one setup word and
12153                                    that is the subcommand code.
12154
12155                                    XXX - except for TRANS2_FSCTL
12156                                    and TRANS2_IOCTL. */
12157                                 subcmd = tvb_get_letohs(tvb, offset);
12158                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12159                                     tvb, offset, 2, subcmd);
12160                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12161                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12162                                             val_to_str(subcmd, trans2_cmd_vals,
12163                                                 "Unknown (0x%02x)"));
12164                                 }
12165                                 if (!si->unidir) {
12166                                         if(!pinfo->fd->flags.visited){
12167                                                 /*
12168                                                  * Allocate a new
12169                                                  * smb_transact2_info_t
12170                                                  * structure.
12171                                                  */
12172                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
12173                                                 t2i->subcmd = subcmd;
12174                                                 t2i->info_level = -1;
12175                                                 t2i->resume_keys = FALSE;
12176                                                 si->sip->extra_info = t2i;
12177                                         }
12178                                 }
12179
12180                                 /*
12181                                  * XXX - process TRANS2_FSCTL and
12182                                  * TRANS2_IOCTL setup words here.
12183                                  */
12184                                 break;
12185
12186                         case SMB_COM_TRANSACTION:
12187                                 /* TRANSACTION setup words processed below */
12188                                 break;
12189                         }
12190
12191                         offset += sl;
12192                 }
12193         }
12194
12195         BYTE_COUNT;
12196
12197         if(wc!=8){
12198                 /* primary request */
12199                 /* name is NULL if transaction2 */
12200                 if(si->cmd == SMB_COM_TRANSACTION){
12201                         /* Transaction Name */
12202                         an = get_unicode_or_ascii_string(tvb, &offset,
12203                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12204                         if (an == NULL)
12205                                 goto endofcommand;
12206                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12207                                 offset, an_len, an);
12208                         COUNT_BYTES(an_len);
12209                 }
12210         }
12211
12212         /*
12213          * The pipe or mailslot arguments for Transaction start with
12214          * the first setup word (or where the first setup word would
12215          * be if there were any setup words), and run to the current
12216          * offset (which could mean that there aren't any).
12217          */
12218         spo = so;
12219         spc = offset - spo;
12220
12221         /* parameters */
12222         if(po>offset){
12223                 /* We have some initial padding bytes.
12224                 */
12225                 padcnt = po-offset;
12226                 if (padcnt > bc)
12227                         padcnt = bc;
12228                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12229                 COUNT_BYTES(padcnt);
12230         }
12231         if(pc){
12232                 CHECK_BYTE_COUNT(pc);
12233                 switch(si->cmd) {
12234
12235                 case SMB_COM_TRANSACTION2:
12236                         /* TRANSACTION2 parameters*/
12237                         offset = dissect_transaction2_request_parameters(tvb,
12238                             pinfo, tree, offset, subcmd, pc);
12239                         bc -= pc;
12240                         break;
12241
12242                 case SMB_COM_TRANSACTION:
12243                         /* TRANSACTION parameters processed below */
12244                         COUNT_BYTES(pc);
12245                         break;
12246                 }
12247         }
12248
12249         /* data */
12250         if(od>offset){
12251                 /* We have some initial padding bytes.
12252                 */
12253                 padcnt = od-offset;
12254                 if (padcnt > bc)
12255                         padcnt = bc;
12256                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12257                 COUNT_BYTES(padcnt);
12258         }
12259         if(dc){
12260                 CHECK_BYTE_COUNT(dc);
12261                 switch(si->cmd){
12262
12263                 case SMB_COM_TRANSACTION2:
12264                         /* TRANSACTION2 data*/
12265                         offset = dissect_transaction2_request_data(tvb, pinfo,
12266                             tree, offset, subcmd, dc);
12267                         bc -= dc;
12268                         break;
12269
12270                 case SMB_COM_TRANSACTION:
12271                         /* TRANSACTION data processed below */
12272                         COUNT_BYTES(dc);
12273                         break;
12274                 }
12275         }
12276
12277         /*TRANSACTION request parameters */
12278         if(si->cmd==SMB_COM_TRANSACTION){
12279                 /*XXX replace this block with a function and use that one
12280                      for both requests/responses*/
12281                 if(dd==0){
12282                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12283                         tvbuff_t *sp_tvb, *pd_tvb;
12284
12285                         if(pc>0){
12286                                 if(pc>tvb_length_remaining(tvb, po)){
12287                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12288                                 } else {
12289                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12290                                 }
12291                         } else {
12292                                 p_tvb = NULL;
12293                         }
12294                         if(dc>0){
12295                                 if(dc>tvb_length_remaining(tvb, od)){
12296                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12297                                 } else {
12298                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12299                                 }
12300                         } else {
12301                                 d_tvb = NULL;
12302                         }
12303                         if(sl){
12304                                 if(sl>tvb_length_remaining(tvb, so)){
12305                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12306                                 } else {
12307                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12308                                 }
12309                         } else {
12310                                 s_tvb = NULL;
12311                         }
12312
12313                         if (!si->unidir) {
12314                                 if(!pinfo->fd->flags.visited){
12315                                         /*
12316                                          * Allocate a new smb_transact_info_t
12317                                          * structure.
12318                                          */
12319                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
12320                                         tri->subcmd = -1;
12321                                         tri->trans_subcmd = -1;
12322                                         tri->function = -1;
12323                                         tri->fid = -1;
12324                                         tri->lanman_cmd = 0;
12325                                         tri->param_descrip = NULL;
12326                                         tri->data_descrip = NULL;
12327                                         tri->aux_data_descrip = NULL;
12328                                         tri->info_level = -1;
12329                                         si->sip->extra_info = tri;
12330                                 } else {
12331                                         /*
12332                                          * We already filled the structure
12333                                          * in; don't bother doing so again.
12334                                          */
12335                                         tri = NULL;
12336                                 }
12337                         } else {
12338                                 /*
12339                                  * This is a unidirectional message, for
12340                                  * which there will be no reply; don't
12341                                  * bother allocating an "smb_transact_info_t"
12342                                  * structure for it.
12343                                  */
12344                                 tri = NULL;
12345                         }
12346                         dissected_trans = FALSE;
12347                         if(strncmp("\\PIPE\\", an, 6) == 0){
12348                                 if (tri != NULL)
12349                                         tri->subcmd=TRANSACTION_PIPE;
12350
12351                                 /*
12352                                  * A tvbuff containing the setup words and
12353                                  * the pipe path.
12354                                  */
12355                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12356
12357                                 /*
12358                                  * A tvbuff containing the parameters and the
12359                                  * data.
12360                                  */
12361                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12362
12363                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12364                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12365                                     top_tree);
12366
12367                                 /* In case we did not see the TreeConnect call,
12368                                    store this TID here as well as a IPC TID 
12369                                    so we know that future Read/Writes to this 
12370                                    TID is (probably) DCERPC.
12371                                 */
12372                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
12373                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
12374                                 }
12375                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
12376                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12377                                 if (tri != NULL)
12378                                         tri->subcmd=TRANSACTION_MAILSLOT;
12379
12380                                 /*
12381                                  * A tvbuff containing the setup words and
12382                                  * the mailslot path.
12383                                  */
12384                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12385                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12386                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12387                         }
12388                         if (!dissected_trans)
12389                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12390                 } else {
12391                         if(check_col(pinfo->cinfo, COL_INFO)){
12392                                 col_append_str(pinfo->cinfo, COL_INFO,
12393                                         "[transact continuation]");
12394                         }
12395                 }
12396         }
12397
12398         END_OF_SMB
12399
12400         return offset;
12401 }
12402
12403
12404
12405 static int
12406 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12407     int offset, guint16 *bcp, gboolean *trunc)
12408 {
12409         int fn_len;
12410         const char *fn;
12411         int old_offset = offset;
12412         proto_item *item = NULL;
12413         proto_tree *tree = NULL;
12414         smb_info_t *si;
12415         smb_transact2_info_t *t2i;
12416         gboolean resume_keys = FALSE;
12417
12418         si = (smb_info_t *)pinfo->private_data;
12419         if (si->sip != NULL) {
12420                 t2i = si->sip->extra_info;
12421                 if (t2i != NULL)
12422                         resume_keys = t2i->resume_keys;
12423         }
12424
12425         if(parent_tree){
12426                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12427                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12428                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12429         }
12430
12431         if (resume_keys) {
12432                 /* resume key */
12433                 CHECK_BYTE_COUNT_SUBR(4);
12434                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12435                 COUNT_BYTES_SUBR(4);
12436         }
12437
12438         /* create time */
12439         CHECK_BYTE_COUNT_SUBR(4);
12440         offset = dissect_smb_datetime(tvb, tree, offset,
12441                 hf_smb_create_time,
12442                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12443         *bcp -= 4;
12444
12445         /* access time */
12446         CHECK_BYTE_COUNT_SUBR(4);
12447         offset = dissect_smb_datetime(tvb, tree, offset,
12448                 hf_smb_access_time,
12449                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12450         *bcp -= 4;
12451
12452         /* last write time */
12453         CHECK_BYTE_COUNT_SUBR(4);
12454         offset = dissect_smb_datetime(tvb, tree, offset,
12455                 hf_smb_last_write_time,
12456                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12457         *bcp -= 4;
12458
12459         /* data size */
12460         CHECK_BYTE_COUNT_SUBR(4);
12461         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12462         COUNT_BYTES_SUBR(4);
12463
12464         /* allocation size */
12465         CHECK_BYTE_COUNT_SUBR(4);
12466         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12467         COUNT_BYTES_SUBR(4);
12468
12469         /* File Attributes */
12470         CHECK_BYTE_COUNT_SUBR(2);
12471         offset = dissect_file_attributes(tvb, tree, offset, 2);
12472         *bcp -= 2;
12473
12474         /* file name len */
12475         CHECK_BYTE_COUNT_SUBR(1);
12476         fn_len = tvb_get_guint8(tvb, offset);
12477         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12478         COUNT_BYTES_SUBR(1);
12479         if (si->unicode)
12480                 fn_len += 2;    /* include terminating '\0' */
12481         else
12482                 fn_len++;       /* include terminating '\0' */
12483
12484         /* file name */
12485         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12486         CHECK_STRING_SUBR(fn);
12487         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12488                 fn);
12489         COUNT_BYTES_SUBR(fn_len);
12490
12491         if (check_col(pinfo->cinfo, COL_INFO)) {
12492                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12493                 fn);
12494         }
12495
12496         proto_item_append_text(item, " File: %s", fn);
12497         proto_item_set_len(item, offset-old_offset);
12498
12499         *trunc = FALSE;
12500         return offset;
12501 }
12502
12503 static int
12504 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12505     int offset, guint16 *bcp, gboolean *trunc)
12506 {
12507         int fn_len;
12508         const char *fn;
12509         int old_offset = offset;
12510         proto_item *item = NULL;
12511         proto_tree *tree = NULL;
12512         smb_info_t *si;
12513         smb_transact2_info_t *t2i;
12514         gboolean resume_keys = FALSE;
12515
12516         si = (smb_info_t *)pinfo->private_data;
12517         if (si->sip != NULL) {
12518                 t2i = si->sip->extra_info;
12519                 if (t2i != NULL)
12520                         resume_keys = t2i->resume_keys;
12521         }
12522
12523         if(parent_tree){
12524                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12525                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12526                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12527         }
12528
12529         if (resume_keys) {
12530                 /* resume key */
12531                 CHECK_BYTE_COUNT_SUBR(4);
12532                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12533                 COUNT_BYTES_SUBR(4);
12534         }
12535
12536         /* create time */
12537         CHECK_BYTE_COUNT_SUBR(4);
12538         offset = dissect_smb_datetime(tvb, tree, offset,
12539                 hf_smb_create_time,
12540                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12541         *bcp -= 4;
12542
12543         /* access time */
12544         CHECK_BYTE_COUNT_SUBR(4);
12545         offset = dissect_smb_datetime(tvb, tree, offset,
12546                 hf_smb_access_time,
12547                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12548         *bcp -= 4;
12549
12550         /* last write time */
12551         CHECK_BYTE_COUNT_SUBR(4);
12552         offset = dissect_smb_datetime(tvb, tree, offset,
12553                 hf_smb_last_write_time,
12554                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12555         *bcp -= 4;
12556
12557         /* data size */
12558         CHECK_BYTE_COUNT_SUBR(4);
12559         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12560         COUNT_BYTES_SUBR(4);
12561
12562         /* allocation size */
12563         CHECK_BYTE_COUNT_SUBR(4);
12564         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12565         COUNT_BYTES_SUBR(4);
12566
12567         /* File Attributes */
12568         CHECK_BYTE_COUNT_SUBR(2);
12569         offset = dissect_file_attributes(tvb, tree, offset, 2);
12570         *bcp -= 2;
12571
12572         /* ea length */
12573         CHECK_BYTE_COUNT_SUBR(4);
12574         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12575         COUNT_BYTES_SUBR(4);
12576
12577         /* file name len */
12578         CHECK_BYTE_COUNT_SUBR(1);
12579         fn_len = tvb_get_guint8(tvb, offset);
12580         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12581         COUNT_BYTES_SUBR(1);
12582         if (si->unicode)
12583                 fn_len += 2;    /* include terminating '\0' */
12584         else
12585                 fn_len++;       /* include terminating '\0' */
12586
12587         /* file name */
12588         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12589         CHECK_STRING_SUBR(fn);
12590         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12591                 fn);
12592         COUNT_BYTES_SUBR(fn_len);
12593
12594         if (check_col(pinfo->cinfo, COL_INFO)) {
12595                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12596                 fn);
12597         }
12598
12599         proto_item_append_text(item, " File: %s", fn);
12600         proto_item_set_len(item, offset-old_offset);
12601
12602         *trunc = FALSE;
12603         return offset;
12604 }
12605
12606 static int
12607 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12608     int offset, guint16 *bcp, gboolean *trunc)
12609 {
12610         int fn_len;
12611         const char *fn;
12612         int old_offset = offset;
12613         proto_item *item = NULL;
12614         proto_tree *tree = NULL;
12615         smb_info_t *si;
12616         guint32 neo;
12617         int padcnt;
12618
12619         si = (smb_info_t *)pinfo->private_data;
12620
12621         if(parent_tree){
12622                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12623                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12624                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12625         }
12626
12627         /*
12628          * We assume that the presence of a next entry offset implies the
12629          * absence of a resume key, as appears to be the case for 4.3.4.6.
12630          */
12631
12632         /* next entry offset */
12633         CHECK_BYTE_COUNT_SUBR(4);
12634         neo = tvb_get_letohl(tvb, offset);
12635         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12636         COUNT_BYTES_SUBR(4);
12637
12638         /* file index */
12639         CHECK_BYTE_COUNT_SUBR(4);
12640         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12641         COUNT_BYTES_SUBR(4);
12642
12643         /* create time */
12644         CHECK_BYTE_COUNT_SUBR(8);
12645         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12646         *bcp -= 8;
12647
12648         /* access time */
12649         CHECK_BYTE_COUNT_SUBR(8);
12650         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12651         *bcp -= 8;
12652
12653         /* last write time */
12654         CHECK_BYTE_COUNT_SUBR(8);
12655         offset = dissect_smb_64bit_time(tvb, tree, offset,
12656                 hf_smb_last_write_time);
12657         *bcp -= 8;
12658
12659         /* last change time */
12660         CHECK_BYTE_COUNT_SUBR(8);
12661         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12662         *bcp -= 8;
12663
12664         /* end of file */
12665         CHECK_BYTE_COUNT_SUBR(8);
12666         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12667         COUNT_BYTES_SUBR(8);
12668
12669         /* allocation size */
12670         CHECK_BYTE_COUNT_SUBR(8);
12671         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12672         COUNT_BYTES_SUBR(8);
12673
12674         /* Extended File Attributes */
12675         CHECK_BYTE_COUNT_SUBR(4);
12676         offset = dissect_file_ext_attr(tvb, tree, offset);
12677         *bcp -= 4;
12678
12679         /* file name len */
12680         CHECK_BYTE_COUNT_SUBR(4);
12681         fn_len = tvb_get_letohl(tvb, offset);
12682         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12683         COUNT_BYTES_SUBR(4);
12684
12685         /* file name */
12686         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12687         CHECK_STRING_SUBR(fn);
12688         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12689                 fn);
12690         COUNT_BYTES_SUBR(fn_len);
12691
12692         if (check_col(pinfo->cinfo, COL_INFO)) {
12693                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12694                 fn);
12695         }
12696
12697         /* skip to next structure */
12698         if(neo){
12699                 padcnt = (old_offset + neo) - offset;
12700                 if (padcnt < 0) {
12701                         /*
12702                          * XXX - this is bogus; flag it?
12703                          */
12704                         padcnt = 0;
12705                 }
12706                 if (padcnt != 0) {
12707                         CHECK_BYTE_COUNT_SUBR(padcnt);
12708                         COUNT_BYTES_SUBR(padcnt);
12709                 }
12710         }
12711
12712         proto_item_append_text(item, " File: %s", fn);
12713         proto_item_set_len(item, offset-old_offset);
12714
12715         *trunc = FALSE;
12716         return offset;
12717 }
12718
12719 static int
12720 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12721     int offset, guint16 *bcp, gboolean *trunc)
12722 {
12723         int fn_len;
12724         const char *fn;
12725         int old_offset = offset;
12726         proto_item *item = NULL;
12727         proto_tree *tree = NULL;
12728         smb_info_t *si;
12729         guint32 neo;
12730         int padcnt;
12731
12732         si = (smb_info_t *)pinfo->private_data;
12733
12734         if(parent_tree){
12735                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12736                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12737                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12738         }
12739
12740         /*
12741          * We assume that the presence of a next entry offset implies the
12742          * absence of a resume key, as appears to be the case for 4.3.4.6.
12743          */
12744
12745         /* next entry offset */
12746         CHECK_BYTE_COUNT_SUBR(4);
12747         neo = tvb_get_letohl(tvb, offset);
12748         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12749         COUNT_BYTES_SUBR(4);
12750
12751         /* file index */
12752         CHECK_BYTE_COUNT_SUBR(4);
12753         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12754         COUNT_BYTES_SUBR(4);
12755
12756         /* create time */
12757         CHECK_BYTE_COUNT_SUBR(8);
12758         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12759         *bcp -= 8;
12760
12761         /* access time */
12762         CHECK_BYTE_COUNT_SUBR(8);
12763         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12764         *bcp -= 8;
12765
12766         /* last write time */
12767         CHECK_BYTE_COUNT_SUBR(8);
12768         offset = dissect_smb_64bit_time(tvb, tree, offset,
12769                 hf_smb_last_write_time);
12770         *bcp -= 8;
12771
12772         /* last change time */
12773         CHECK_BYTE_COUNT_SUBR(8);
12774         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12775         *bcp -= 8;
12776
12777         /* end of file */
12778         CHECK_BYTE_COUNT_SUBR(8);
12779         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12780         COUNT_BYTES_SUBR(8);
12781
12782         /* allocation size */
12783         CHECK_BYTE_COUNT_SUBR(8);
12784         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12785         COUNT_BYTES_SUBR(8);
12786
12787         /* Extended File Attributes */
12788         CHECK_BYTE_COUNT_SUBR(4);
12789         offset = dissect_file_ext_attr(tvb, tree, offset);
12790         *bcp -= 4;
12791
12792         /* file name len */
12793         CHECK_BYTE_COUNT_SUBR(4);
12794         fn_len = tvb_get_letohl(tvb, offset);
12795         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12796         COUNT_BYTES_SUBR(4);
12797
12798         /* ea length */
12799         CHECK_BYTE_COUNT_SUBR(4);
12800         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12801         COUNT_BYTES_SUBR(4);
12802
12803         /* file name */
12804         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12805         CHECK_STRING_SUBR(fn);
12806         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12807                 fn);
12808         COUNT_BYTES_SUBR(fn_len);
12809
12810         if (check_col(pinfo->cinfo, COL_INFO)) {
12811                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12812                 fn);
12813         }
12814
12815         /* skip to next structure */
12816         if(neo){
12817                 padcnt = (old_offset + neo) - offset;
12818                 if (padcnt < 0) {
12819                         /*
12820                          * XXX - this is bogus; flag it?
12821                          */
12822                         padcnt = 0;
12823                 }
12824                 if (padcnt != 0) {
12825                         CHECK_BYTE_COUNT_SUBR(padcnt);
12826                         COUNT_BYTES_SUBR(padcnt);
12827                 }
12828         }
12829
12830         proto_item_append_text(item, " File: %s", fn);
12831         proto_item_set_len(item, offset-old_offset);
12832
12833         *trunc = FALSE;
12834         return offset;
12835 }
12836
12837 static int
12838 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12839     int offset, guint16 *bcp, gboolean *trunc)
12840 {
12841         int fn_len, sfn_len;
12842         const char *fn, *sfn;
12843         int old_offset = offset;
12844         proto_item *item = NULL;
12845         proto_tree *tree = NULL;
12846         smb_info_t *si;
12847         guint32 neo;
12848         int padcnt;
12849
12850         si = (smb_info_t *)pinfo->private_data;
12851
12852         if(parent_tree){
12853                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12854                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12855                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12856         }
12857
12858         /*
12859          * XXX - I have not seen any of these that contain a resume
12860          * key, even though some of the requests had the "return resume
12861          * key" flag set.
12862          */
12863
12864         /* next entry offset */
12865         CHECK_BYTE_COUNT_SUBR(4);
12866         neo = tvb_get_letohl(tvb, offset);
12867         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12868         COUNT_BYTES_SUBR(4);
12869
12870         /* file index */
12871         CHECK_BYTE_COUNT_SUBR(4);
12872         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12873         COUNT_BYTES_SUBR(4);
12874
12875         /* create time */
12876         CHECK_BYTE_COUNT_SUBR(8);
12877         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12878         *bcp -= 8;
12879
12880         /* access time */
12881         CHECK_BYTE_COUNT_SUBR(8);
12882         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12883         *bcp -= 8;
12884
12885         /* last write time */
12886         CHECK_BYTE_COUNT_SUBR(8);
12887         offset = dissect_smb_64bit_time(tvb, tree, offset,
12888                 hf_smb_last_write_time);
12889         *bcp -= 8;
12890
12891         /* last change time */
12892         CHECK_BYTE_COUNT_SUBR(8);
12893         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12894         *bcp -= 8;
12895
12896         /* end of file */
12897         CHECK_BYTE_COUNT_SUBR(8);
12898         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12899         COUNT_BYTES_SUBR(8);
12900
12901         /* allocation size */
12902         CHECK_BYTE_COUNT_SUBR(8);
12903         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12904         COUNT_BYTES_SUBR(8);
12905
12906         /* Extended File Attributes */
12907         CHECK_BYTE_COUNT_SUBR(4);
12908         offset = dissect_file_ext_attr(tvb, tree, offset);
12909         *bcp -= 4;
12910
12911         /* file name len */
12912         CHECK_BYTE_COUNT_SUBR(4);
12913         fn_len = tvb_get_letohl(tvb, offset);
12914         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12915         COUNT_BYTES_SUBR(4);
12916
12917         /*
12918          * EA length.
12919          *
12920          * XXX - in one captures, this has the topmost bit set, and the
12921          * rest of the bits have the value 7.  Is the topmost bit being
12922          * set some indication that the value *isn't* the length of
12923          * the EAs?
12924          */
12925         CHECK_BYTE_COUNT_SUBR(4);
12926         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12927         COUNT_BYTES_SUBR(4);
12928
12929         /* short file name len */
12930         CHECK_BYTE_COUNT_SUBR(1);
12931         sfn_len = tvb_get_guint8(tvb, offset);
12932         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12933         COUNT_BYTES_SUBR(1);
12934
12935         /* reserved byte */
12936         CHECK_BYTE_COUNT_SUBR(1);
12937         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12938         COUNT_BYTES_SUBR(1);
12939
12940         /* short file name - it's not always in Unicode */
12941         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12942         CHECK_STRING_SUBR(sfn);
12943         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12944                 sfn);
12945         COUNT_BYTES_SUBR(24);
12946
12947         /* file name */
12948         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12949         CHECK_STRING_SUBR(fn);
12950         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12951                 fn);
12952         COUNT_BYTES_SUBR(fn_len);
12953
12954         if (check_col(pinfo->cinfo, COL_INFO)) {
12955                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12956                 fn);
12957         }
12958
12959         /* skip to next structure */
12960         if(neo){
12961                 padcnt = (old_offset + neo) - offset;
12962                 if (padcnt < 0) {
12963                         /*
12964                          * XXX - this is bogus; flag it?
12965                          */
12966                         padcnt = 0;
12967                 }
12968                 if (padcnt != 0) {
12969                         CHECK_BYTE_COUNT_SUBR(padcnt);
12970                         COUNT_BYTES_SUBR(padcnt);
12971                 }
12972         }
12973
12974         proto_item_append_text(item, " File: %s", fn);
12975         proto_item_set_len(item, offset-old_offset);
12976
12977         *trunc = FALSE;
12978         return offset;
12979 }
12980
12981 static int
12982 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12983     int offset, guint16 *bcp, gboolean *trunc)
12984 {
12985         int fn_len;
12986         const char *fn;
12987         int old_offset = offset;
12988         proto_item *item = NULL;
12989         proto_tree *tree = NULL;
12990         smb_info_t *si;
12991         guint32 neo;
12992         int padcnt;
12993
12994         si = (smb_info_t *)pinfo->private_data;
12995
12996         if(parent_tree){
12997                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12998                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12999                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
13000         }
13001
13002         /*
13003          * We assume that the presence of a next entry offset implies the
13004          * absence of a resume key, as appears to be the case for 4.3.4.6.
13005          */
13006
13007         /* next entry offset */
13008         CHECK_BYTE_COUNT_SUBR(4);
13009         neo = tvb_get_letohl(tvb, offset);
13010         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
13011         COUNT_BYTES_SUBR(4);
13012
13013         /* file index */
13014         CHECK_BYTE_COUNT_SUBR(4);
13015         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
13016         COUNT_BYTES_SUBR(4);
13017
13018         /* file name len */
13019         CHECK_BYTE_COUNT_SUBR(4);
13020         fn_len = tvb_get_letohl(tvb, offset);
13021         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
13022         COUNT_BYTES_SUBR(4);
13023
13024         /* file name */
13025         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13026         CHECK_STRING_SUBR(fn);
13027         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
13028                 fn);
13029         COUNT_BYTES_SUBR(fn_len);
13030
13031         if (check_col(pinfo->cinfo, COL_INFO)) {
13032                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
13033                 fn);
13034         }
13035
13036         /* skip to next structure */
13037         if(neo){
13038                 padcnt = (old_offset + neo) - offset;
13039                 if (padcnt < 0) {
13040                         /*
13041                          * XXX - this is bogus; flag it?
13042                          */
13043                         padcnt = 0;
13044                 }
13045                 if (padcnt != 0) {
13046                         CHECK_BYTE_COUNT_SUBR(padcnt);
13047                         COUNT_BYTES_SUBR(padcnt);
13048                 }
13049         }
13050
13051         proto_item_append_text(item, " File: %s", fn);
13052         proto_item_set_len(item, offset-old_offset);
13053
13054         *trunc = FALSE;
13055         return offset;
13056 }
13057
13058 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
13059
13060 static int
13061 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
13062                 proto_tree *tree, int offset, guint16 *bcp,
13063                 gboolean *trunc)
13064 {
13065         smb_info_t *si = pinfo->private_data;
13066         const char *fn;
13067         int fn_len;
13068
13069         /* NextEntryOffset */
13070         CHECK_BYTE_COUNT_SUBR(4);
13071         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13072         COUNT_BYTES_SUBR(4);
13073         
13074         /* ResumeKey */
13075         CHECK_BYTE_COUNT_SUBR(4);
13076         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
13077         COUNT_BYTES_SUBR(4);
13078
13079         /* End of file (file size) */
13080         CHECK_BYTE_COUNT_SUBR(8);
13081         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
13082         COUNT_BYTES_SUBR(8);
13083
13084         /* Number of bytes */
13085         CHECK_BYTE_COUNT_SUBR(8);
13086         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
13087         COUNT_BYTES_SUBR(8);
13088
13089         /* Last status change */
13090         CHECK_BYTE_COUNT_SUBR(8);
13091         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13092         *bcp -= 8;
13093
13094         /* Last access time */
13095         CHECK_BYTE_COUNT_SUBR(8);
13096         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13097         *bcp -= 8;
13098
13099         /* Last modification time */
13100         CHECK_BYTE_COUNT_SUBR(8);
13101         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13102         *bcp -= 8;
13103
13104         /* File owner uid */
13105         CHECK_BYTE_COUNT_SUBR(8);
13106         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
13107         COUNT_BYTES_SUBR(8);
13108
13109         /* File group gid */
13110         CHECK_BYTE_COUNT_SUBR(8);
13111         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
13112         COUNT_BYTES_SUBR(8);
13113
13114         /* File type */
13115         CHECK_BYTE_COUNT_SUBR(4);
13116         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
13117         COUNT_BYTES_SUBR(4);
13118
13119         /* Major device number */
13120         CHECK_BYTE_COUNT_SUBR(8);
13121         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
13122         COUNT_BYTES_SUBR(8);
13123
13124         /* Minor device number */
13125         CHECK_BYTE_COUNT_SUBR(8);
13126         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
13127         COUNT_BYTES_SUBR(8);
13128
13129         /* Unique id */
13130         CHECK_BYTE_COUNT_SUBR(8);
13131         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
13132         COUNT_BYTES_SUBR(8);
13133
13134         /* Permissions */
13135         CHECK_BYTE_COUNT_SUBR(8);
13136         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
13137         COUNT_BYTES_SUBR(8);
13138
13139         /* Nlinks */
13140         CHECK_BYTE_COUNT_SUBR(8);
13141         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
13142         COUNT_BYTES_SUBR(8);
13143
13144         /* Name */
13145
13146         fn = get_unicode_or_ascii_string(
13147                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13148
13149         CHECK_STRING_SUBR(fn);
13150         proto_tree_add_string(
13151                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13152         COUNT_BYTES_SUBR(fn_len);
13153
13154         /* Pad to 4 bytes */
13155
13156         if (offset % 4)
13157                 offset += 4 - (offset % 4);
13158
13159         *trunc = FALSE;
13160         return offset;
13161 }
13162
13163 /*dissect the data block for TRANS2_FIND_FIRST2*/
13164 static int
13165 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13166     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13167 {
13168         smb_info_t *si;
13169
13170         if(!*bcp){
13171                 return offset;
13172         }
13173
13174         si = (smb_info_t *)pinfo->private_data;
13175         switch(si->info_level){
13176         case 1:         /*Info Standard*/
13177                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13178                     trunc);
13179                 break;
13180         case 2:         /*Info Query EA Size*/
13181                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13182                     trunc);
13183                 break;
13184         case 3:         /*Info Query EAs From List same as
13185                                 InfoQueryEASize*/
13186                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13187                     trunc);
13188                 break;
13189         case 0x0101:    /*Find File Directory Info*/
13190                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13191                     trunc);
13192                 break;
13193         case 0x0102:    /*Find File Full Directory Info*/
13194                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13195                     trunc);
13196                 break;
13197         case 0x0103:    /*Find File Names Info*/
13198                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13199                     trunc);
13200                 break;
13201         case 0x0104:    /*Find File Both Directory Info*/
13202                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13203                     trunc);
13204                 break;
13205         case 0x0202:    /*Find File UNIX*/
13206                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13207                     trunc);
13208                 break;
13209         default:        /* unknown info level */
13210                 *trunc = FALSE;
13211                 break;
13212         }
13213         return offset;
13214 }
13215
13216
13217 static int
13218 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13219 {
13220         guint32 mask;
13221         proto_item *item = NULL;
13222         proto_tree *tree = NULL;
13223
13224         mask = tvb_get_letohl(tvb, offset);
13225
13226         if(parent_tree){
13227                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13228                         "FS Attributes: 0x%08x", mask);
13229                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13230         }
13231
13232         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13233                 tvb, offset, 4, mask);
13234         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13235                 tvb, offset, 4, mask);
13236         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13237                 tvb, offset, 4, mask);
13238         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13239                 tvb, offset, 4, mask);
13240         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13241                 tvb, offset, 4, mask);
13242         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
13243                 tvb, offset, 4, mask);
13244         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13245                 tvb, offset, 4, mask);
13246
13247         offset += 4;
13248         return offset;
13249 }
13250
13251
13252 static int
13253 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13254 {
13255         guint32 mask;
13256         proto_item *item = NULL;
13257         proto_tree *tree = NULL;
13258
13259         mask = tvb_get_letohl(tvb, offset);
13260
13261         if(parent_tree){
13262                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13263                         "Device Characteristics: 0x%08x", mask);
13264                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13265         }
13266
13267         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13268                 tvb, offset, 4, mask);
13269         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13270                 tvb, offset, 4, mask);
13271         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13272                 tvb, offset, 4, mask);
13273         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13274                 tvb, offset, 4, mask);
13275         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13276                 tvb, offset, 4, mask);
13277         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13278                 tvb, offset, 4, mask);
13279         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13280                 tvb, offset, 4, mask);
13281
13282         offset += 4;
13283         return offset;
13284 }
13285
13286 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13287
13288 static const true_false_string tfs_smb_mac_access_ctrl = {
13289   "Macintosh Access Control Supported",
13290   "Macintosh Access Control Not Supported"
13291 };
13292
13293 static const true_false_string tfs_smb_mac_getset_comments = {
13294   "Macintosh Get & Set Comments Supported",
13295   "Macintosh Get & Set Comments Not Supported"
13296 };
13297
13298 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13299   "Macintosh Get & Set Desktop Database Info Supported",
13300   "Macintosh Get & Set Desktop Database Info Supported"
13301 };
13302
13303 static const true_false_string tfs_smb_mac_unique_ids = {
13304   "Macintosh Unique IDs Supported",
13305   "Macintosh Unique IDs Not Supported"
13306 };
13307
13308 static const true_false_string tfs_smb_mac_streams = {
13309   "Macintosh and Streams Extensions Not Supported",
13310   "Macintosh and Streams Extensions Supported"
13311 };
13312
13313 static int
13314 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13315     int offset, guint16 *bcp)
13316 {
13317         smb_info_t *si;
13318         int fn_len, vll, fnl;
13319         const char *fn;
13320         guint support = 0;
13321         proto_item *item = NULL;
13322         proto_tree *ti = NULL;
13323
13324         if(!*bcp){
13325                 return offset;
13326         }
13327
13328         si = (smb_info_t *)pinfo->private_data;
13329         switch(si->info_level){
13330         case 1:         /* SMB_INFO_ALLOCATION */
13331                 /* filesystem id */
13332                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13333                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13334                 COUNT_BYTES_TRANS_SUBR(4);
13335
13336                 /* sectors per unit */
13337                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13338                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13339                 COUNT_BYTES_TRANS_SUBR(4);
13340
13341                 /* units */
13342                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13343                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13344                 COUNT_BYTES_TRANS_SUBR(4);
13345
13346                 /* avail units */
13347                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13348                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13349                 COUNT_BYTES_TRANS_SUBR(4);
13350
13351                 /* bytes per sector, only 16bit integer here */
13352                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13353                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13354                 COUNT_BYTES_TRANS_SUBR(2);
13355
13356                 break;
13357         case 2:         /* SMB_INFO_VOLUME */
13358                 /* volume serial number */
13359                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13360                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13361                 COUNT_BYTES_TRANS_SUBR(4);
13362
13363                 /* volume label length, only one byte here */
13364                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13365                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13366                 COUNT_BYTES_TRANS_SUBR(1);
13367
13368                 /* label */
13369                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13370                 CHECK_STRING_TRANS_SUBR(fn);
13371                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13372                         fn);
13373                 COUNT_BYTES_TRANS_SUBR(fn_len);
13374
13375                 break;
13376         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13377         case 1002:      /* SMB_FS_LABEL_INFORMATION */
13378                 /* volume label length */
13379                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13380                 vll = tvb_get_letohl(tvb, offset);
13381                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13382                 COUNT_BYTES_TRANS_SUBR(4);
13383
13384                 /* label */
13385                 fn_len = vll;
13386                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13387                 CHECK_STRING_TRANS_SUBR(fn);
13388                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13389                         fn);
13390                 COUNT_BYTES_TRANS_SUBR(fn_len);
13391
13392                 break;
13393         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13394         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
13395                 /* create time */
13396                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13397                 offset = dissect_smb_64bit_time(tvb, tree, offset,
13398                         hf_smb_create_time);
13399                 *bcp -= 8;
13400
13401                 /* volume serial number */
13402                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13403                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13404                 COUNT_BYTES_TRANS_SUBR(4);
13405
13406                 /* volume label length */
13407                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13408                 vll = tvb_get_letohl(tvb, offset);
13409                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13410                 COUNT_BYTES_TRANS_SUBR(4);
13411
13412                 /* 2 reserved bytes */
13413                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13414                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13415                 COUNT_BYTES_TRANS_SUBR(2);
13416
13417                 /* label */
13418                 fn_len = vll;
13419                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13420                 CHECK_STRING_TRANS_SUBR(fn);
13421                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13422                         fn);
13423                 COUNT_BYTES_TRANS_SUBR(fn_len);
13424
13425                 break;
13426         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13427         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13428                 /* allocation size */
13429                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13430                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13431                 COUNT_BYTES_TRANS_SUBR(8);
13432
13433                 /* free allocation units */
13434                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13435                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13436                 COUNT_BYTES_TRANS_SUBR(8);
13437
13438                 /* sectors per unit */
13439                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13440                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13441                 COUNT_BYTES_TRANS_SUBR(4);
13442
13443                 /* bytes per sector */
13444                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13445                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13446                 COUNT_BYTES_TRANS_SUBR(4);
13447
13448                 break;
13449         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13450         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13451                 /* device type */
13452                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13453                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13454                 COUNT_BYTES_TRANS_SUBR(4);
13455
13456                 /* device characteristics */
13457                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13458                 offset = dissect_device_characteristics(tvb, tree, offset);
13459                 *bcp -= 4;
13460
13461                 break;
13462         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13463         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13464                 /* FS attributes */
13465                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13466                 offset = dissect_fs_attributes(tvb, tree, offset);
13467                 *bcp -= 4;
13468
13469                 /* max name len */
13470                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13471                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13472                 COUNT_BYTES_TRANS_SUBR(4);
13473
13474                 /* fs name length */
13475                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13476                 fnl = tvb_get_letohl(tvb, offset);
13477                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13478                 COUNT_BYTES_TRANS_SUBR(4);
13479
13480                 /* label */
13481                 fn_len = fnl;
13482                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13483                 CHECK_STRING_TRANS_SUBR(fn);
13484                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13485                         fn);
13486                 COUNT_BYTES_TRANS_SUBR(fn_len);
13487
13488                 break;
13489         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13490                 proto_item *item = NULL;
13491                 proto_tree *subtree = NULL;
13492                 guint32 caps_lo, caps_hi;
13493
13494                 /* MajorVersionNumber */
13495                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13496                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13497                 COUNT_BYTES_TRANS_SUBR(2);
13498
13499                 /* MinorVersionNumber */
13500                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13501                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13502                 COUNT_BYTES_TRANS_SUBR(2);
13503
13504                 /* Capability */
13505
13506                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13507
13508                 caps_lo = tvb_get_letohl(tvb, offset);
13509                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13510
13511                 if (tree) {
13512                         item = proto_tree_add_text(
13513                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13514                                 caps_hi, caps_lo);
13515                         subtree = proto_item_add_subtree(
13516                                 item, ett_smb_unix_capabilities);
13517                 }
13518
13519                 proto_tree_add_boolean(
13520                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13521                         caps_lo);
13522
13523                 proto_tree_add_boolean(
13524                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13525                         caps_lo);
13526
13527                 COUNT_BYTES_TRANS_SUBR(8);
13528
13529                 break;
13530         }
13531         case 0x301:     /* MAC_QUERY_FS_INFO */
13532                 /* Create time */
13533                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13534                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
13535                 *bcp -= 8;
13536                 /* Modify Time */
13537                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13538                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13539                 *bcp -= 8;
13540                 /* Backup Time */
13541                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13542                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13543                 *bcp -= 8;
13544                 /* Allocation blocks */
13545                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13546                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13547                                     offset,
13548                                     4, TRUE);
13549                 COUNT_BYTES_TRANS_SUBR(4);
13550                 /* Allocation Block Size */
13551                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13552                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13553                                     offset, 4, TRUE);
13554                 COUNT_BYTES_TRANS_SUBR(4);
13555                 /* Free Block Count */
13556                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13557                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13558                                     offset, 4, TRUE);
13559                 COUNT_BYTES_TRANS_SUBR(4);
13560                 /* Finder Info ... */
13561                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13562                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13563                                             offset, 32,
13564                                             tvb_get_ptr(tvb, offset,32),
13565                                             "Finder Info: %s",
13566                                             tvb_format_text(tvb, offset, 32));
13567                 COUNT_BYTES_TRANS_SUBR(32);
13568                 /* Number Files */
13569                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13570                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13571                                     offset, 4, TRUE);
13572                 COUNT_BYTES_TRANS_SUBR(4);
13573                 /* Number of Root Directories */
13574                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13575                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13576                                     offset, 4, TRUE);
13577                 COUNT_BYTES_TRANS_SUBR(4);
13578                 /* Number of files */
13579                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13580                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13581                                     offset, 4, TRUE);
13582                 COUNT_BYTES_TRANS_SUBR(4);
13583                 /* Dir Count */
13584                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13585                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13586                                     offset, 4, TRUE);
13587                 COUNT_BYTES_TRANS_SUBR(4);
13588                 /* Mac Support Flags */
13589                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13590                 support = tvb_get_ntohl(tvb, offset);
13591                 item = proto_tree_add_text(tree, tvb, offset, 4,
13592                                            "Mac Support Flags: 0x%08x", support);
13593                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13594                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13595                                        tvb, offset, 4, support);
13596                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13597                                        tvb, offset, 4, support);
13598                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13599                                        tvb, offset, 4, support);
13600                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13601                                        tvb, offset, 4, support);
13602                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13603                                        tvb, offset, 4, support);
13604                 COUNT_BYTES_TRANS_SUBR(4);
13605                 break;
13606         case 1006:      /* QUERY_FS_QUOTA_INFO */
13607                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13608                 break;
13609         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13610                 /* allocation size */
13611                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13612                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13613                 COUNT_BYTES_TRANS_SUBR(8);
13614
13615                 /* caller free allocation units */
13616                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13617                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13618                 COUNT_BYTES_TRANS_SUBR(8);
13619
13620                 /* actual free allocation units */
13621                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13622                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13623                 COUNT_BYTES_TRANS_SUBR(8);
13624
13625                 /* sectors per unit */
13626                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13627                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13628                 COUNT_BYTES_TRANS_SUBR(4);
13629
13630                 /* bytes per sector */
13631                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13632                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13633                 COUNT_BYTES_TRANS_SUBR(4);
13634                 break;
13635         case 1008: /* Query Object ID is GUID plus unknown data */ {
13636                 e_uuid_t fs_id;
13637                 char uuid_str[DCERPC_UUID_STR_LEN]; 
13638                 int uuid_str_len;
13639                 guint8 drep = 0x10;
13640                 
13641                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
13642
13643                 dcerpc_tvb_get_uuid (tvb, offset, &drep, &fs_id);
13644
13645                 uuid_str_len = snprintf(
13646                         uuid_str, DCERPC_UUID_STR_LEN, 
13647                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
13648                         fs_id.Data1, fs_id.Data2, fs_id.Data3,
13649                         fs_id.Data4[0], fs_id.Data4[1],
13650                         fs_id.Data4[2], fs_id.Data4[3],
13651                         fs_id.Data4[4], fs_id.Data4[5],
13652                         fs_id.Data4[6], fs_id.Data4[7]);
13653
13654                 proto_tree_add_string_format(
13655                         tree, hf_smb_fs_guid, tvb,
13656                         offset, 16, uuid_str, "GUID: %s", uuid_str);
13657
13658                 COUNT_BYTES_TRANS_SUBR(16);
13659                 break;
13660             }
13661         }
13662
13663         return offset;
13664 }
13665
13666 static int
13667 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13668     proto_tree *parent_tree)
13669 {
13670         proto_item *item = NULL;
13671         proto_tree *tree = NULL;
13672         smb_info_t *si;
13673         smb_transact2_info_t *t2i;
13674         int count;
13675         gboolean trunc;
13676         int offset = 0;
13677         guint16 dc;
13678
13679         dc = tvb_reported_length(tvb);
13680
13681         si = (smb_info_t *)pinfo->private_data;
13682         if (si->sip != NULL)
13683                 t2i = si->sip->extra_info;
13684         else
13685                 t2i = NULL;
13686
13687         if(parent_tree){
13688                 if (t2i != NULL && t2i->subcmd != -1) {
13689                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13690                                 "%s Data",
13691                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13692                                         "Unknown (0x%02x)"));
13693                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13694                 } else {
13695                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13696                                 "Unknown Transaction2 Data");
13697                 }
13698         }
13699
13700         if (t2i == NULL) {
13701                 offset += dc;
13702                 return offset;
13703         }
13704         switch(t2i->subcmd){
13705         case 0x00:      /*TRANS2_OPEN2*/
13706                 /* XXX not implemented yet. See SNIA doc */
13707                 break;
13708         case 0x01:      /*TRANS2_FIND_FIRST2*/
13709                 /* returned data */
13710                 count = si->info_count;
13711
13712                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13713                         col_append_fstr(pinfo->cinfo, COL_INFO,
13714                         ", Files:");
13715                 }
13716
13717                 while(count--){
13718                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13719                                 offset, &dc, &trunc);
13720                         if (trunc)
13721                                 break;
13722                 }
13723                 break;
13724         case 0x02:      /*TRANS2_FIND_NEXT2*/
13725                 /* returned data */
13726                 count = si->info_count;
13727
13728                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13729                         col_append_fstr(pinfo->cinfo, COL_INFO,
13730                         ", Files:");
13731                 }
13732
13733                 while(count--){
13734                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13735                                 offset, &dc, &trunc);
13736                         if (trunc)
13737                                 break;
13738                 }
13739                 break;
13740         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13741                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13742                 break;
13743         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13744                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13745                 break;
13746         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13747                 /* no data in this response */
13748                 break;
13749         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13750                 /* identical to QUERY_PATH_INFO */
13751                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13752                 break;
13753         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13754                 /* no data in this response */
13755                 break;
13756         case 0x09:      /*TRANS2_FSCTL*/
13757                 /* XXX dont know how to dissect this one (yet)*/
13758
13759                 /*
13760                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13761                  * Extensions Version 3.0, Document Version 1.11,
13762                  * July 19, 1990" says this this contains a
13763                  * "File system specific return data block".
13764                  * (That means we may not be able to dissect it in any
13765                  * case.)
13766                  */
13767                 break;
13768         case 0x0a:      /*TRANS2_IOCTL2*/
13769                 /* XXX dont know how to dissect this one (yet)*/
13770
13771                 /*
13772                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13773                  * Extensions Version 3.0, Document Version 1.11,
13774                  * July 19, 1990" says this this contains a
13775                  * "Device/function specific return data block".
13776                  * (That means we may not be able to dissect it in any
13777                  * case.)
13778                  */
13779                 break;
13780         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13781                 /* XXX dont know how to dissect this one (yet)*/
13782
13783                 /*
13784                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13785                  * Extensions Version 3.0, Document Version 1.11,
13786                  * July 19, 1990" says this this contains "the level
13787                  * dependent information about the changes which
13788                  * occurred".
13789                  */
13790                 break;
13791         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13792                 /* XXX dont know how to dissect this one (yet)*/
13793
13794                 /*
13795                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13796                  * Extensions Version 3.0, Document Version 1.11,
13797                  * July 19, 1990" says this this contains "the level
13798                  * dependent information about the changes which
13799                  * occurred".
13800                  */
13801                 break;
13802         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13803                 /* no data in this response */
13804                 break;
13805         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13806                 /* XXX dont know how to dissect this one (yet)*/
13807                 break;
13808         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13809                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13810                 break;
13811         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13812                 /* the SNIA spec appears to say the response has no data */
13813                 break;
13814         case -1:
13815                 /*
13816                  * We don't know what the matching request was; don't
13817                  * bother putting anything else into the tree for the data.
13818                  */
13819                 offset += dc;
13820                 dc = 0;
13821                 break;
13822         }
13823
13824         /* ooops there were data we didnt know how to process */
13825         if(dc != 0){
13826                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13827                 offset += dc;
13828         }
13829
13830         return offset;
13831 }
13832
13833
13834 static void
13835 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13836 {
13837         proto_item *item = NULL;
13838         proto_tree *tree = NULL;
13839         smb_info_t *si;
13840         smb_transact2_info_t *t2i;
13841         guint16 fid;
13842         int lno;
13843         int offset = 0;
13844         int pc;
13845
13846         pc = tvb_reported_length(tvb);
13847
13848         si = (smb_info_t *)pinfo->private_data;
13849         if (si->sip != NULL)
13850                 t2i = si->sip->extra_info;
13851         else
13852                 t2i = NULL;
13853
13854         if(parent_tree){
13855                 if (t2i != NULL && t2i->subcmd != -1) {
13856                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13857                                 "%s Parameters",
13858                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13859                                                 "Unknown (0x%02x)"));
13860                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13861                 } else {
13862                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13863                                 "Unknown Transaction2 Parameters");
13864                 }
13865         }
13866
13867         if (t2i == NULL) {
13868                 offset += pc;
13869                 return;
13870         }
13871         switch(t2i->subcmd){
13872         case 0x00:      /*TRANS2_OPEN2*/
13873                 /* fid */
13874                 fid = tvb_get_letohs(tvb, offset);
13875                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13876                 offset += 2;
13877
13878                 /*
13879                  * XXX - Microsoft Networks SMB File Sharing Protocol
13880                  * Extensions Version 3.0, Document Version 1.11,
13881                  * July 19, 1990 says that the file attributes, create
13882                  * time (which it says is the last modification time),
13883                  * data size, granted access, file type, and IPC state
13884                  * are returned only if bit 0 is set in the open flags,
13885                  * and that the EA length is returned only if bit 3
13886                  * is set in the open flags.  Does that mean that,
13887                  * at least in that SMB dialect, those fields are not
13888                  * present in the reply parameters if the bits in
13889                  * question aren't set?
13890                  */
13891
13892                 /* File Attributes */
13893                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13894
13895                 /* create time */
13896                 offset = dissect_smb_datetime(tvb, tree, offset,
13897                         hf_smb_create_time,
13898                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13899
13900                 /* data size */
13901                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13902                 offset += 4;
13903
13904                 /* granted access */
13905                 offset = dissect_access(tvb, tree, offset, "Granted");
13906
13907                 /* File Type */
13908                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13909                 offset += 2;
13910
13911                 /* IPC State */
13912                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13913
13914                 /* open_action */
13915                 offset = dissect_open_action(tvb, tree, offset);
13916
13917                 /* server unique file ID */
13918                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13919                 offset += 4;
13920
13921                 /* ea error offset, only a 16 bit integer here */
13922                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13923                 offset += 2;
13924
13925                 /* ea length */
13926                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13927                 offset += 4;
13928
13929                 break;
13930         case 0x01:      /*TRANS2_FIND_FIRST2*/
13931                 /* Find First2 information level */
13932                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13933
13934                 /* sid */
13935                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13936                 offset += 2;
13937
13938                 /* search count */
13939                 si->info_count = tvb_get_letohs(tvb, offset);
13940                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13941                 offset += 2;
13942
13943                 /* end of search */
13944                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13945                 offset += 2;
13946
13947                 /* ea error offset, only a 16 bit integer here */
13948                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13949                 offset += 2;
13950
13951                 /* last name offset */
13952                 lno = tvb_get_letohs(tvb, offset);
13953                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13954                 offset += 2;
13955
13956                 break;
13957         case 0x02:      /*TRANS2_FIND_NEXT2*/
13958                 /* search count */
13959                 si->info_count = tvb_get_letohs(tvb, offset);
13960                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13961                 offset += 2;
13962
13963                 /* end of search */
13964                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13965                 offset += 2;
13966
13967                 /* ea_error_offset, only a 16 bit integer here*/
13968                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13969                 offset += 2;
13970
13971                 /* last name offset */
13972                 lno = tvb_get_letohs(tvb, offset);
13973                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13974                 offset += 2;
13975
13976                 break;
13977         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13978                 /* no parameter block here */
13979                 break;
13980         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13981                 /* ea_error_offset, only a 16 bit integer here*/
13982                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13983                 offset += 2;
13984
13985                 break;
13986         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13987                 /* ea_error_offset, only a 16 bit integer here*/
13988                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13989                 offset += 2;
13990
13991                 break;
13992         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13993                 /* ea_error_offset, only a 16 bit integer here*/
13994                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13995                 offset += 2;
13996
13997                 break;
13998         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13999                 /* ea_error_offset, only a 16 bit integer here*/
14000                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14001                 offset += 2;
14002
14003                 break;
14004         case 0x09:      /*TRANS2_FSCTL*/
14005                 /* XXX dont know how to dissect this one (yet)*/
14006
14007                 /*
14008                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14009                  * Extensions Version 3.0, Document Version 1.11,
14010                  * July 19, 1990" says this this contains a
14011                  * "File system specific return parameter block".
14012                  * (That means we may not be able to dissect it in any
14013                  * case.)
14014                  */
14015                 break;
14016         case 0x0a:      /*TRANS2_IOCTL2*/
14017                 /* XXX dont know how to dissect this one (yet)*/
14018
14019                 /*
14020                  * XXX - "Microsoft Networks SMB File Sharing Protocol
14021                  * Extensions Version 3.0, Document Version 1.11,
14022                  * July 19, 1990" says this this contains a
14023                  * "Device/function specific return parameter block".
14024                  * (That means we may not be able to dissect it in any
14025                  * case.)
14026                  */
14027                 break;
14028         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
14029                 /* Find Notify information level */
14030                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14031
14032                 /* Monitor handle */
14033                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14034                 offset += 2;
14035
14036                 /* Change count */
14037                 si->info_count = tvb_get_letohs(tvb, offset);
14038                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14039                 offset += 2;
14040
14041                 /* ea_error_offset, only a 16 bit integer here*/
14042                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14043                 offset += 2;
14044
14045                 break;
14046         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
14047                 /* Find Notify information level */
14048                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
14049
14050                 /* Change count */
14051                 si->info_count = tvb_get_letohs(tvb, offset);
14052                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
14053                 offset += 2;
14054
14055                 /* ea_error_offset, only a 16 bit integer here*/
14056                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14057                 offset += 2;
14058
14059                 break;
14060         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
14061                 /* ea error offset, only a 16 bit integer here */
14062                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
14063                 offset += 2;
14064
14065                 break;
14066         case 0x0e:      /*TRANS2_SESSION_SETUP*/
14067                 /* XXX dont know how to dissect this one (yet)*/
14068                 break;
14069         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14070                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14071                 break;
14072         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14073                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14074                 break;
14075         case -1:
14076                 /*
14077                  * We don't know what the matching request was; don't
14078                  * bother putting anything else into the tree for the data.
14079                  */
14080                 offset += pc;
14081                 break;
14082         }
14083
14084         /* ooops there were data we didnt know how to process */
14085         if(offset<pc){
14086                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
14087                 offset += pc-offset;
14088         }
14089 }
14090
14091
14092 static int
14093 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14094 {
14095         guint8 sc, wc;
14096         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
14097         smb_info_t *si;
14098         smb_transact2_info_t *t2i = NULL;
14099         guint16 bc;
14100         int padcnt;
14101         gboolean dissected_trans;
14102         fragment_data *r_fd = NULL;
14103         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
14104         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
14105         gboolean save_fragmented;
14106
14107         si = (smb_info_t *)pinfo->private_data;
14108
14109         switch(si->cmd){
14110         case SMB_COM_TRANSACTION2:
14111                 /* transaction2 */
14112                 if (si->sip != NULL) {
14113                         t2i = si->sip->extra_info;
14114                 } else
14115                         t2i = NULL;
14116                 if (t2i == NULL) {
14117                         /*
14118                          * We didn't see the matching request, so we don't
14119                          * know what type of transaction this is.
14120                          */
14121                         proto_tree_add_text(tree, tvb, 0, 0,
14122                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
14123                         if (check_col(pinfo->cinfo, COL_INFO)) {
14124                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14125                         }
14126                 } else {
14127                         si->info_level = t2i->info_level;
14128                         if (t2i->subcmd == -1) {
14129                                 /*
14130                                  * We didn't manage to extract the subcommand
14131                                  * from the matching request (perhaps because
14132                                  * the frame was short), so we don't know what
14133                                  * type of transaction this is.
14134                                  */
14135                                 proto_tree_add_text(tree, tvb, 0, 0,
14136                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
14137                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14138                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14139                                 }
14140                         } else {
14141                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
14142                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14143                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14144                                                 val_to_str(t2i->subcmd,
14145                                                         trans2_cmd_vals,
14146                                                         "<unknown (0x%02x)>"));
14147                                 }
14148                         }
14149                 }
14150                 break;
14151         }
14152
14153         WORD_COUNT;
14154
14155         /* total param count, only a 16bit integer here */
14156         tp = tvb_get_letohs(tvb, offset);
14157         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14158         offset += 2;
14159
14160         /* total data count, only a 16 bit integer here */
14161         td = tvb_get_letohs(tvb, offset);
14162         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14163         offset += 2;
14164
14165         /* 2 reserved bytes */
14166         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14167         offset += 2;
14168
14169         /* param count */
14170         pc = tvb_get_letohs(tvb, offset);
14171         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14172         offset += 2;
14173
14174         /* param offset */
14175         po = tvb_get_letohs(tvb, offset);
14176         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14177         offset += 2;
14178
14179         /* param disp */
14180         pd = tvb_get_letohs(tvb, offset);
14181         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14182         offset += 2;
14183
14184         /* data count */
14185         dc = tvb_get_letohs(tvb, offset);
14186         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14187         offset += 2;
14188
14189         /* data offset */
14190         od = tvb_get_letohs(tvb, offset);
14191         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14192         offset += 2;
14193
14194         /* data disp */
14195         dd = tvb_get_letohs(tvb, offset);
14196         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14197         offset += 2;
14198
14199         /* setup count */
14200         sc = tvb_get_guint8(tvb, offset);
14201         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14202         offset += 1;
14203
14204         /* reserved byte */
14205         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14206         offset += 1;
14207
14208
14209         /* if there were any setup bytes, put them in a tvb for later */
14210         if(sc){
14211                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14212                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14213                 } else {
14214                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14215                 }
14216                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14217         } else {
14218                 s_tvb = NULL;
14219                 sp_tvb=NULL;
14220         }
14221         offset += 2*sc;
14222
14223
14224         BYTE_COUNT;
14225
14226
14227         /* reassembly of SMB Transaction data payload.
14228            In this section we do reassembly of both the data and parameters
14229            blocks of the SMB transaction command.
14230         */
14231         save_fragmented = pinfo->fragmented;
14232         /* do we need reassembly? */
14233         if( (td!=dc) || (tp!=pc) ){
14234                 /* oh yeah, either data or parameter section needs
14235                    reassembly
14236                 */
14237                 pinfo->fragmented = TRUE;
14238                 if(smb_trans_reassembly){
14239                         /* ...and we were told to do reassembly */
14240                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14241                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14242                                                              po, pc, pd, td+tp);
14243
14244                         }
14245                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14246                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14247                                                              od, dc, dd+tp, td+tp);
14248                         }
14249                 }
14250         }
14251
14252         /* if we got a reassembled fd structure from the reassembly routine we must
14253            create pd_tvb from it
14254         */
14255         if(r_fd){
14256                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14257                                              r_fd->datalen);
14258                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14259                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14260                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
14261         }
14262
14263
14264         if(pd_tvb){
14265                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14266                 if(tp){
14267                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14268                 }
14269                 if(td){
14270                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14271                 }
14272         } else {
14273                 /* It was not reassembled. Do as best as we can.
14274                  * in this case we always try to dissect the stuff if
14275                  * data and param displacement is 0. i.e. for the first
14276                  * (and maybe only) packet.
14277                  */
14278                 if( (pd==0) && (dd==0) ){
14279                         int min;
14280                         int reported_min;
14281                         min = MIN(pc,tvb_length_remaining(tvb,po));
14282                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14283                         if(min && reported_min) {
14284                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14285                         }
14286                         min = MIN(dc,tvb_length_remaining(tvb,od));
14287                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14288                         if(min && reported_min) {
14289                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14290                         }
14291                         /*
14292                          * A tvbuff containing the parameters
14293                          * and the data.
14294                          * XXX - check pc and dc as well?
14295                          */
14296                         if (tvb_length_remaining(tvb, po)){
14297                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14298                         }
14299                 }
14300         }
14301
14302
14303
14304         /* parameters */
14305         if(po>offset){
14306                 /* We have some padding bytes.
14307                 */
14308                 padcnt = po-offset;
14309                 if (padcnt > bc)
14310                         padcnt = bc;
14311                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14312                 COUNT_BYTES(padcnt);
14313         }
14314         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14315                 /* TRANSACTION2 parameters*/
14316                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14317         }
14318         COUNT_BYTES(pc);
14319
14320
14321         /* data */
14322         if(od>offset){
14323                 /* We have some initial padding bytes.
14324                 */
14325                 padcnt = od-offset;
14326                 if (padcnt > bc)
14327                         padcnt = bc;
14328                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14329                 COUNT_BYTES(padcnt);
14330         }
14331         /*
14332          * If the data count is bigger than the count of bytes
14333          * remaining, clamp it so that the count of bytes remaining
14334          * doesn't go negative.
14335          */
14336         if (dc > bc)
14337                 dc = bc;
14338         COUNT_BYTES(dc);
14339
14340
14341
14342         /* from now on, everything is in separate tvbuffs so we dont count
14343            the bytes with COUNT_BYTES any more.
14344            neither do we reference offset any more (which by now points to the
14345            first byte AFTER this PDU */
14346
14347
14348         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14349                 /* TRANSACTION2 parameters*/
14350                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14351         }
14352
14353
14354         if(si->cmd==SMB_COM_TRANSACTION){
14355                 smb_transact_info_t *tri;
14356
14357                 dissected_trans = FALSE;
14358                 if (si->sip != NULL)
14359                         tri = si->sip->extra_info;
14360                 else
14361                         tri = NULL;
14362                 if (tri != NULL) {
14363                         switch(tri->subcmd){
14364
14365                         case TRANSACTION_PIPE:
14366                                 /* This function is safe to call for
14367                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14368                                    know them at this point.
14369                                    It's also safe to call if "p_tvb"
14370                                    or "d_tvb" are null.
14371                                 */
14372                                 if( pd_tvb) {
14373                                         dissected_trans = dissect_pipe_smb(
14374                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14375                                                 d_tvb, NULL, pinfo, top_tree);
14376                                 }
14377                                 break;
14378
14379                         case TRANSACTION_MAILSLOT:
14380                                 /* This one should be safe to call
14381                                    even if s_tvb and sp_tvb is NULL
14382                                 */
14383                                 if(d_tvb){
14384                                         dissected_trans = dissect_mailslot_smb(
14385                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14386                                                 top_tree);
14387                                 }
14388                                 break;
14389                         }
14390                 }
14391                 if (!dissected_trans) {
14392                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14393                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14394                 }
14395         }
14396
14397
14398         if( (p_tvb==0) && (d_tvb==0) ){
14399                 if(check_col(pinfo->cinfo, COL_INFO)){
14400                         col_append_str(pinfo->cinfo, COL_INFO,
14401                                        "[transact continuation]");
14402                 }
14403         }
14404
14405         pinfo->fragmented = save_fragmented;
14406         END_OF_SMB
14407
14408         return offset;
14409 }
14410
14411
14412 static int
14413 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14414 {
14415         guint8 wc;
14416         guint16 bc;
14417
14418         WORD_COUNT;
14419
14420         /* Monitor handle */
14421         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14422         offset += 2;
14423
14424         BYTE_COUNT;
14425
14426         END_OF_SMB
14427
14428         return offset;
14429 }
14430
14431 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14432    END Transaction/Transaction2 Primary and secondary requests
14433    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14434
14435
14436 static int
14437 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14438 {
14439         guint8 wc;
14440         guint16 bc;
14441
14442         WORD_COUNT;
14443
14444         if (wc != 0) {
14445                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14446                 offset += wc*2;
14447         }
14448
14449         BYTE_COUNT;
14450
14451         if (bc != 0) {
14452                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14453                 offset += bc;
14454                 bc = 0;
14455         }
14456
14457         END_OF_SMB
14458
14459         return offset;
14460 }
14461
14462 typedef struct _smb_function {
14463        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14464        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14465 } smb_function;
14466
14467 static smb_function smb_dissector[256] = {
14468   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14469   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14470   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14471   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
14472   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14473   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
14474   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14475   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14476   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14477   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14478   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14479   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14480   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14481   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14482   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14483   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
14484
14485   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14486   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14487   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14488   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14489   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14490   /* 0x15 */  {dissect_unknown, dissect_unknown},
14491   /* 0x16 */  {dissect_unknown, dissect_unknown},
14492   /* 0x17 */  {dissect_unknown, dissect_unknown},
14493   /* 0x18 */  {dissect_unknown, dissect_unknown},
14494   /* 0x19 */  {dissect_unknown, dissect_unknown},
14495   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14496   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14497   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14498   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14499   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14500   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14501
14502   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14503   /* 0x21 */  {dissect_unknown, dissect_unknown},
14504   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14505   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
14506   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14507   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14508   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14509   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14510   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14511   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14512   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14513   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14514   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14515   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14516   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14517   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14518
14519   /* 0x30 */  {dissect_unknown, dissect_unknown},
14520   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14521   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14522   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14523   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14524   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14525   /* 0x36 */  {dissect_unknown, dissect_unknown},
14526   /* 0x37 */  {dissect_unknown, dissect_unknown},
14527   /* 0x38 */  {dissect_unknown, dissect_unknown},
14528   /* 0x39 */  {dissect_unknown, dissect_unknown},
14529   /* 0x3a */  {dissect_unknown, dissect_unknown},
14530   /* 0x3b */  {dissect_unknown, dissect_unknown},
14531   /* 0x3c */  {dissect_unknown, dissect_unknown},
14532   /* 0x3d */  {dissect_unknown, dissect_unknown},
14533   /* 0x3e */  {dissect_unknown, dissect_unknown},
14534   /* 0x3f */  {dissect_unknown, dissect_unknown},
14535
14536   /* 0x40 */  {dissect_unknown, dissect_unknown},
14537   /* 0x41 */  {dissect_unknown, dissect_unknown},
14538   /* 0x42 */  {dissect_unknown, dissect_unknown},
14539   /* 0x43 */  {dissect_unknown, dissect_unknown},
14540   /* 0x44 */  {dissect_unknown, dissect_unknown},
14541   /* 0x45 */  {dissect_unknown, dissect_unknown},
14542   /* 0x46 */  {dissect_unknown, dissect_unknown},
14543   /* 0x47 */  {dissect_unknown, dissect_unknown},
14544   /* 0x48 */  {dissect_unknown, dissect_unknown},
14545   /* 0x49 */  {dissect_unknown, dissect_unknown},
14546   /* 0x4a */  {dissect_unknown, dissect_unknown},
14547   /* 0x4b */  {dissect_unknown, dissect_unknown},
14548   /* 0x4c */  {dissect_unknown, dissect_unknown},
14549   /* 0x4d */  {dissect_unknown, dissect_unknown},
14550   /* 0x4e */  {dissect_unknown, dissect_unknown},
14551   /* 0x4f */  {dissect_unknown, dissect_unknown},
14552
14553   /* 0x50 */  {dissect_unknown, dissect_unknown},
14554   /* 0x51 */  {dissect_unknown, dissect_unknown},
14555   /* 0x52 */  {dissect_unknown, dissect_unknown},
14556   /* 0x53 */  {dissect_unknown, dissect_unknown},
14557   /* 0x54 */  {dissect_unknown, dissect_unknown},
14558   /* 0x55 */  {dissect_unknown, dissect_unknown},
14559   /* 0x56 */  {dissect_unknown, dissect_unknown},
14560   /* 0x57 */  {dissect_unknown, dissect_unknown},
14561   /* 0x58 */  {dissect_unknown, dissect_unknown},
14562   /* 0x59 */  {dissect_unknown, dissect_unknown},
14563   /* 0x5a */  {dissect_unknown, dissect_unknown},
14564   /* 0x5b */  {dissect_unknown, dissect_unknown},
14565   /* 0x5c */  {dissect_unknown, dissect_unknown},
14566   /* 0x5d */  {dissect_unknown, dissect_unknown},
14567   /* 0x5e */  {dissect_unknown, dissect_unknown},
14568   /* 0x5f */  {dissect_unknown, dissect_unknown},
14569
14570   /* 0x60 */  {dissect_unknown, dissect_unknown},
14571   /* 0x61 */  {dissect_unknown, dissect_unknown},
14572   /* 0x62 */  {dissect_unknown, dissect_unknown},
14573   /* 0x63 */  {dissect_unknown, dissect_unknown},
14574   /* 0x64 */  {dissect_unknown, dissect_unknown},
14575   /* 0x65 */  {dissect_unknown, dissect_unknown},
14576   /* 0x66 */  {dissect_unknown, dissect_unknown},
14577   /* 0x67 */  {dissect_unknown, dissect_unknown},
14578   /* 0x68 */  {dissect_unknown, dissect_unknown},
14579   /* 0x69 */  {dissect_unknown, dissect_unknown},
14580   /* 0x6a */  {dissect_unknown, dissect_unknown},
14581   /* 0x6b */  {dissect_unknown, dissect_unknown},
14582   /* 0x6c */  {dissect_unknown, dissect_unknown},
14583   /* 0x6d */  {dissect_unknown, dissect_unknown},
14584   /* 0x6e */  {dissect_unknown, dissect_unknown},
14585   /* 0x6f */  {dissect_unknown, dissect_unknown},
14586
14587   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14588   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14589   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14590   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14591   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14592   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14593   /* 0x76 */  {dissect_unknown, dissect_unknown},
14594   /* 0x77 */  {dissect_unknown, dissect_unknown},
14595   /* 0x78 */  {dissect_unknown, dissect_unknown},
14596   /* 0x79 */  {dissect_unknown, dissect_unknown},
14597   /* 0x7a */  {dissect_unknown, dissect_unknown},
14598   /* 0x7b */  {dissect_unknown, dissect_unknown},
14599   /* 0x7c */  {dissect_unknown, dissect_unknown},
14600   /* 0x7d */  {dissect_unknown, dissect_unknown},
14601   /* 0x7e */  {dissect_unknown, dissect_unknown},
14602   /* 0x7f */  {dissect_unknown, dissect_unknown},
14603
14604   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14605   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14606   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14607   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14608   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14609   /* 0x85 */  {dissect_unknown, dissect_unknown},
14610   /* 0x86 */  {dissect_unknown, dissect_unknown},
14611   /* 0x87 */  {dissect_unknown, dissect_unknown},
14612   /* 0x88 */  {dissect_unknown, dissect_unknown},
14613   /* 0x89 */  {dissect_unknown, dissect_unknown},
14614   /* 0x8a */  {dissect_unknown, dissect_unknown},
14615   /* 0x8b */  {dissect_unknown, dissect_unknown},
14616   /* 0x8c */  {dissect_unknown, dissect_unknown},
14617   /* 0x8d */  {dissect_unknown, dissect_unknown},
14618   /* 0x8e */  {dissect_unknown, dissect_unknown},
14619   /* 0x8f */  {dissect_unknown, dissect_unknown},
14620
14621   /* 0x90 */  {dissect_unknown, dissect_unknown},
14622   /* 0x91 */  {dissect_unknown, dissect_unknown},
14623   /* 0x92 */  {dissect_unknown, dissect_unknown},
14624   /* 0x93 */  {dissect_unknown, dissect_unknown},
14625   /* 0x94 */  {dissect_unknown, dissect_unknown},
14626   /* 0x95 */  {dissect_unknown, dissect_unknown},
14627   /* 0x96 */  {dissect_unknown, dissect_unknown},
14628   /* 0x97 */  {dissect_unknown, dissect_unknown},
14629   /* 0x98 */  {dissect_unknown, dissect_unknown},
14630   /* 0x99 */  {dissect_unknown, dissect_unknown},
14631   /* 0x9a */  {dissect_unknown, dissect_unknown},
14632   /* 0x9b */  {dissect_unknown, dissect_unknown},
14633   /* 0x9c */  {dissect_unknown, dissect_unknown},
14634   /* 0x9d */  {dissect_unknown, dissect_unknown},
14635   /* 0x9e */  {dissect_unknown, dissect_unknown},
14636   /* 0x9f */  {dissect_unknown, dissect_unknown},
14637
14638   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14639   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14640   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14641   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14642   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14643   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14644   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14645   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14646   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14647   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14648   /* 0xaa */  {dissect_unknown, dissect_unknown},
14649   /* 0xab */  {dissect_unknown, dissect_unknown},
14650   /* 0xac */  {dissect_unknown, dissect_unknown},
14651   /* 0xad */  {dissect_unknown, dissect_unknown},
14652   /* 0xae */  {dissect_unknown, dissect_unknown},
14653   /* 0xaf */  {dissect_unknown, dissect_unknown},
14654
14655   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14656   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14657   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14658   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14659   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14660   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14661   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14662   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14663   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14664   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14665   /* 0xba */  {dissect_unknown, dissect_unknown},
14666   /* 0xbb */  {dissect_unknown, dissect_unknown},
14667   /* 0xbc */  {dissect_unknown, dissect_unknown},
14668   /* 0xbd */  {dissect_unknown, dissect_unknown},
14669   /* 0xbe */  {dissect_unknown, dissect_unknown},
14670   /* 0xbf */  {dissect_unknown, dissect_unknown},
14671
14672   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14673   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14674   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14675   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14676   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14677   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14678   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14679   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14680   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14681   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14682   /* 0xca */  {dissect_unknown, dissect_unknown},
14683   /* 0xcb */  {dissect_unknown, dissect_unknown},
14684   /* 0xcc */  {dissect_unknown, dissect_unknown},
14685   /* 0xcd */  {dissect_unknown, dissect_unknown},
14686   /* 0xce */  {dissect_unknown, dissect_unknown},
14687   /* 0xcf */  {dissect_unknown, dissect_unknown},
14688
14689   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14690   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14691   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14692   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14693   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14694   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14695   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14696   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14697   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14698   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14699   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14700   /* 0xdb */  {dissect_unknown, dissect_unknown},
14701   /* 0xdc */  {dissect_unknown, dissect_unknown},
14702   /* 0xdd */  {dissect_unknown, dissect_unknown},
14703   /* 0xde */  {dissect_unknown, dissect_unknown},
14704   /* 0xdf */  {dissect_unknown, dissect_unknown},
14705
14706   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14707   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14708   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14709   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14710   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14711   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14712   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14713   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14714   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14715   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14716   /* 0xea */  {dissect_unknown, dissect_unknown},
14717   /* 0xeb */  {dissect_unknown, dissect_unknown},
14718   /* 0xec */  {dissect_unknown, dissect_unknown},
14719   /* 0xed */  {dissect_unknown, dissect_unknown},
14720   /* 0xee */  {dissect_unknown, dissect_unknown},
14721   /* 0xef */  {dissect_unknown, dissect_unknown},
14722
14723   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14724   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14725   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14726   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14727   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14728   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14729   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14730   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14731   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14732   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14733   /* 0xfa */  {dissect_unknown, dissect_unknown},
14734   /* 0xfb */  {dissect_unknown, dissect_unknown},
14735   /* 0xfc */  {dissect_unknown, dissect_unknown},
14736   /* 0xfd */  {dissect_unknown, dissect_unknown},
14737   /* 0xfe */  {dissect_unknown, dissect_unknown},
14738   /* 0xff */  {dissect_unknown, dissect_unknown},
14739 };
14740
14741 static int
14742 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14743 {
14744         smb_info_t *si;
14745
14746         si = pinfo->private_data;
14747         if(cmd!=0xff){
14748                 proto_item *cmd_item;
14749                 proto_tree *cmd_tree;
14750                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14751
14752                 if (check_col(pinfo->cinfo, COL_INFO)) {
14753                         if(first_pdu){
14754                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14755                                         "%s %s",
14756                                         decode_smb_name(cmd),
14757                                         (si->request)? "Request" : "Response");
14758                         } else {
14759                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14760                                         "; %s",
14761                                         decode_smb_name(cmd));
14762                         }
14763
14764                 }
14765
14766                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14767                         "%s %s (0x%02x)",
14768                         decode_smb_name(cmd),
14769                         (si->request)?"Request":"Response",
14770                         cmd);
14771
14772                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14773
14774                 dissector = (si->request)?
14775                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14776
14777                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14778                 proto_item_set_end(cmd_item, tvb, offset);
14779         }
14780         return offset;
14781 }
14782
14783
14784 /* NOTE: this value_string array will also be used to access data directly by
14785  * index instead of val_to_str() since
14786  * 1, the array will always span every value from 0x00 to 0xff and
14787  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14788  * This means that this value_string array MUST always
14789  * 1, contain all entries 0x00 to 0xff
14790  * 2, all entries must be in order.
14791  */
14792 const value_string smb_cmd_vals[] = {
14793   { 0x00, "Create Directory" },
14794   { 0x01, "Delete Directory" },
14795   { 0x02, "Open" },
14796   { 0x03, "Create" },
14797   { 0x04, "Close" },
14798   { 0x05, "Flush" },
14799   { 0x06, "Delete" },
14800   { 0x07, "Rename" },
14801   { 0x08, "Query Information" },
14802   { 0x09, "Set Information" },
14803   { 0x0A, "Read" },
14804   { 0x0B, "Write" },
14805   { 0x0C, "Lock Byte Range" },
14806   { 0x0D, "Unlock Byte Range" },
14807   { 0x0E, "Create Temp" },
14808   { 0x0F, "Create New" },
14809   { 0x10, "Check Directory" },
14810   { 0x11, "Process Exit" },
14811   { 0x12, "Seek" },
14812   { 0x13, "Lock And Read" },
14813   { 0x14, "Write And Unlock" },
14814   { 0x15, "unknown-0x15" },
14815   { 0x16, "unknown-0x16" },
14816   { 0x17, "unknown-0x17" },
14817   { 0x18, "unknown-0x18" },
14818   { 0x19, "unknown-0x19" },
14819   { 0x1A, "Read Raw" },
14820   { 0x1B, "Read MPX" },
14821   { 0x1C, "Read MPX Secondary" },
14822   { 0x1D, "Write Raw" },
14823   { 0x1E, "Write MPX" },
14824   { 0x1F, "Write MPX Secondary" },
14825   { 0x20, "Write Complete" },
14826   { 0x21, "unknown-0x21" },
14827   { 0x22, "Set Information2" },
14828   { 0x23, "Query Information2" },
14829   { 0x24, "Locking AndX" },
14830   { 0x25, "Trans" },
14831   { 0x26, "Trans Secondary" },
14832   { 0x27, "IOCTL" },
14833   { 0x28, "IOCTL Secondary" },
14834   { 0x29, "Copy" },
14835   { 0x2A, "Move" },
14836   { 0x2B, "Echo" },
14837   { 0x2C, "Write And Close" },
14838   { 0x2D, "Open AndX" },
14839   { 0x2E, "Read AndX" },
14840   { 0x2F, "Write AndX" },
14841   { 0x30, "unknown-0x30" },
14842   { 0x31, "Close And Tree Disconnect" },
14843   { 0x32, "Trans2" },
14844   { 0x33, "Trans2 Secondary" },
14845   { 0x34, "Find Close2" },
14846   { 0x35, "Find Notify Close" },
14847   { 0x36, "unknown-0x36" },
14848   { 0x37, "unknown-0x37" },
14849   { 0x38, "unknown-0x38" },
14850   { 0x39, "unknown-0x39" },
14851   { 0x3A, "unknown-0x3A" },
14852   { 0x3B, "unknown-0x3B" },
14853   { 0x3C, "unknown-0x3C" },
14854   { 0x3D, "unknown-0x3D" },
14855   { 0x3E, "unknown-0x3E" },
14856   { 0x3F, "unknown-0x3F" },
14857   { 0x40, "unknown-0x40" },
14858   { 0x41, "unknown-0x41" },
14859   { 0x42, "unknown-0x42" },
14860   { 0x43, "unknown-0x43" },
14861   { 0x44, "unknown-0x44" },
14862   { 0x45, "unknown-0x45" },
14863   { 0x46, "unknown-0x46" },
14864   { 0x47, "unknown-0x47" },
14865   { 0x48, "unknown-0x48" },
14866   { 0x49, "unknown-0x49" },
14867   { 0x4A, "unknown-0x4A" },
14868   { 0x4B, "unknown-0x4B" },
14869   { 0x4C, "unknown-0x4C" },
14870   { 0x4D, "unknown-0x4D" },
14871   { 0x4E, "unknown-0x4E" },
14872   { 0x4F, "unknown-0x4F" },
14873   { 0x50, "unknown-0x50" },
14874   { 0x51, "unknown-0x51" },
14875   { 0x52, "unknown-0x52" },
14876   { 0x53, "unknown-0x53" },
14877   { 0x54, "unknown-0x54" },
14878   { 0x55, "unknown-0x55" },
14879   { 0x56, "unknown-0x56" },
14880   { 0x57, "unknown-0x57" },
14881   { 0x58, "unknown-0x58" },
14882   { 0x59, "unknown-0x59" },
14883   { 0x5A, "unknown-0x5A" },
14884   { 0x5B, "unknown-0x5B" },
14885   { 0x5C, "unknown-0x5C" },
14886   { 0x5D, "unknown-0x5D" },
14887   { 0x5E, "unknown-0x5E" },
14888   { 0x5F, "unknown-0x5F" },
14889   { 0x60, "unknown-0x60" },
14890   { 0x61, "unknown-0x61" },
14891   { 0x62, "unknown-0x62" },
14892   { 0x63, "unknown-0x63" },
14893   { 0x64, "unknown-0x64" },
14894   { 0x65, "unknown-0x65" },
14895   { 0x66, "unknown-0x66" },
14896   { 0x67, "unknown-0x67" },
14897   { 0x68, "unknown-0x68" },
14898   { 0x69, "unknown-0x69" },
14899   { 0x6A, "unknown-0x6A" },
14900   { 0x6B, "unknown-0x6B" },
14901   { 0x6C, "unknown-0x6C" },
14902   { 0x6D, "unknown-0x6D" },
14903   { 0x6E, "unknown-0x6E" },
14904   { 0x6F, "unknown-0x6F" },
14905   { 0x70, "Tree Connect" },
14906   { 0x71, "Tree Disconnect" },
14907   { 0x72, "Negotiate Protocol" },
14908   { 0x73, "Session Setup AndX" },
14909   { 0x74, "Logoff AndX" },
14910   { 0x75, "Tree Connect AndX" },
14911   { 0x76, "unknown-0x76" },
14912   { 0x77, "unknown-0x77" },
14913   { 0x78, "unknown-0x78" },
14914   { 0x79, "unknown-0x79" },
14915   { 0x7A, "unknown-0x7A" },
14916   { 0x7B, "unknown-0x7B" },
14917   { 0x7C, "unknown-0x7C" },
14918   { 0x7D, "unknown-0x7D" },
14919   { 0x7E, "unknown-0x7E" },
14920   { 0x7F, "unknown-0x7F" },
14921   { 0x80, "Query Information Disk" },
14922   { 0x81, "Search" },
14923   { 0x82, "Find" },
14924   { 0x83, "Find Unique" },
14925   { 0x84, "Find Close" },
14926   { 0x85, "unknown-0x85" },
14927   { 0x86, "unknown-0x86" },
14928   { 0x87, "unknown-0x87" },
14929   { 0x88, "unknown-0x88" },
14930   { 0x89, "unknown-0x89" },
14931   { 0x8A, "unknown-0x8A" },
14932   { 0x8B, "unknown-0x8B" },
14933   { 0x8C, "unknown-0x8C" },
14934   { 0x8D, "unknown-0x8D" },
14935   { 0x8E, "unknown-0x8E" },
14936   { 0x8F, "unknown-0x8F" },
14937   { 0x90, "unknown-0x90" },
14938   { 0x91, "unknown-0x91" },
14939   { 0x92, "unknown-0x92" },
14940   { 0x93, "unknown-0x93" },
14941   { 0x94, "unknown-0x94" },
14942   { 0x95, "unknown-0x95" },
14943   { 0x96, "unknown-0x96" },
14944   { 0x97, "unknown-0x97" },
14945   { 0x98, "unknown-0x98" },
14946   { 0x99, "unknown-0x99" },
14947   { 0x9A, "unknown-0x9A" },
14948   { 0x9B, "unknown-0x9B" },
14949   { 0x9C, "unknown-0x9C" },
14950   { 0x9D, "unknown-0x9D" },
14951   { 0x9E, "unknown-0x9E" },
14952   { 0x9F, "unknown-0x9F" },
14953   { 0xA0, "NT Trans" },
14954   { 0xA1, "NT Trans Secondary" },
14955   { 0xA2, "NT Create AndX" },
14956   { 0xA3, "unknown-0xA3" },
14957   { 0xA4, "NT Cancel" },
14958   { 0xA5, "NT Rename" },
14959   { 0xA6, "unknown-0xA6" },
14960   { 0xA7, "unknown-0xA7" },
14961   { 0xA8, "unknown-0xA8" },
14962   { 0xA9, "unknown-0xA9" },
14963   { 0xAA, "unknown-0xAA" },
14964   { 0xAB, "unknown-0xAB" },
14965   { 0xAC, "unknown-0xAC" },
14966   { 0xAD, "unknown-0xAD" },
14967   { 0xAE, "unknown-0xAE" },
14968   { 0xAF, "unknown-0xAF" },
14969   { 0xB0, "unknown-0xB0" },
14970   { 0xB1, "unknown-0xB1" },
14971   { 0xB2, "unknown-0xB2" },
14972   { 0xB3, "unknown-0xB3" },
14973   { 0xB4, "unknown-0xB4" },
14974   { 0xB5, "unknown-0xB5" },
14975   { 0xB6, "unknown-0xB6" },
14976   { 0xB7, "unknown-0xB7" },
14977   { 0xB8, "unknown-0xB8" },
14978   { 0xB9, "unknown-0xB9" },
14979   { 0xBA, "unknown-0xBA" },
14980   { 0xBB, "unknown-0xBB" },
14981   { 0xBC, "unknown-0xBC" },
14982   { 0xBD, "unknown-0xBD" },
14983   { 0xBE, "unknown-0xBE" },
14984   { 0xBF, "unknown-0xBF" },
14985   { 0xC0, "Open Print File" },
14986   { 0xC1, "Write Print File" },
14987   { 0xC2, "Close Print File" },
14988   { 0xC3, "Get Print Queue" },
14989   { 0xC4, "unknown-0xC4" },
14990   { 0xC5, "unknown-0xC5" },
14991   { 0xC6, "unknown-0xC6" },
14992   { 0xC7, "unknown-0xC7" },
14993   { 0xC8, "unknown-0xC8" },
14994   { 0xC9, "unknown-0xC9" },
14995   { 0xCA, "unknown-0xCA" },
14996   { 0xCB, "unknown-0xCB" },
14997   { 0xCC, "unknown-0xCC" },
14998   { 0xCD, "unknown-0xCD" },
14999   { 0xCE, "unknown-0xCE" },
15000   { 0xCF, "unknown-0xCF" },
15001   { 0xD0, "Send Single Block Message" },
15002   { 0xD1, "Send Broadcast Message" },
15003   { 0xD2, "Forward User Name" },
15004   { 0xD3, "Cancel Forward" },
15005   { 0xD4, "Get Machine Name" },
15006   { 0xD5, "Send Start of Multi-block Message" },
15007   { 0xD6, "Send End of Multi-block Message" },
15008   { 0xD7, "Send Text of Multi-block Message" },
15009   { 0xD8, "SMBreadbulk" },
15010   { 0xD9, "SMBwritebulk" },
15011   { 0xDA, "SMBwritebulkdata" },
15012   { 0xDB, "unknown-0xDB" },
15013   { 0xDC, "unknown-0xDC" },
15014   { 0xDD, "unknown-0xDD" },
15015   { 0xDE, "unknown-0xDE" },
15016   { 0xDF, "unknown-0xDF" },
15017   { 0xE0, "unknown-0xE0" },
15018   { 0xE1, "unknown-0xE1" },
15019   { 0xE2, "unknown-0xE2" },
15020   { 0xE3, "unknown-0xE3" },
15021   { 0xE4, "unknown-0xE4" },
15022   { 0xE5, "unknown-0xE5" },
15023   { 0xE6, "unknown-0xE6" },
15024   { 0xE7, "unknown-0xE7" },
15025   { 0xE8, "unknown-0xE8" },
15026   { 0xE9, "unknown-0xE9" },
15027   { 0xEA, "unknown-0xEA" },
15028   { 0xEB, "unknown-0xEB" },
15029   { 0xEC, "unknown-0xEC" },
15030   { 0xED, "unknown-0xED" },
15031   { 0xEE, "unknown-0xEE" },
15032   { 0xEF, "unknown-0xEF" },
15033   { 0xF0, "unknown-0xF0" },
15034   { 0xF1, "unknown-0xF1" },
15035   { 0xF2, "unknown-0xF2" },
15036   { 0xF3, "unknown-0xF3" },
15037   { 0xF4, "unknown-0xF4" },
15038   { 0xF5, "unknown-0xF5" },
15039   { 0xF6, "unknown-0xF6" },
15040   { 0xF7, "unknown-0xF7" },
15041   { 0xF8, "unknown-0xF8" },
15042   { 0xF9, "unknown-0xF9" },
15043   { 0xFA, "unknown-0xFA" },
15044   { 0xFB, "unknown-0xFB" },
15045   { 0xFC, "unknown-0xFC" },
15046   { 0xFD, "unknown-0xFD" },
15047   { 0xFE, "SMBinvalid" },
15048   { 0xFF, "unknown-0xFF" },
15049   { 0x00, NULL },
15050 };
15051
15052 static char *decode_smb_name(guint8 cmd)
15053 {
15054   return(smb_cmd_vals[cmd].strptr);
15055 }
15056
15057
15058
15059 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15060  * Everything TVBUFFIFIED above this line
15061  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
15062
15063
15064 static void
15065 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
15066 {
15067         conv_tables_t *ct = ctarg;
15068
15069         if (ct->unmatched)
15070                 g_hash_table_destroy(ct->unmatched);
15071         if (ct->matched)
15072                 g_hash_table_destroy(ct->matched);
15073         if (ct->tid_service)
15074                 g_hash_table_destroy(ct->tid_service);
15075 }
15076
15077 static void
15078 smb_init_protocol(void)
15079 {
15080         if (smb_saved_info_key_chunk)
15081                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
15082         if (smb_saved_info_chunk)
15083                 g_mem_chunk_destroy(smb_saved_info_chunk);
15084         if (smb_nt_transact_info_chunk)
15085                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
15086         if (smb_transact2_info_chunk)
15087                 g_mem_chunk_destroy(smb_transact2_info_chunk);
15088         if (smb_transact_info_chunk)
15089                 g_mem_chunk_destroy(smb_transact_info_chunk);
15090
15091         /*
15092          * Free the hash tables attached to the conversation table
15093          * structures, and then free the list of conversation table
15094          * data structures (which doesn't free the data structures
15095          * themselves; that's done by destroying the chunk from
15096          * which they were allocated).
15097          */
15098         if (conv_tables) {
15099                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
15100                 g_slist_free(conv_tables);
15101                 conv_tables = NULL;
15102         }
15103
15104         /*
15105          * Now destroy the chunk from which the conversation table
15106          * structures were allocated.
15107          */
15108         if (conv_tables_chunk)
15109                 g_mem_chunk_destroy(conv_tables_chunk);
15110
15111         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
15112             sizeof(smb_saved_info_t),
15113             smb_saved_info_init_count * sizeof(smb_saved_info_t),
15114             G_ALLOC_ONLY);
15115         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
15116             sizeof(smb_saved_info_key_t),
15117             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
15118             G_ALLOC_ONLY);
15119         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
15120             sizeof(smb_nt_transact_info_t),
15121             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
15122             G_ALLOC_ONLY);
15123         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
15124             sizeof(smb_transact2_info_t),
15125             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
15126             G_ALLOC_ONLY);
15127         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
15128             sizeof(smb_transact_info_t),
15129             smb_transact_info_init_count * sizeof(smb_transact_info_t),
15130             G_ALLOC_ONLY);
15131         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
15132             sizeof(conv_tables_t),
15133             conv_tables_count * sizeof(conv_tables_t),
15134             G_ALLOC_ONLY);
15135 }
15136
15137 static const value_string errcls_types[] = {
15138   { SMB_SUCCESS, "Success"},
15139   { SMB_ERRDOS, "DOS Error"},
15140   { SMB_ERRSRV, "Server Error"},
15141   { SMB_ERRHRD, "Hardware Error"},
15142   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
15143   { 0, NULL }
15144 };
15145
15146 const value_string DOS_errors[] = {
15147   {0, "Success"},
15148   {SMBE_insufficientbuffer, "Insufficient buffer"},
15149   {SMBE_badfunc, "Invalid function (or system call)"},
15150   {SMBE_badfile, "File not found (pathname error)"},
15151   {SMBE_badpath, "Directory not found"},
15152   {SMBE_nofids, "Too many open files"},
15153   {SMBE_noaccess, "Access denied"},
15154   {SMBE_badfid, "Invalid fid"},
15155   {SMBE_nomem,  "Out of memory"},
15156   {SMBE_badmem, "Invalid memory block address"},
15157   {SMBE_badenv, "Invalid environment"},
15158   {SMBE_badaccess, "Invalid open mode"},
15159   {SMBE_baddata, "Invalid data (only from ioctl call)"},
15160   {SMBE_res, "Reserved error code?"},
15161   {SMBE_baddrive, "Invalid drive"},
15162   {SMBE_remcd, "Attempt to delete current directory"},
15163   {SMBE_diffdevice, "Rename/move across different filesystems"},
15164   {SMBE_nofiles, "No more files found in file search"},
15165   {SMBE_badshare, "Share mode on file conflict with open mode"},
15166   {SMBE_lock, "Lock request conflicts with existing lock"},
15167   {SMBE_unsup, "Request unsupported, returned by Win 95"},
15168   {SMBE_nosuchshare, "Requested share does not exist"},
15169   {SMBE_filexists, "File in operation already exists"},
15170   {SMBE_cannotopen, "Cannot open the file specified"},
15171   {SMBE_unknownlevel, "Unknown info level"},
15172   {SMBE_invalidname, "Invalid name"},
15173   {SMBE_badpipe, "Named pipe invalid"},
15174   {SMBE_pipebusy, "All instances of pipe are busy"},
15175   {SMBE_pipeclosing, "Named pipe close in progress"},
15176   {SMBE_notconnected, "No process on other end of named pipe"},
15177   {SMBE_moredata, "More data to be returned"},
15178   {SMBE_baddirectory,  "Invalid directory name in a path."},
15179   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
15180   {SMBE_eas_nsup, "Extended attributes not supported"},
15181   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
15182   {SMBE_unknownipc, "Unknown IPC Operation"},
15183   {SMBE_noipc, "Don't support ipc"},
15184   {SMBE_alreadyexists, "File already exists"},
15185   {SMBE_unknownprinterdriver, "Unknown printer driver"},
15186   {SMBE_invalidprintername, "Invalid printer name"},
15187   {SMBE_printeralreadyexists, "Printer already exists"},
15188   {SMBE_invaliddatatype, "Invalid data type"},
15189   {SMBE_invalidenvironment, "Invalid environment"},
15190   {SMBE_printerdriverinuse, "Printer driver in use"},
15191   {SMBE_invalidparam, "Invalid parameter"},
15192   {SMBE_invalidformsize, "Invalid form size"},
15193   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
15194   {SMBE_invalidowner, "Invalid owner"},
15195   {SMBE_nomoreitems, "No more items"},
15196   {SMBE_serverunavailable, "Server unavailable"},
15197   {0, NULL}
15198   };
15199
15200 /* Error codes for the ERRSRV class */
15201
15202 static const value_string SRV_errors[] = {
15203   {SMBE_error, "Non specific error code"},
15204   {SMBE_badpw, "Bad password"},
15205   {SMBE_badtype, "Reserved"},
15206   {SMBE_access, "No permissions to perform the requested operation"},
15207   {SMBE_invnid, "TID invalid"},
15208   {SMBE_invnetname, "Invalid network name. Service not found"},
15209   {SMBE_invdevice, "Invalid device"},
15210   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15211   {SMBE_qfull, "Print queue full"},
15212   {SMBE_qtoobig, "Queued item too big"},
15213   {SMBE_qeof, "EOF on print queue dump"},
15214   {SMBE_invpfid, "Invalid print file in smb_fid"},
15215   {SMBE_smbcmd, "Unrecognised command"},
15216   {SMBE_srverror, "SMB server internal error"},
15217   {SMBE_filespecs, "Fid and pathname invalid combination"},
15218   {SMBE_badlink, "Bad link in request ???"},
15219   {SMBE_badpermits, "Access specified for a file is not valid"},
15220   {SMBE_badpid, "Bad process id in request"},
15221   {SMBE_setattrmode, "Attribute mode invalid"},
15222   {SMBE_paused, "Message server paused"},
15223   {SMBE_msgoff, "Not receiving messages"},
15224   {SMBE_noroom, "No room for message"},
15225   {SMBE_rmuns, "Too many remote usernames"},
15226   {SMBE_timeout, "Operation timed out"},
15227   {SMBE_noresource, "No resources currently available for request."},
15228   {SMBE_toomanyuids, "Too many userids"},
15229   {SMBE_baduid, "Bad userid"},
15230   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15231   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15232   {SMBE_contMPX, "Resume MPX mode"},
15233   {SMBE_badPW, "Bad Password???"},
15234   {SMBE_nosupport, "Operation not supported"},
15235   { 0, NULL}
15236 };
15237
15238 /* Error codes for the ERRHRD class */
15239
15240 static const value_string HRD_errors[] = {
15241   {SMBE_nowrite, "Read only media"},
15242   {SMBE_badunit, "Unknown device"},
15243   {SMBE_notready, "Drive not ready"},
15244   {SMBE_badcmd, "Unknown command"},
15245   {SMBE_data, "Data (CRC) error"},
15246   {SMBE_badreq, "Bad request structure length"},
15247   {SMBE_seek, "Seek error"},
15248   {SMBE_badmedia, "Unknown media type"},
15249   {SMBE_badsector, "Sector not found"},
15250   {SMBE_nopaper, "Printer out of paper"},
15251   {SMBE_write, "Write fault"},
15252   {SMBE_read, "Read fault"},
15253   {SMBE_general, "General failure"},
15254   {SMBE_badshare, "A open conflicts with an existing open"},
15255   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15256   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15257   {SMBE_FCBunavail, "No FCBs are available to process request"},
15258   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15259   {SMBE_diskfull, "Disk full???"},
15260   {0, NULL}
15261 };
15262
15263 static char *decode_smb_error(guint8 errcls, guint16 errcode)
15264 {
15265
15266   switch (errcls) {
15267
15268   case SMB_SUCCESS:
15269
15270     return("No Error");   /* No error ??? */
15271     break;
15272
15273   case SMB_ERRDOS:
15274
15275     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15276     break;
15277
15278   case SMB_ERRSRV:
15279
15280     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15281     break;
15282
15283   case SMB_ERRHRD:
15284
15285     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15286     break;
15287
15288   default:
15289
15290     return("Unknown error class!");
15291
15292   }
15293
15294 }
15295
15296
15297 /* These are the MS country codes from
15298
15299         http://www.unicode.org/unicode/onlinedat/countries.html
15300
15301    For countries that share the same number, I choose to use only the
15302    name of the largest country. Apologies for this. If this offends you,
15303    here is the table to change that.
15304
15305    This also includes the code of 0 for "Default", which isn't in
15306    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
15307    header file.  Presumably it means "don't override the setting
15308    on the user's machine".
15309
15310    Future versions of Microsoft's "winnls.h" header file might include
15311    additional codes; the current version matches the Unicode Consortium's
15312    table.
15313 */
15314 const value_string ms_country_codes[] = {
15315         {  0,   "Default"},
15316         {  1,   "USA"},
15317         {  2,   "Canada"},
15318         {  7,   "Russia"},
15319         { 20,   "Egypt"},
15320         { 27,   "South Africa"},
15321         { 30,   "Greece"},
15322         { 31,   "Netherlands"},
15323         { 32,   "Belgium"},
15324         { 33,   "France"},
15325         { 34,   "Spain"},
15326         { 36,   "Hungary"},
15327         { 39,   "Italy"},
15328         { 40,   "Romania"},
15329         { 41,   "Switzerland"},
15330         { 43,   "Austria"},
15331         { 44,   "United Kingdom"},
15332         { 45,   "Denmark"},
15333         { 46,   "Sweden"},
15334         { 47,   "Norway"},
15335         { 48,   "Poland"},
15336         { 49,   "Germany"},
15337         { 51,   "Peru"},
15338         { 52,   "Mexico"},
15339         { 54,   "Argentina"},
15340         { 55,   "Brazil"},
15341         { 56,   "Chile"},
15342         { 57,   "Colombia"},
15343         { 58,   "Venezuela"},
15344         { 60,   "Malaysia"},
15345         { 61,   "Australia"},
15346         { 62,   "Indonesia"},
15347         { 63,   "Philippines"},
15348         { 64,   "New Zealand"},
15349         { 65,   "Singapore"},
15350         { 66,   "Thailand"},
15351         { 81,   "Japan"},
15352         { 82,   "South Korea"},
15353         { 84,   "Viet Nam"},
15354         { 86,   "China"},
15355         { 90,   "Turkey"},
15356         { 91,   "India"},
15357         { 92,   "Pakistan"},
15358         {212,   "Morocco"},
15359         {213,   "Algeria"},
15360         {216,   "Tunisia"},
15361         {218,   "Libya"},
15362         {254,   "Kenya"},
15363         {263,   "Zimbabwe"},
15364         {298,   "Faroe Islands"},
15365         {351,   "Portugal"},
15366         {352,   "Luxembourg"},
15367         {353,   "Ireland"},
15368         {354,   "Iceland"},
15369         {355,   "Albania"},
15370         {358,   "Finland"},
15371         {359,   "Bulgaria"},
15372         {370,   "Lithuania"},
15373         {371,   "Latvia"},
15374         {372,   "Estonia"},
15375         {374,   "Armenia"},
15376         {375,   "Belarus"},
15377         {380,   "Ukraine"},
15378         {381,   "Serbia"},
15379         {385,   "Croatia"},
15380         {386,   "Slovenia"},
15381         {389,   "Macedonia"},
15382         {420,   "Czech Republic"},
15383         {421,   "Slovak Republic"},
15384         {501,   "Belize"},
15385         {502,   "Guatemala"},
15386         {503,   "El Salvador"},
15387         {504,   "Honduras"},
15388         {505,   "Nicaragua"},
15389         {506,   "Costa Rica"},
15390         {507,   "Panama"},
15391         {591,   "Bolivia"},
15392         {593,   "Ecuador"},
15393         {595,   "Paraguay"},
15394         {598,   "Uruguay"},
15395         {673,   "Brunei Darussalam"},
15396         {852,   "Hong Kong"},
15397         {853,   "Macau"},
15398         {886,   "Taiwan"},
15399         {960,   "Maldives"},
15400         {961,   "Lebanon"},
15401         {962,   "Jordan"},
15402         {963,   "Syria"},
15403         {964,   "Iraq"},
15404         {965,   "Kuwait"},
15405         {966,   "Saudi Arabia"},
15406         {967,   "Yemen"},
15407         {968,   "Oman"},
15408         {971,   "United Arab Emirates"},
15409         {972,   "Israel"},
15410         {973,   "Bahrain"},
15411         {974,   "Qatar"},
15412         {976,   "Mongolia"},
15413         {981,   "Iran"},
15414         {994,   "Azerbaijan"},
15415         {995,   "Georgia"},
15416         {996,   "Kyrgyzstan"},
15417
15418         {0,     NULL}
15419 };
15420
15421 /*
15422  * NT error codes.
15423  *
15424  * From
15425  *
15426  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
15427  */
15428 const value_string NT_errors[] = {
15429   { 0x00000000, "STATUS_SUCCESS" },
15430   { 0x00000000, "STATUS_WAIT_0" },
15431   { 0x00000001, "STATUS_WAIT_1" },
15432   { 0x00000002, "STATUS_WAIT_2" },
15433   { 0x00000003, "STATUS_WAIT_3" },
15434   { 0x0000003F, "STATUS_WAIT_63" },
15435   { 0x00000080, "STATUS_ABANDONED" },
15436   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
15437   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
15438   { 0x000000C0, "STATUS_USER_APC" },
15439   { 0x00000100, "STATUS_KERNEL_APC" },
15440   { 0x00000101, "STATUS_ALERTED" },
15441   { 0x00000102, "STATUS_TIMEOUT" },
15442   { 0x00000103, "STATUS_PENDING" },
15443   { 0x00000104, "STATUS_REPARSE" },
15444   { 0x00000105, "STATUS_MORE_ENTRIES" },
15445   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
15446   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
15447   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
15448   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
15449   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
15450   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
15451   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
15452   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
15453   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
15454   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
15455   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
15456   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
15457   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
15458   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
15459   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
15460   { 0x00000116, "STATUS_CRASH_DUMP" },
15461   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
15462   { 0x00000118, "STATUS_REPARSE_OBJECT" },
15463   { 0x0000045C, "STATUS_NO_SHUTDOWN_IN_PROGRESS" },
15464   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
15465   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
15466   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
15467   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
15468   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
15469   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
15470   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
15471   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
15472   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
15473   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
15474   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
15475   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
15476   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
15477   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
15478   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
15479   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
15480   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
15481   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
15482   { 0x40000012, "STATUS_EVENT_DONE" },
15483   { 0x40000013, "STATUS_EVENT_PENDING" },
15484   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
15485   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
15486   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
15487   { 0x40000017, "STATUS_WAS_UNLOCKED" },
15488   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
15489   { 0x40000019, "STATUS_WAS_LOCKED" },
15490   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
15491   { 0x4000001B, "STATUS_ALREADY_WIN32" },
15492   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
15493   { 0x4000001D, "STATUS_WX86_CONTINUE" },
15494   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
15495   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
15496   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
15497   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
15498   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
15499   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
15500   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
15501   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
15502   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
15503   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
15504   { 0x80000003, "STATUS_BREAKPOINT" },
15505   { 0x80000004, "STATUS_SINGLE_STEP" },
15506   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
15507   { 0x80000006, "STATUS_NO_MORE_FILES" },
15508   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
15509   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
15510   { 0x8000000B, "STATUS_NO_INHERITANCE" },
15511   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
15512   { 0x8000000D, "STATUS_PARTIAL_COPY" },
15513   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
15514   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
15515   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
15516   { 0x80000011, "STATUS_DEVICE_BUSY" },
15517   { 0x80000012, "STATUS_NO_MORE_EAS" },
15518   { 0x80000013, "STATUS_INVALID_EA_NAME" },
15519   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
15520   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
15521   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
15522   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
15523   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
15524   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
15525   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
15526   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
15527   { 0x8000001D, "STATUS_BUS_RESET" },
15528   { 0x8000001E, "STATUS_END_OF_MEDIA" },
15529   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
15530   { 0x80000020, "STATUS_MEDIA_CHECK" },
15531   { 0x80000021, "STATUS_SETMARK_DETECTED" },
15532   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
15533   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
15534   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
15535   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
15536   { 0x80000026, "STATUS_LONGJUMP" },
15537   { 0x80040111, "MAPI_E_LOGON_FAILED" },
15538   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
15539   { 0x80090301, "SEC_E_INVALID_HANDLE" },
15540   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
15541   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
15542   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
15543   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
15544   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
15545   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
15546   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
15547   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
15548   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
15549   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
15550   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
15551   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
15552   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
15553   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
15554   { 0xC0000008, "STATUS_INVALID_HANDLE" },
15555   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
15556   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
15557   { 0xC000000B, "STATUS_INVALID_CID" },
15558   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
15559   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
15560   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
15561   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
15562   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
15563   { 0xC0000011, "STATUS_END_OF_FILE" },
15564   { 0xC0000012, "STATUS_WRONG_VOLUME" },
15565   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
15566   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
15567   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
15568   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
15569   { 0xC0000017, "STATUS_NO_MEMORY" },
15570   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
15571   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
15572   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
15573   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
15574   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
15575   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
15576   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
15577   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
15578   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
15579   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
15580   { 0xC0000022, "STATUS_ACCESS_DENIED" },
15581   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
15582   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
15583   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
15584   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
15585   { 0xC0000027, "STATUS_UNWIND" },
15586   { 0xC0000028, "STATUS_BAD_STACK" },
15587   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
15588   { 0xC000002A, "STATUS_NOT_LOCKED" },
15589   { 0xC000002B, "STATUS_PARITY_ERROR" },
15590   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
15591   { 0xC000002D, "STATUS_NOT_COMMITTED" },
15592   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
15593   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
15594   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
15595   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
15596   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
15597   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
15598   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
15599   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
15600   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
15601   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
15602   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
15603   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
15604   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
15605   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15606   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15607   { 0xC000003E, "STATUS_DATA_ERROR" },
15608   { 0xC000003F, "STATUS_CRC_ERROR" },
15609   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15610   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15611   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15612   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15613   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15614   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15615   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15616   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15617   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15618   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15619   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15620   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15621   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15622   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15623   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15624   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15625   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15626   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15627   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15628   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15629   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15630   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15631   { 0xC0000056, "STATUS_DELETE_PENDING" },
15632   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15633   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15634   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15635   { 0xC000005A, "STATUS_INVALID_OWNER" },
15636   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15637   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15638   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15639   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15640   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15641   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15642   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15643   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15644   { 0xC0000063, "STATUS_USER_EXISTS" },
15645   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15646   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15647   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15648   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15649   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15650   { 0xC0000069, "STATUS_LAST_ADMIN" },
15651   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15652   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15653   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15654   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15655   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15656   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15657   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15658   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15659   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15660   { 0xC0000073, "STATUS_NONE_MAPPED" },
15661   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15662   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15663   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15664   { 0xC0000077, "STATUS_INVALID_ACL" },
15665   { 0xC0000078, "STATUS_INVALID_SID" },
15666   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15667   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15668   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15669   { 0xC000007C, "STATUS_NO_TOKEN" },
15670   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15671   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15672   { 0xC000007F, "STATUS_DISK_FULL" },
15673   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15674   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15675   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15676   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15677   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15678   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15679   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15680   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15681   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15682   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15683   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15684   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15685   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15686   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15687   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15688   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15689   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15690   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15691   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15692   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15693   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15694   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15695   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15696   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15697   { 0xC0000098, "STATUS_FILE_INVALID" },
15698   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15699   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15700   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15701   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15702   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15703   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15704   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15705   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15706   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15707   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15708   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15709   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15710   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15711   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15712   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15713   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15714   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15715   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15716   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15717   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15718   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15719   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15720   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15721   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15722   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15723   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15724   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15725   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15726   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15727   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15728   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15729   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15730   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15731   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15732   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15733   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15734   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15735   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15736   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15737   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15738   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15739   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15740   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15741   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15742   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15743   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15744   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15745   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15746   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15747   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15748   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15749   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15750   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15751   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15752   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15753   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15754   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15755   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15756   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15757   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15758   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15759   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15760   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15761   { 0xC00000D8, "STATUS_CANT_WAIT" },
15762   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15763   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15764   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15765   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15766   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15767   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15768   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15769   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15770   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15771   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15772   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15773   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15774   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15775   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15776   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15777   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15778   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15779   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15780   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15781   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15782   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15783   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15784   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15785   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15786   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15787   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15788   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15789   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15790   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15791   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15792   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15793   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15794   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15795   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15796   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15797   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15798   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15799   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15800   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15801   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15802   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15803   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15804   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15805   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15806   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15807   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15808   { 0xC0000107, "STATUS_FILES_OPEN" },
15809   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15810   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15811   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15812   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15813   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15814   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15815   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15816   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15817   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15818   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15819   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15820   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15821   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15822   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15823   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15824   { 0xC0000117, "STATUS_NO_LDT" },
15825   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15826   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15827   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15828   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15829   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15830   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15831   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15832   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15833   { 0xC0000120, "STATUS_CANCELLED" },
15834   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15835   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15836   { 0xC0000123, "STATUS_FILE_DELETED" },
15837   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15838   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15839   { 0xC0000126, "STATUS_SPECIAL_USER" },
15840   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15841   { 0xC0000128, "STATUS_FILE_CLOSED" },
15842   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15843   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15844   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15845   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15846   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15847   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15848   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15849   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15850   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15851   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15852   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15853   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15854   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15855   { 0xC0000136, "STATUS_OPEN_FAILED" },
15856   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15857   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15858   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15859   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15860   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15861   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15862   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15863   { 0xC000013E, "STATUS_LINK_FAILED" },
15864   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15865   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15866   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15867   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15868   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15869   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15870   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15871   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15872   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15873   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15874   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15875   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15876   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15877   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15878   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15879   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15880   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15881   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15882   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15883   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15884   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15885   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15886   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15887   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15888   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15889   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15890   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15891   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15892   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15893   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15894   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15895   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15896   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15897   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15898   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15899   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15900   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15901   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15902   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15903   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15904   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15905   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15906   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15907   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15908   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15909   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15910   { 0xC000016D, "STATUS_FT_ORPHANING" },
15911   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15912   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15913   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15914   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15915   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15916   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15917   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15918   { 0xC0000178, "STATUS_NO_MEDIA" },
15919   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15920   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15921   { 0xC000017C, "STATUS_KEY_DELETED" },
15922   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15923   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15924   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15925   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15926   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15927   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15928   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15929   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15930   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15931   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15932   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15933   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15934   { 0xC0000189, "STATUS_TOO_LATE" },
15935   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15936   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15937   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15938   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15939   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15940   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15941   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15942   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15943   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15944   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15945   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15946   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15947   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15948   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15949   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15950   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15951   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15952   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15953   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15954   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15955   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15956   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15957   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15958   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15959   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15960   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15961   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15962   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15963   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15964   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15965   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15966   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15967   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15968   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15969   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15970   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15971   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15972   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15973   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15974   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15975   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15976   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15977   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15978   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15979   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15980   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15981   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15982   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15983   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15984   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15985   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15986   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15987   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15988   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15989   { 0xC0000225, "STATUS_NOT_FOUND" },
15990   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15991   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15992   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15993   { 0xC0000229, "STATUS_FAIL_CHECK" },
15994   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15995   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15996   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15997   { 0xC000022D, "STATUS_RETRY" },
15998   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15999   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
16000   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
16001   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
16002   { 0xC0000232, "STATUS_INVALID_VARIANT" },
16003   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
16004   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
16005   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
16006   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
16007   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
16008   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
16009   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
16010   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
16011   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
16012   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
16013   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
16014   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
16015   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
16016   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
16017   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
16018   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
16019   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
16020   { 0xC0000244, "STATUS_AUDIT_FAILED" },
16021   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
16022   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
16023   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
16024   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
16025   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
16026   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
16027   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
16028   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
16029   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
16030   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
16031   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
16032   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
16033   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
16034   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
16035   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
16036   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
16037   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
16038   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
16039   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
16040   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
16041   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
16042   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
16043   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
16044   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
16045   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
16046   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
16047   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
16048   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
16049   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
16050   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
16051   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
16052   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
16053   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
16054   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
16055   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
16056   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
16057   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
16058   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
16059   { 0xC0000272, "STATUS_NO_MATCH" },
16060   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
16061   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
16062   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
16063   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
16064   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
16065   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
16066   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
16067   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
16068   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
16069   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
16070   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
16071   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
16072   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
16073   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
16074   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
16075   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
16076   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
16077   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
16078   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
16079   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
16080   { 0xC000028E, "STATUS_NO_EFS" },
16081   { 0xC000028F, "STATUS_WRONG_EFS" },
16082   { 0xC0000290, "STATUS_NO_USER_KEYS" },
16083   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
16084   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
16085   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
16086   { 0x40000294, "STATUS_WAKE_SYSTEM" },
16087   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
16088   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
16089   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
16090   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
16091   { 0xC0000299, "STATUS_SHARED_POLICY" },
16092   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
16093   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
16094   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
16095   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
16096   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
16097   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
16098   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
16099   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
16100   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
16101   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
16102   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
16103   { 0xC00002A5, "STATUS_DS_BUSY" },
16104   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
16105   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
16106   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
16107   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
16108   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
16109   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
16110   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
16111   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
16112   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
16113   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
16114   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
16115   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
16116   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
16117   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
16118   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
16119   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
16120   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
16121   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
16122   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
16123   { 0xC00002B9, "STATUS_NOINTERFACE" },
16124   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
16125   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
16126   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
16127   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
16128   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
16129   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
16130   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
16131   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
16132   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
16133   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
16134   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
16135   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
16136   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
16137   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
16138   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
16139   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
16140   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
16141   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
16142   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
16143   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
16144   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
16145   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
16146   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
16147   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
16148   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
16149   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
16150   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
16151   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
16152   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
16153   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
16154   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
16155   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
16156   { 0xC00002E1, "STATUS_DS_CANT_START" },
16157   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
16158   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
16159   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
16160   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
16161   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
16162   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
16163   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
16164   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
16165   { 0xC0009898, "STATUS_WOW_ASSERTION" },
16166   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
16167   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
16168   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
16169   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
16170   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
16171   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
16172   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
16173   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
16174   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
16175   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
16176   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
16177   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
16178   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
16179   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
16180   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
16181   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
16182   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
16183   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
16184   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
16185   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
16186   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
16187   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
16188   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
16189   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
16190   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
16191   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
16192   { 0xC002001B, "RPC_NT_CALL_FAILED" },
16193   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
16194   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
16195   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
16196   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
16197   { 0xC0020022, "RPC_NT_INVALID_TAG" },
16198   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
16199   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
16200   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
16201   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
16202   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
16203   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
16204   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
16205   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
16206   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
16207   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
16208   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
16209   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
16210   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
16211   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
16212   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
16213   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
16214   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
16215   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
16216   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
16217   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
16218   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
16219   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
16220   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
16221   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
16222   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
16223   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
16224   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
16225   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
16226   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
16227   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
16228   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
16229   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
16230   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
16231   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
16232   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
16233   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
16234   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
16235   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
16236   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
16237   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
16238   { 0xC002100A, "RPC_P_SEND_FAILED" },
16239   { 0xC002100B, "RPC_P_TIMEOUT" },
16240   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
16241   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
16242   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
16243   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
16244   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
16245   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
16246   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
16247   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
16248   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
16249   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
16250   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
16251   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
16252   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
16253   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
16254   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
16255   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
16256   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
16257   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
16258   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
16259   { 0xC002004C, "EPT_NT_CANT_CREATE" },
16260   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
16261   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
16262   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
16263   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
16264   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
16265   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
16266   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
16267   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
16268   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
16269   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
16270   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
16271   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
16272   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
16273   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
16274   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
16275   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
16276   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
16277   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
16278   { 0,          NULL }
16279 };
16280
16281
16282
16283 static const true_false_string tfs_smb_flags_lock = {
16284         "Lock&Read, Write&Unlock are supported",
16285         "Lock&Read, Write&Unlock are not supported"
16286 };
16287 static const true_false_string tfs_smb_flags_receive_buffer = {
16288         "Receive buffer has been posted",
16289         "Receive buffer has not been posted"
16290 };
16291 static const true_false_string tfs_smb_flags_caseless = {
16292         "Path names are caseless",
16293         "Path names are case sensitive"
16294 };
16295 static const true_false_string tfs_smb_flags_canon = {
16296         "Pathnames are canonicalized",
16297         "Pathnames are not canonicalized"
16298 };
16299 static const true_false_string tfs_smb_flags_oplock = {
16300         "OpLock requested/granted",
16301         "OpLock not requested/granted"
16302 };
16303 static const true_false_string tfs_smb_flags_notify = {
16304         "Notify client on all modifications",
16305         "Notify client only on open"
16306 };
16307 static const true_false_string tfs_smb_flags_response = {
16308         "Message is a response to the client/redirector",
16309         "Message is a request to the server"
16310 };
16311
16312 static int
16313 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16314 {
16315         guint8 mask;
16316         proto_item *item = NULL;
16317         proto_tree *tree = NULL;
16318
16319         mask = tvb_get_guint8(tvb, offset);
16320
16321         if(parent_tree){
16322                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16323                         "Flags: 0x%02x", mask);
16324                 tree = proto_item_add_subtree(item, ett_smb_flags);
16325         }
16326         proto_tree_add_boolean(tree, hf_smb_flags_response,
16327                 tvb, offset, 1, mask);
16328         proto_tree_add_boolean(tree, hf_smb_flags_notify,
16329                 tvb, offset, 1, mask);
16330         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16331                 tvb, offset, 1, mask);
16332         proto_tree_add_boolean(tree, hf_smb_flags_canon,
16333                 tvb, offset, 1, mask);
16334         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16335                 tvb, offset, 1, mask);
16336         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16337                 tvb, offset, 1, mask);
16338         proto_tree_add_boolean(tree, hf_smb_flags_lock,
16339                 tvb, offset, 1, mask);
16340         offset += 1;
16341         return offset;
16342 }
16343
16344
16345
16346 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16347         "Long file names are allowed in the response",
16348         "Long file names are not allowed in the response"
16349 };
16350 static const true_false_string tfs_smb_flags2_ea = {
16351         "Extended attributes are supported",
16352         "Extended attributes are not supported"
16353 };
16354 static const true_false_string tfs_smb_flags2_sec_sig = {
16355         "Security signatures are supported",
16356         "Security signatures are not supported"
16357 };
16358 static const true_false_string tfs_smb_flags2_long_names_used = {
16359         "Path names in request are long file names",
16360         "Path names in request are not long file names"
16361 };
16362 static const true_false_string tfs_smb_flags2_esn = {
16363         "Extended security negotiation is supported",
16364         "Extended security negotiation is not supported"
16365 };
16366 static const true_false_string tfs_smb_flags2_dfs = {
16367         "Resolve pathnames with Dfs",
16368         "Don't resolve pathnames with Dfs"
16369 };
16370 static const true_false_string tfs_smb_flags2_roe = {
16371         "Permit reads if execute-only",
16372         "Don't permit reads if execute-only"
16373 };
16374 static const true_false_string tfs_smb_flags2_nt_error = {
16375         "Error codes are NT error codes",
16376         "Error codes are DOS error codes"
16377 };
16378 static const true_false_string tfs_smb_flags2_string = {
16379         "Strings are Unicode",
16380         "Strings are ASCII"
16381 };
16382 static int
16383 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16384 {
16385         guint16 mask;
16386         proto_item *item = NULL;
16387         proto_tree *tree = NULL;
16388
16389         mask = tvb_get_letohs(tvb, offset);
16390
16391         if(parent_tree){
16392                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16393                         "Flags2: 0x%04x", mask);
16394                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16395         }
16396
16397         proto_tree_add_boolean(tree, hf_smb_flags2_string,
16398                 tvb, offset, 2, mask);
16399         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16400                 tvb, offset, 2, mask);
16401         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16402                 tvb, offset, 2, mask);
16403         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16404                 tvb, offset, 2, mask);
16405         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16406                 tvb, offset, 2, mask);
16407         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16408                 tvb, offset, 2, mask);
16409         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16410                 tvb, offset, 2, mask);
16411         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16412                 tvb, offset, 2, mask);
16413         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16414                 tvb, offset, 2, mask);
16415
16416         offset += 2;
16417         return offset;
16418 }
16419
16420
16421
16422 #define SMB_FLAGS_DIRN 0x80
16423
16424
16425 static void
16426 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16427 {
16428         int offset = 0;
16429         proto_item *item = NULL, *hitem = NULL;
16430         proto_tree *tree = NULL, *htree = NULL;
16431         guint8          flags;
16432         guint16         flags2;
16433         static smb_info_t       si_arr[20];
16434         static int si_counter=0;
16435         smb_info_t              *si;
16436         smb_saved_info_t *sip = NULL;
16437         smb_saved_info_key_t key;
16438         smb_saved_info_key_t *new_key;
16439         guint32 nt_status = 0;
16440         guint8 errclass = 0;
16441         guint16 errcode = 0;
16442         guint32 pid_mid;
16443         conversation_t *conversation;
16444         nstime_t ns;
16445
16446         si_counter++;
16447         if(si_counter==20){
16448                 si_counter=0;
16449         }
16450         si=&si_arr[si_counter];
16451
16452         top_tree=parent_tree;
16453
16454         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16455                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16456         }
16457         if (check_col(pinfo->cinfo, COL_INFO)){
16458                 col_clear(pinfo->cinfo, COL_INFO);
16459         }
16460
16461         /* start off using the local variable, we will allocate a new one if we
16462            need to*/
16463         si->cmd = tvb_get_guint8(tvb, offset+4);
16464         flags = tvb_get_guint8(tvb, offset+9);
16465         /*
16466          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16467          * the direction flag appears never to be set, even for what appear
16468          * to be replies.  Do some SMB servers fail to set that flag,
16469          * under the assumption that the client knows it's a reply because
16470          * it received it?
16471          */
16472         si->request = !(flags&SMB_FLAGS_DIRN);
16473         flags2 = tvb_get_letohs(tvb, offset+10);
16474         if(flags2 & 0x8000){
16475                 si->unicode = TRUE; /* Mark them as Unicode */
16476         } else {
16477                 si->unicode = FALSE;
16478         }
16479         si->tid = tvb_get_letohs(tvb, offset+24);
16480         si->pid = tvb_get_letohs(tvb, offset+26);
16481         si->uid = tvb_get_letohs(tvb, offset+28);
16482         si->mid = tvb_get_letohs(tvb, offset+30);
16483         pid_mid = (si->pid << 16) | si->mid;
16484         si->info_level = -1;
16485         si->info_count = -1;
16486
16487         if (parent_tree) {
16488                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16489                         -1, FALSE);
16490                 tree = proto_item_add_subtree(item, ett_smb);
16491
16492                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16493                         "SMB Header");
16494
16495                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16496         }
16497
16498         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16499         offset += 4;  /* Skip the marker */
16500
16501         /* find which conversation we are part of and get the tables for that
16502            conversation*/
16503         conversation = find_conversation(&pinfo->src, &pinfo->dst,
16504                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16505         if(!conversation){
16506                 /* OK this is a new conversation so lets create it */
16507                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
16508                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16509         }
16510         /* see if we already have the smb data for this conversation */
16511         si->ct=conversation_get_proto_data(conversation, proto_smb);
16512         if(!si->ct){
16513                 /* No, not yet. create it and attach it to the conversation */
16514                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
16515                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16516                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16517                         smb_saved_info_equal_matched);
16518                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16519                         smb_saved_info_equal_unmatched);
16520                 si->ct->tid_service=g_hash_table_new(
16521                         smb_saved_info_hash_unmatched,
16522                         smb_saved_info_equal_unmatched);
16523                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16524         }
16525
16526         if( (si->request)
16527             &&  (si->mid==0)
16528             &&  (si->uid==0)
16529             &&  (si->pid==0)
16530             &&  (si->tid==0) ){
16531                 /* this is a broadcast SMB packet, there will not be a reply.
16532                    We dont need to do anything
16533                 */
16534                 si->unidir = TRUE;
16535         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16536                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16537                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16538                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16539                 /* Ok, we got a special request type. This request is either
16540                    an NT Cancel or a continuation relative to a real request
16541                    in an earlier packet.  In either case, we don't expect any
16542                    responses to this packet.  For continuations, any later
16543                    responses we see really just belong to the original request.
16544                    Anyway, we want to remember this packet somehow and
16545                    remember which original request it is associated with so
16546                    we can say nice things such as "This is a Cancellation to
16547                    the request in frame x", but we don't want the
16548                    request/response matching to get messed up.
16549
16550                    The only thing we do in this case is trying to find which original
16551                    request we match with and insert an entry for this "special"
16552                    request for later reference. We continue to reference the original
16553                    requests smb_saved_info_t but we dont touch it or change anything
16554                    in it.
16555                 */
16556
16557                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16558
16559                 if(!pinfo->fd->flags.visited){
16560                         /* try to find which original call we match and if we
16561                            find it add us to the matched table. Dont touch
16562                            anything else since we dont want this one to mess
16563                            up the request/response matching. We still consider
16564                            the initial call the real request and this is only
16565                            some sort of continuation.
16566                         */
16567                         /* we only check the unmatched table and assume that the
16568                            last seen MID matching ours is the right one.
16569                            This can fail but is better than nothing
16570                         */
16571                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16572                         if(sip!=NULL){
16573                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16574                                 new_key->frame = pinfo->fd->num;
16575                                 new_key->pid_mid = pid_mid;
16576                                 g_hash_table_insert(si->ct->matched, new_key,
16577                                     sip);
16578                         }
16579                 } else {
16580                         /* we have seen this packet before; check the
16581                            matching table
16582                         */
16583                         key.frame = pinfo->fd->num;
16584                         key.pid_mid = pid_mid;
16585                         sip=g_hash_table_lookup(si->ct->matched, &key);
16586                         if(sip==NULL){
16587                         /*
16588                           We didn't find it.
16589                           Too bad, unfortunately there is not really much we can
16590                           do now since this means that we never saw the initial
16591                           request.
16592                          */
16593                         }
16594                 }
16595
16596
16597                 if(sip && sip->frame_req){
16598                         switch(si->cmd){
16599                         case SMB_COM_NT_CANCEL:
16600                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
16601                                                     tvb, 0, 0, sip->frame_req);
16602                                 break;
16603                         case SMB_COM_TRANSACTION_SECONDARY:
16604                         case SMB_COM_TRANSACTION2_SECONDARY:
16605                         case SMB_COM_NT_TRANSACT_SECONDARY:
16606                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16607                                                     tvb, 0, 0, sip->frame_req);
16608                                 break;
16609                         }
16610                 } else {
16611                         switch(si->cmd){
16612                         case SMB_COM_NT_CANCEL:
16613                                 proto_tree_add_text(htree, tvb, 0, 0,
16614                                                     "Cancellation to: <unknown frame>");
16615                                 break;
16616                         case SMB_COM_TRANSACTION_SECONDARY:
16617                         case SMB_COM_TRANSACTION2_SECONDARY:
16618                         case SMB_COM_NT_TRANSACT_SECONDARY:
16619                                 proto_tree_add_text(htree, tvb, 0, 0,
16620                                                     "Continuation to: <unknown frame>");
16621                                 break;
16622                         }
16623                 }
16624         } else { /* normal bidirectional request or response */
16625                 si->unidir = FALSE;
16626
16627                 if(!pinfo->fd->flags.visited){
16628                         /* first see if we find an unmatched smb "equal" to
16629                            the current one
16630                         */
16631                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16632                         if(sip!=NULL){
16633                                 gboolean cmd_match=FALSE;
16634
16635                                 /*
16636                                  * Make sure the SMB we found was the
16637                                  * same command, or a different command
16638                                  * that's another valid type of reply
16639                                  * to that command.
16640                                  */
16641                                 if(si->cmd==sip->cmd){
16642                                         cmd_match=TRUE;
16643                                 }
16644                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16645                                         cmd_match=TRUE;
16646                                 }
16647                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16648                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16649                                         cmd_match=TRUE;
16650                                 }
16651                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16652                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16653                                         cmd_match=TRUE;
16654                                 }
16655                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16656                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16657                                         cmd_match=TRUE;
16658                                 }
16659
16660                                 if( (si->request) || (!cmd_match) ) {
16661                                         /* If we are processing an SMB request but there was already
16662                                            another "identical" smb resuest we had not matched yet.
16663                                            This must mean that either we have a retransmission or that the
16664                                            response to the previous one was lost and the client has reused
16665                                            the MID for this conversation. In either case it's not much more
16666                                            we can do than forget the old request and concentrate on the
16667                                            present one instead.
16668
16669                                            We also do this cleanup if we see that the cmd in the original
16670                                            request in sip->cmd is not compatible with the current cmd.
16671                                            This is to prevent matching errors such as if there were two
16672                                            SMBs of different cmds but with identical MID and PID values and
16673                                            if ethereal lost the first reply and the second request.
16674                                         */
16675                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16676                                         sip=NULL; /* XXX should free it as well */
16677                                 } else {
16678                                         /* we have found a response to some request we have seen earlier.
16679                                            What we do now depends on whether this is the first response
16680                                            to that request we see (id frame_res==0) or not.
16681                                         */
16682                                         if(sip->frame_res==0){
16683                                                 /* ok it is the first response we have seen to this packet */
16684                                                 sip->frame_res = pinfo->fd->num;
16685                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16686                                                 new_key->frame = sip->frame_res;
16687                                                 new_key->pid_mid = pid_mid;
16688                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16689                                         } else {
16690                                                 /* We have already seen another response to this MID.
16691                                                    Since the MID in reality is only something like 10 bits
16692                                                    this probably means that we just have a MID that is being
16693                                                    reused due to the small MID space and that this is a new
16694                                                    command we did not see the original request for.
16695                                                 */
16696                                                 sip=NULL;
16697                                         }
16698                                 }
16699                         }
16700                         if(si->request){
16701                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16702                                 sip->frame_req = pinfo->fd->num;
16703                                 sip->frame_res = 0;
16704                                 sip->req_time.secs=pinfo->fd->abs_secs;
16705                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16706                                 sip->flags = 0;
16707                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16708                                     == (void *)TID_IPC) {
16709                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16710                                 }
16711                                 sip->cmd = si->cmd;
16712                                 sip->extra_info = NULL;
16713                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16714                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16715                                 new_key->frame = sip->frame_req;
16716                                 new_key->pid_mid = pid_mid;
16717                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16718                         }
16719                 } else {
16720                         /* we have seen this packet before; check the
16721                            matching table.
16722                            If we haven't yet seen the reply, we won't
16723                            find the info for it; we don't need it, as
16724                            we only use it to save information, and, as
16725                            we've seen this packet before, we've already
16726                            saved the information.
16727                         */
16728                         key.frame = pinfo->fd->num;
16729                         key.pid_mid = pid_mid;
16730                         sip=g_hash_table_lookup(si->ct->matched, &key);
16731                 }
16732         }
16733
16734         /*
16735          * Pass the "sip" on to subdissectors through "si".
16736          */
16737         si->sip = sip;
16738
16739         if (sip != NULL) {
16740                 /*
16741                  * Put in fields for the frame number of the frame to which
16742                  * this is a response or the frame with the response to this
16743                  * frame - if we know the frame number (i.e., it's not 0).
16744                  */
16745                 if(si->request){
16746                         if (sip->frame_res != 0)
16747                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16748                 } else {
16749                         if (sip->frame_req != 0) {
16750                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16751                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16752                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16753                                 if(ns.nsecs<0){
16754                                         ns.nsecs+=1000000000;
16755                                         ns.secs--;
16756                                 }
16757                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16758                                     0, 0, &ns);
16759                         }
16760                 }
16761         }
16762
16763         /* smb command */
16764         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);
16765         offset += 1;
16766
16767         if(flags2 & 0x4000){
16768                 /* handle NT 32 bit error code */
16769
16770                 nt_status = tvb_get_letohl(tvb, offset);
16771
16772                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16773                         TRUE);
16774                 offset += 4;
16775
16776         } else {
16777                 /* handle DOS error code & class */
16778                 errclass = tvb_get_guint8(tvb, offset);
16779                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16780                         errclass);
16781                 offset += 1;
16782
16783                 /* reserved byte */
16784                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16785                 offset += 1;
16786
16787                 /* error code */
16788                 /* XXX - the type of this field depends on the value of
16789                  * "errcls", so there is isn't a single value_string array
16790                  * fo it, so there can't be a single field for it.
16791                  */
16792                 errcode = tvb_get_letohs(tvb, offset);
16793                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16794                         offset, 2, errcode, "Error Code: %s",
16795                         decode_smb_error(errclass, errcode));
16796                 offset += 2;
16797         }
16798
16799         /* flags */
16800         offset = dissect_smb_flags(tvb, htree, offset);
16801
16802         /* flags2 */
16803         offset = dissect_smb_flags2(tvb, htree, offset);
16804
16805         /*
16806          * The document at
16807          *
16808          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16809          *
16810          * (a text version of "Microsoft Networks SMB FILE SHARING
16811          * PROTOCOL, Document Version 6.0p") says that:
16812          *
16813          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16814          *      the "High Part of PID";
16815          *
16816          *      the next four bytes are reserved;
16817          *
16818          *      the next four bytes are, for SMB-over-IPX (with no
16819          *      NetBIOS involved) two bytes of Session ID and two bytes
16820          *      of SequenceNumber.
16821          *
16822          * Network Monitor 2.x dissects the four bytes before the Session ID
16823          * as a "Key", and the two bytes after the SequenceNumber as
16824          * a "Group ID".
16825          *
16826          * The "High Part of PID" has been seen in calls other than NT
16827          * Create and X, although most of them appear to be I/O on DCE RPC
16828          * pipes opened with the NT Create and X in question.
16829          */
16830         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16831         offset += 2;
16832
16833         if (pinfo->ptype == PT_IPX &&
16834             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16835              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16836              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16837                 /*
16838                  * This is SMB-over-IPX.
16839                  * XXX - do we have to worry about "sequenced commands",
16840                  * as per the Samba document?  They say that for
16841                  * "unsequenced commands" (with a sequence number of 0),
16842                  * the Mid must be unique, but perhaps the Mid doesn't
16843                  * have to be unique for sequenced commands.  In at least
16844                  * one capture with SMB-over-IPX, however, the Mids
16845                  * are unique even for sequenced commands.
16846                  */
16847                 /* Key */
16848                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16849                     TRUE);
16850                 offset += 4;
16851
16852                 /* Session ID */
16853                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16854                     TRUE);
16855                 offset += 2;
16856
16857                 /* Sequence number */
16858                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16859                     TRUE);
16860                 offset += 2;
16861
16862                 /* Group ID */
16863                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16864                     TRUE);
16865                 offset += 2;
16866         } else {
16867                 /*
16868                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16869                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16870                  * bytes after the "High part of PID" are an 8-byte
16871                  * signature ...
16872                  */
16873                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16874                 offset += 8;
16875
16876                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16877                 offset += 2;
16878         }
16879
16880         /* TID */
16881         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16882         offset += 2;
16883
16884         /* PID */
16885         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16886         offset += 2;
16887
16888         /* UID */
16889         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16890         offset += 2;
16891
16892         /* MID */
16893         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16894         offset += 2;
16895
16896         pinfo->private_data = si;
16897
16898         /* tap the packet before the dissectors are called so we still get
16899            the tap listener called even if there is an exception.
16900         */
16901         tap_queue_packet(smb_tap, pinfo, si);
16902         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16903
16904         /* Append error info from this packet to info string. */
16905         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16906                 if (flags2 & 0x4000) {
16907                         /*
16908                          * The status is an NT status code; was there
16909                          * an error?
16910                          */
16911                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16912                                 /*
16913                                  * Yes.
16914                                  */
16915                                 col_append_fstr(
16916                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16917                                         val_to_str(nt_status, NT_errors,
16918                                             "Unknown (0x%08X)"));
16919                         }
16920                 } else {
16921                         /*
16922                          * The status is a DOS error class and code; was
16923                          * there an error?
16924                          */
16925                         if (errclass != SMB_SUCCESS) {
16926                                 /*
16927                                  * Yes.
16928                                  */
16929                                 col_append_fstr(
16930                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16931                                         decode_smb_error(errclass, errcode));
16932                         }
16933                 }
16934         }
16935 }
16936
16937 static gboolean
16938 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16939 {
16940         /* must check that this really is a smb packet */
16941         if (!tvb_bytes_exist(tvb, 0, 4))
16942                 return FALSE;
16943
16944         if( (tvb_get_guint8(tvb, 0) != 0xff)
16945             || (tvb_get_guint8(tvb, 1) != 'S')
16946             || (tvb_get_guint8(tvb, 2) != 'M')
16947             || (tvb_get_guint8(tvb, 3) != 'B') ){
16948                 return FALSE;
16949         }
16950
16951         dissect_smb(tvb, pinfo, parent_tree);
16952         return TRUE;
16953 }
16954
16955 void
16956 proto_register_smb(void)
16957 {
16958         static hf_register_info hf[] = {
16959         { &hf_smb_cmd,
16960                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16961                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16962
16963         { &hf_smb_word_count,
16964                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16965                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16966
16967         { &hf_smb_byte_count,
16968                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16969                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16970
16971         { &hf_smb_response_to,
16972                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16973                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16974
16975         { &hf_smb_time,
16976                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16977                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16978
16979         { &hf_smb_response_in,
16980                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16981                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16982
16983         { &hf_smb_continuation_to,
16984                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16985                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16986
16987         { &hf_smb_nt_status,
16988                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16989                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16990
16991         { &hf_smb_error_class,
16992                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16993                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16994
16995         { &hf_smb_error_code,
16996                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16997                 NULL, 0, "DOS Error Code", HFILL }},
16998
16999         { &hf_smb_reserved,
17000                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
17001                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
17002
17003         { &hf_smb_sig,
17004                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
17005                 NULL, 0, "Signature bytes", HFILL }},
17006
17007         { &hf_smb_key,
17008                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
17009                 NULL, 0, "SMB-over-IPX Key", HFILL }},
17010
17011         { &hf_smb_session_id,
17012                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
17013                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
17014
17015         { &hf_smb_sequence_num,
17016                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
17017                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
17018
17019         { &hf_smb_group_id,
17020                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
17021                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
17022
17023         { &hf_smb_pid,
17024                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
17025                 NULL, 0, "Process ID", HFILL }},
17026
17027         { &hf_smb_pid_high,
17028                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
17029                 NULL, 0, "Process ID High Bytes", HFILL }},
17030
17031         { &hf_smb_tid,
17032                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
17033                 NULL, 0, "Tree ID", HFILL }},
17034
17035         { &hf_smb_uid,
17036                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
17037                 NULL, 0, "User ID", HFILL }},
17038
17039         { &hf_smb_mid,
17040                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
17041                 NULL, 0, "Multiplex ID", HFILL }},
17042
17043         { &hf_smb_flags_lock,
17044                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
17045                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
17046
17047         { &hf_smb_flags_receive_buffer,
17048                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
17049                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
17050
17051         { &hf_smb_flags_caseless,
17052                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
17053                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
17054
17055         { &hf_smb_flags_canon,
17056                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
17057                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
17058
17059         { &hf_smb_flags_oplock,
17060                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
17061                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
17062
17063         { &hf_smb_flags_notify,
17064                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
17065                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
17066
17067         { &hf_smb_flags_response,
17068                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
17069                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
17070
17071         { &hf_smb_flags2_long_names_allowed,
17072                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
17073                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
17074
17075         { &hf_smb_flags2_ea,
17076                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
17077                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
17078
17079         { &hf_smb_flags2_sec_sig,
17080                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
17081                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
17082
17083         { &hf_smb_flags2_long_names_used,
17084                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
17085                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
17086
17087         { &hf_smb_flags2_esn,
17088                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
17089                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
17090
17091         { &hf_smb_flags2_dfs,
17092                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
17093                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
17094
17095         { &hf_smb_flags2_roe,
17096                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
17097                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
17098
17099         { &hf_smb_flags2_nt_error,
17100                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
17101                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
17102
17103         { &hf_smb_flags2_string,
17104                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
17105                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
17106
17107         { &hf_smb_buffer_format,
17108                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
17109                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
17110
17111         { &hf_smb_dialect_name,
17112                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
17113                 NULL, 0, "Name of dialect", HFILL }},
17114
17115         { &hf_smb_dialect_index,
17116                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
17117                 NULL, 0, "Index of selected dialect", HFILL }},
17118
17119         { &hf_smb_max_trans_buf_size,
17120                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
17121                 NULL, 0, "Maximum transmit buffer size", HFILL }},
17122
17123         { &hf_smb_max_mpx_count,
17124                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
17125                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
17126
17127         { &hf_smb_max_vcs_num,
17128                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
17129                 NULL, 0, "Maximum VCs between client and server", HFILL }},
17130
17131         { &hf_smb_session_key,
17132                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
17133                 NULL, 0, "Unique token identifying this session", HFILL }},
17134
17135         { &hf_smb_server_timezone,
17136                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
17137                 NULL, 0, "Current timezone at server.", HFILL }},
17138
17139         { &hf_smb_encryption_key_length,
17140                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
17141                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
17142
17143         { &hf_smb_encryption_key,
17144                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
17145                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
17146
17147         { &hf_smb_primary_domain,
17148                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
17149                 NULL, 0, "The server's primary domain", HFILL }},
17150
17151         { &hf_smb_server,
17152                 { "Server", "smb.server", FT_STRING, BASE_NONE,
17153                 NULL, 0, "The name of the DC/server", HFILL }},
17154
17155         { &hf_smb_max_raw_buf_size,
17156                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17157                 NULL, 0, "Maximum raw buffer size", HFILL }},
17158
17159         { &hf_smb_server_guid,
17160                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
17161                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17162
17163         { &hf_smb_security_blob_len,
17164                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17165                 NULL, 0, "Security blob length", HFILL }},
17166
17167         { &hf_smb_security_blob,
17168                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
17169                 NULL, 0, "Security blob", HFILL }},
17170
17171         { &hf_smb_sm_mode16,
17172                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17173                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17174
17175         { &hf_smb_sm_password16,
17176                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17177                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17178
17179         { &hf_smb_sm_mode,
17180                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17181                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17182
17183         { &hf_smb_sm_password,
17184                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17185                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17186
17187         { &hf_smb_sm_signatures,
17188                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17189                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17190
17191         { &hf_smb_sm_sig_required,
17192                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17193                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17194
17195         { &hf_smb_rm_read,
17196                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17197                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17198
17199         { &hf_smb_rm_write,
17200                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17201                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17202
17203         { &hf_smb_server_date_time,
17204                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17205                 NULL, 0, "Current date and time at server", HFILL }},
17206
17207         { &hf_smb_server_smb_date,
17208                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17209                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17210
17211         { &hf_smb_server_smb_time,
17212                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17213                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17214
17215         { &hf_smb_server_cap_raw_mode,
17216                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17217                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17218
17219         { &hf_smb_server_cap_mpx_mode,
17220                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17221                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17222
17223         { &hf_smb_server_cap_unicode,
17224                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17225                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17226
17227         { &hf_smb_server_cap_large_files,
17228                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17229                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17230
17231         { &hf_smb_server_cap_nt_smbs,
17232                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17233                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17234
17235         { &hf_smb_server_cap_rpc_remote_apis,
17236                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17237                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17238
17239         { &hf_smb_server_cap_nt_status,
17240                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17241                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17242
17243         { &hf_smb_server_cap_level_ii_oplocks,
17244                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17245                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17246
17247         { &hf_smb_server_cap_lock_and_read,
17248                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17249                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17250
17251         { &hf_smb_server_cap_nt_find,
17252                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17253                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17254
17255         { &hf_smb_server_cap_dfs,
17256                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17257                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17258
17259         { &hf_smb_server_cap_infolevel_passthru,
17260                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17261                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17262
17263         { &hf_smb_server_cap_large_readx,
17264                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17265                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17266
17267         { &hf_smb_server_cap_large_writex,
17268                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17269                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17270
17271         { &hf_smb_server_cap_unix,
17272                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17273                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17274
17275         { &hf_smb_server_cap_reserved,
17276                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17277                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17278
17279         { &hf_smb_server_cap_bulk_transfer,
17280                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17281                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17282
17283         { &hf_smb_server_cap_compressed_data,
17284                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17285                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17286
17287         { &hf_smb_server_cap_extended_security,
17288                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17289                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17290
17291         { &hf_smb_system_time,
17292                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17293                 NULL, 0, "System Time", HFILL }},
17294
17295         { &hf_smb_unknown,
17296                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17297                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17298
17299         { &hf_smb_dir_name,
17300                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17301                 NULL, 0, "SMB Directory Name", HFILL }},
17302
17303         { &hf_smb_echo_count,
17304                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17305                 NULL, 0, "Number of times to echo data back", HFILL }},
17306
17307         { &hf_smb_echo_data,
17308                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17309                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17310
17311         { &hf_smb_echo_seq_num,
17312                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17313                 NULL, 0, "Sequence number for this echo response", HFILL }},
17314
17315         { &hf_smb_max_buf_size,
17316                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17317                 NULL, 0, "Max client buffer size", HFILL }},
17318
17319         { &hf_smb_path,
17320                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17321                 NULL, 0, "Path. Server name and share name", HFILL }},
17322
17323         { &hf_smb_service,
17324                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17325                 NULL, 0, "Service name", HFILL }},
17326
17327         { &hf_smb_password,
17328                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17329                 NULL, 0, "Password", HFILL }},
17330
17331         { &hf_smb_ansi_password,
17332                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17333                 NULL, 0, "ANSI Password", HFILL }},
17334
17335         { &hf_smb_unicode_password,
17336                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17337                 NULL, 0, "Unicode Password", HFILL }},
17338
17339         { &hf_smb_move_flags_file,
17340                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17341                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17342
17343         { &hf_smb_move_flags_dir,
17344                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17345                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17346
17347         { &hf_smb_move_flags_verify,
17348                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17349                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17350
17351         { &hf_smb_files_moved,
17352                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17353                 NULL, 0, "Number of files moved", HFILL }},
17354
17355         { &hf_smb_copy_flags_file,
17356                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17357                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17358
17359         { &hf_smb_copy_flags_dir,
17360                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17361                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17362
17363         { &hf_smb_copy_flags_dest_mode,
17364                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17365                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17366
17367         { &hf_smb_copy_flags_source_mode,
17368                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17369                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17370
17371         { &hf_smb_copy_flags_verify,
17372                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17373                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17374
17375         { &hf_smb_copy_flags_tree_copy,
17376                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17377                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17378
17379         { &hf_smb_copy_flags_ea_action,
17380                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17381                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17382
17383         { &hf_smb_count,
17384                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17385                 NULL, 0, "Count number of items/bytes", HFILL }},
17386
17387         { &hf_smb_count_low,
17388                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17389                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17390
17391         { &hf_smb_count_high,
17392                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17393                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17394
17395         { &hf_smb_file_name,
17396                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17397                 NULL, 0, "File Name", HFILL }},
17398
17399         { &hf_smb_open_function_create,
17400                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17401                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17402
17403         { &hf_smb_open_function_open,
17404                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17405                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17406
17407         { &hf_smb_fid,
17408                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17409                 NULL, 0, "FID: File ID", HFILL }},
17410
17411         { &hf_smb_file_attr_read_only_16bit,
17412                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17413                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17414
17415         { &hf_smb_file_attr_read_only_8bit,
17416                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17417                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17418
17419         { &hf_smb_file_attr_hidden_16bit,
17420                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17421                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17422
17423         { &hf_smb_file_attr_hidden_8bit,
17424                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17425                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17426
17427         { &hf_smb_file_attr_system_16bit,
17428                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17429                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17430
17431         { &hf_smb_file_attr_system_8bit,
17432                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17433                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17434
17435         { &hf_smb_file_attr_volume_16bit,
17436                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17437                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17438
17439         { &hf_smb_file_attr_volume_8bit,
17440                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17441                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17442
17443         { &hf_smb_file_attr_directory_16bit,
17444                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17445                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17446
17447         { &hf_smb_file_attr_directory_8bit,
17448                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17449                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17450
17451         { &hf_smb_file_attr_archive_16bit,
17452                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17453                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17454
17455         { &hf_smb_file_attr_archive_8bit,
17456                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17457                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17458
17459         { &hf_smb_file_attr_device,
17460                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17461                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17462
17463         { &hf_smb_file_attr_normal,
17464                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17465                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17466
17467         { &hf_smb_file_attr_temporary,
17468                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17469                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17470
17471         { &hf_smb_file_attr_sparse,
17472                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17473                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17474
17475         { &hf_smb_file_attr_reparse,
17476                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17477                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17478
17479         { &hf_smb_file_attr_compressed,
17480                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17481                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17482
17483         { &hf_smb_file_attr_offline,
17484                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17485                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17486
17487         { &hf_smb_file_attr_not_content_indexed,
17488                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17489                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17490
17491         { &hf_smb_file_attr_encrypted,
17492                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17493                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17494
17495         { &hf_smb_file_size,
17496                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17497                 NULL, 0, "File Size", HFILL }},
17498
17499         { &hf_smb_search_attribute_read_only,
17500                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17501                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17502
17503         { &hf_smb_search_attribute_hidden,
17504                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17505                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17506
17507         { &hf_smb_search_attribute_system,
17508                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17509                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17510
17511         { &hf_smb_search_attribute_volume,
17512                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17513                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17514
17515         { &hf_smb_search_attribute_directory,
17516                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17517                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17518
17519         { &hf_smb_search_attribute_archive,
17520                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17521                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17522
17523         { &hf_smb_access_mode,
17524                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17525                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17526
17527         { &hf_smb_access_sharing,
17528                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17529                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17530
17531         { &hf_smb_access_locality,
17532                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17533                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17534
17535         { &hf_smb_access_caching,
17536                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17537                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17538
17539         { &hf_smb_access_writetru,
17540                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17541                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17542
17543         { &hf_smb_create_time,
17544                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17545                 NULL, 0, "Creation Time", HFILL }},
17546
17547         { &hf_smb_modify_time,
17548                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17549                   NULL, 0, "Modification Time", HFILL }},
17550
17551         { &hf_smb_backup_time,
17552                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17553                   NULL, 0, "Backup time", HFILL}},
17554
17555         { &hf_smb_mac_alloc_block_count,
17556                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17557                   NULL, 0, "Allocation Block Count", HFILL}},
17558
17559         { &hf_smb_mac_alloc_block_size,
17560                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17561                   NULL, 0, "Allocation Block Size", HFILL}},
17562
17563         { &hf_smb_mac_free_block_count,
17564                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17565                   NULL, 0, "Free Block Count", HFILL}},
17566
17567         { &hf_smb_mac_root_file_count,
17568                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17569                 NULL, 0, "Root File Count", HFILL}},
17570
17571         { &hf_smb_mac_root_dir_count,
17572           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17573             NULL, 0, "Root Directory Count", HFILL}},
17574
17575         { &hf_smb_mac_file_count,
17576           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17577             NULL, 0, "File Count", HFILL}},
17578
17579         { &hf_smb_mac_dir_count,
17580           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17581             NULL, 0, "Directory Count", HFILL}},
17582
17583         { &hf_smb_mac_support_flags,
17584           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17585             NULL, 0, "Mac Support Flags", HFILL}},
17586
17587         { &hf_smb_mac_sup_access_ctrl,
17588           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17589             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17590
17591         { &hf_smb_mac_sup_getset_comments,
17592           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17593             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17594
17595         { &hf_smb_mac_sup_desktopdb_calls,
17596           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17597             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17598
17599         { &hf_smb_mac_sup_unique_ids,
17600           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17601             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17602
17603         { &hf_smb_mac_sup_streams,
17604           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17605             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17606
17607         { &hf_smb_create_dos_date,
17608                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17609                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17610
17611         { &hf_smb_create_dos_time,
17612                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17613                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17614
17615         { &hf_smb_last_write_time,
17616                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17617                 NULL, 0, "Time this file was last written to", HFILL }},
17618
17619         { &hf_smb_last_write_dos_date,
17620                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17621                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17622
17623         { &hf_smb_last_write_dos_time,
17624                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17625                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17626
17627         { &hf_smb_old_file_name,
17628                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17629                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17630
17631         { &hf_smb_offset,
17632                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17633                 NULL, 0, "Offset in file", HFILL }},
17634
17635         { &hf_smb_remaining,
17636                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17637                 NULL, 0, "Remaining number of bytes", HFILL }},
17638
17639         { &hf_smb_padding,
17640                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17641                 NULL, 0, "Padding or unknown data", HFILL }},
17642
17643         { &hf_smb_file_data,
17644                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17645                 NULL, 0, "Data read/written to the file", HFILL }},
17646
17647         { &hf_smb_mac_fndrinfo,
17648                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17649                   NULL, 0, "Finder Info", HFILL}},
17650
17651         { &hf_smb_total_data_len,
17652                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17653                 NULL, 0, "Total length of data", HFILL }},
17654
17655         { &hf_smb_data_len,
17656                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17657                 NULL, 0, "Length of data", HFILL }},
17658
17659         { &hf_smb_data_len_low,
17660                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17661                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17662
17663         { &hf_smb_data_len_high,
17664                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17665                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17666
17667         { &hf_smb_seek_mode,
17668                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17669                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17670
17671         { &hf_smb_access_time,
17672                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17673                 NULL, 0, "Last Access Time", HFILL }},
17674
17675         { &hf_smb_access_dos_date,
17676                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17677                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17678
17679         { &hf_smb_access_dos_time,
17680                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17681                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17682
17683         { &hf_smb_data_size,
17684                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17685                 NULL, 0, "Data Size", HFILL }},
17686
17687         { &hf_smb_alloc_size,
17688                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17689                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17690
17691         { &hf_smb_max_count,
17692                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17693                 NULL, 0, "Maximum Count", HFILL }},
17694
17695         { &hf_smb_max_count_low,
17696                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17697                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17698
17699         { &hf_smb_max_count_high,
17700                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17701                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17702
17703         { &hf_smb_min_count,
17704                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17705                 NULL, 0, "Minimum Count", HFILL }},
17706
17707         { &hf_smb_timeout,
17708                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17709                 NULL, 0, "Timeout in miliseconds", HFILL }},
17710
17711         { &hf_smb_high_offset,
17712                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17713                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17714
17715         { &hf_smb_units,
17716                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17717                 NULL, 0, "Total number of units at server", HFILL }},
17718
17719         { &hf_smb_bpu,
17720                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17721                 NULL, 0, "Blocks per unit at server", HFILL }},
17722
17723         { &hf_smb_blocksize,
17724                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17725                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17726
17727         { &hf_smb_freeunits,
17728                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17729                 NULL, 0, "Number of free units at server", HFILL }},
17730
17731         { &hf_smb_data_offset,
17732                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17733                 NULL, 0, "Data Offset", HFILL }},
17734
17735         { &hf_smb_dcm,
17736                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17737                 NULL, 0, "Data Compaction Mode", HFILL }},
17738
17739         { &hf_smb_request_mask,
17740                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17741                 NULL, 0, "Connectionless mode mask", HFILL }},
17742
17743         { &hf_smb_response_mask,
17744                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17745                 NULL, 0, "Connectionless mode mask", HFILL }},
17746
17747         { &hf_smb_search_id,
17748                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17749                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17750
17751         { &hf_smb_write_mode_write_through,
17752                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17753                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17754
17755         { &hf_smb_write_mode_return_remaining,
17756                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17757                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17758
17759         { &hf_smb_write_mode_raw,
17760                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17761                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17762
17763         { &hf_smb_write_mode_message_start,
17764                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17765                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17766
17767         { &hf_smb_write_mode_connectionless,
17768                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17769                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17770
17771         { &hf_smb_resume_key_len,
17772                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17773                 NULL, 0, "Resume Key length", HFILL }},
17774
17775         { &hf_smb_resume_find_id,
17776                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17777                 NULL, 0, "Handle for Find operation", HFILL }},
17778
17779         { &hf_smb_resume_server_cookie,
17780                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17781                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17782
17783         { &hf_smb_resume_client_cookie,
17784                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17785                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17786
17787         { &hf_smb_andxoffset,
17788                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17789                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17790
17791         { &hf_smb_lock_type_large,
17792                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17793                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17794
17795         { &hf_smb_lock_type_cancel,
17796                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17797                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17798
17799         { &hf_smb_lock_type_change,
17800                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17801                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17802
17803         { &hf_smb_lock_type_oplock,
17804                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17805                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17806
17807         { &hf_smb_lock_type_shared,
17808                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17809                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17810
17811         { &hf_smb_locking_ol,
17812                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17813                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17814
17815         { &hf_smb_number_of_locks,
17816                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17817                 NULL, 0, "Number of lock requests in this request", HFILL }},
17818
17819         { &hf_smb_number_of_unlocks,
17820                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17821                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17822
17823         { &hf_smb_lock_long_length,
17824                 { "Length", "smb.lock.length", FT_STRING, BASE_DEC,
17825                 NULL, 0, "Length of lock/unlock region", HFILL }},
17826
17827         { &hf_smb_lock_long_offset,
17828                 { "Offset", "smb.lock.offset", FT_STRING, BASE_DEC,
17829                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17830
17831         { &hf_smb_file_type,
17832                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17833                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17834
17835         { &hf_smb_ipc_state_nonblocking,
17836                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17837                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17838
17839         { &hf_smb_ipc_state_endpoint,
17840                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17841                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17842
17843         { &hf_smb_ipc_state_pipe_type,
17844                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17845                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17846
17847         { &hf_smb_ipc_state_read_mode,
17848                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17849                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17850
17851         { &hf_smb_ipc_state_icount,
17852                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17853                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17854
17855         { &hf_smb_server_fid,
17856                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17857                 NULL, 0, "Server unique File ID", HFILL }},
17858
17859         { &hf_smb_open_flags_add_info,
17860                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17861                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17862
17863         { &hf_smb_open_flags_ex_oplock,
17864                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17865                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17866
17867         { &hf_smb_open_flags_batch_oplock,
17868                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17869                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17870
17871         { &hf_smb_open_flags_ealen,
17872                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17873                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17874
17875         { &hf_smb_open_action_open,
17876                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17877                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17878
17879         { &hf_smb_open_action_lock,
17880                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17881                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17882
17883         { &hf_smb_vc_num,
17884                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17885                 NULL, 0, "VC Number", HFILL }},
17886
17887         { &hf_smb_password_len,
17888                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17889                 NULL, 0, "Length of password", HFILL }},
17890
17891         { &hf_smb_ansi_password_len,
17892                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17893                 NULL, 0, "Length of ANSI password", HFILL }},
17894
17895         { &hf_smb_unicode_password_len,
17896                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17897                 NULL, 0, "Length of Unicode password", HFILL }},
17898
17899         { &hf_smb_account,
17900                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17901                 NULL, 0, "Account, username", HFILL }},
17902
17903         { &hf_smb_os,
17904                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17905                 NULL, 0, "Which OS we are running", HFILL }},
17906
17907         { &hf_smb_lanman,
17908                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17909                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17910
17911         { &hf_smb_setup_action_guest,
17912                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17913                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17914
17915         { &hf_smb_fs,
17916                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17917                 NULL, 0, "Native File System", HFILL }},
17918
17919         { &hf_smb_connect_flags_dtid,
17920                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17921                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17922
17923         { &hf_smb_connect_support_search,
17924                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17925                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17926
17927         { &hf_smb_connect_support_in_dfs,
17928                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17929                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17930
17931         { &hf_smb_max_setup_count,
17932                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17933                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17934
17935         { &hf_smb_total_param_count,
17936                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17937                 NULL, 0, "Total number of parameter bytes", HFILL }},
17938
17939         { &hf_smb_total_data_count,
17940                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17941                 NULL, 0, "Total number of data bytes", HFILL }},
17942
17943         { &hf_smb_max_param_count,
17944                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17945                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17946
17947         { &hf_smb_max_data_count,
17948                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17949                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17950
17951         { &hf_smb_param_disp16,
17952                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17953                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17954
17955         { &hf_smb_param_count16,
17956                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17957                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17958
17959         { &hf_smb_param_offset16,
17960                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17961                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17962
17963         { &hf_smb_param_disp32,
17964                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17965                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17966
17967         { &hf_smb_param_count32,
17968                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17969                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17970
17971         { &hf_smb_param_offset32,
17972                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17973                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17974
17975         { &hf_smb_data_count16,
17976                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17977                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17978
17979         { &hf_smb_data_disp16,
17980                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17981                 NULL, 0, "Data Displacement", HFILL }},
17982
17983         { &hf_smb_data_offset16,
17984                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17985                 NULL, 0, "Data Offset", HFILL }},
17986
17987         { &hf_smb_data_count32,
17988                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17989                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17990
17991         { &hf_smb_data_disp32,
17992                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17993                 NULL, 0, "Data Displacement", HFILL }},
17994
17995         { &hf_smb_data_offset32,
17996                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17997                 NULL, 0, "Data Offset", HFILL }},
17998
17999         { &hf_smb_setup_count,
18000                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
18001                 NULL, 0, "Number of setup words in this buffer", HFILL }},
18002
18003         { &hf_smb_nt_trans_subcmd,
18004                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
18005                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
18006
18007         { &hf_smb_nt_ioctl_function_code,
18008                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
18009                 NULL, 0, "NT IOCTL function code", HFILL }},
18010
18011         { &hf_smb_nt_ioctl_isfsctl,
18012                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
18013                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
18014
18015         { &hf_smb_nt_ioctl_flags_root_handle,
18016                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
18017                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
18018
18019         { &hf_smb_nt_ioctl_data,
18020                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
18021                 NULL, 0, "Data for the IOCTL call", HFILL }},
18022
18023         { &hf_smb_nt_notify_action,
18024                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
18025                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
18026
18027         { &hf_smb_nt_notify_watch_tree,
18028                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
18029                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
18030
18031         { &hf_smb_nt_notify_stream_write,
18032                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
18033                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
18034
18035         { &hf_smb_nt_notify_stream_size,
18036                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
18037                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
18038
18039         { &hf_smb_nt_notify_stream_name,
18040                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
18041                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
18042
18043         { &hf_smb_nt_notify_security,
18044                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
18045                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
18046
18047         { &hf_smb_nt_notify_ea,
18048                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
18049                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
18050
18051         { &hf_smb_nt_notify_creation,
18052                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
18053                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
18054
18055         { &hf_smb_nt_notify_last_access,
18056                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
18057                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
18058
18059         { &hf_smb_nt_notify_last_write,
18060                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
18061                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
18062
18063         { &hf_smb_nt_notify_size,
18064                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
18065                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
18066
18067         { &hf_smb_nt_notify_attributes,
18068                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
18069                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
18070
18071         { &hf_smb_nt_notify_dir_name,
18072                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
18073                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
18074
18075         { &hf_smb_nt_notify_file_name,
18076                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
18077                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
18078
18079         { &hf_smb_root_dir_fid,
18080                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
18081                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
18082
18083         { &hf_smb_alloc_size64,
18084                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
18085                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
18086
18087         { &hf_smb_nt_create_disposition,
18088                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
18089                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
18090
18091         { &hf_smb_sd_length,
18092                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
18093                 NULL, 0, "Total length of security descriptor", HFILL }},
18094
18095         { &hf_smb_ea_list_length,
18096                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
18097                 NULL, 0, "Total length of extended attributes", HFILL }},
18098
18099         { &hf_smb_ea_flags,
18100                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
18101                 NULL, 0, "EA Flags", HFILL }},
18102
18103         { &hf_smb_ea_name_length,
18104                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
18105                 NULL, 0, "EA Name Length", HFILL }},
18106
18107         { &hf_smb_ea_data_length,
18108                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
18109                 NULL, 0, "EA Data Length", HFILL }},
18110
18111         { &hf_smb_ea_name,
18112                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
18113                 NULL, 0, "EA Name", HFILL }},
18114
18115         { &hf_smb_ea_data,
18116                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
18117                 NULL, 0, "EA Data", HFILL }},
18118
18119         { &hf_smb_file_name_len,
18120                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
18121                 NULL, 0, "Length of File Name", HFILL }},
18122
18123         { &hf_smb_nt_impersonation_level,
18124                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
18125                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
18126
18127         { &hf_smb_nt_security_flags_context_tracking,
18128                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
18129                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
18130
18131         { &hf_smb_nt_security_flags_effective_only,
18132                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
18133                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
18134
18135         { &hf_smb_nt_access_mask_generic_read,
18136                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
18137                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
18138
18139         { &hf_smb_nt_access_mask_generic_write,
18140                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
18141                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
18142
18143         { &hf_smb_nt_access_mask_generic_execute,
18144                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
18145                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
18146
18147         { &hf_smb_nt_access_mask_generic_all,
18148                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
18149                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
18150
18151         { &hf_smb_nt_access_mask_maximum_allowed,
18152                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
18153                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
18154
18155         { &hf_smb_nt_access_mask_system_security,
18156                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18157                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18158
18159         { &hf_smb_nt_access_mask_synchronize,
18160                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18161                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18162
18163         { &hf_smb_nt_access_mask_write_owner,
18164                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18165                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18166
18167         { &hf_smb_nt_access_mask_write_dac,
18168                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18169                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18170
18171         { &hf_smb_nt_access_mask_read_control,
18172                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18173                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18174
18175         { &hf_smb_nt_access_mask_delete,
18176                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18177                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18178
18179         { &hf_smb_nt_access_mask_write_attributes,
18180                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18181                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18182
18183         { &hf_smb_nt_access_mask_read_attributes,
18184                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18185                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18186
18187         { &hf_smb_nt_access_mask_delete_child,
18188                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18189                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18190
18191         /*
18192          * "Execute" for files, "traverse" for directories.
18193          */
18194         { &hf_smb_nt_access_mask_execute,
18195                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18196                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18197
18198         { &hf_smb_nt_access_mask_write_ea,
18199                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18200                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18201
18202         { &hf_smb_nt_access_mask_read_ea,
18203                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18204                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18205
18206         /*
18207          * "Append data" for files, "add subdirectory" for directories,
18208          * "create pipe instance" for named pipes.
18209          */
18210         { &hf_smb_nt_access_mask_append,
18211                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18212                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18213
18214         /*
18215          * "Write data" for files and pipes, "add file" for directory.
18216          */
18217         { &hf_smb_nt_access_mask_write,
18218                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18219                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18220
18221         /*
18222          * "Read data" for files and pipes, "list directory" for directory.
18223          */
18224         { &hf_smb_nt_access_mask_read,
18225                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18226                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18227
18228         { &hf_smb_nt_create_bits_oplock,
18229                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18230                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18231
18232         { &hf_smb_nt_create_bits_boplock,
18233                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18234                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18235
18236         { &hf_smb_nt_create_bits_dir,
18237                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18238                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18239
18240         { &hf_smb_nt_create_bits_ext_resp,
18241           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
18242             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18243
18244         { &hf_smb_nt_create_options_directory_file,
18245                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18246                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18247
18248         { &hf_smb_nt_create_options_write_through,
18249                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18250                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18251
18252         { &hf_smb_nt_create_options_sequential_only,
18253                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18254                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
18255
18256         { &hf_smb_nt_create_options_sync_io_alert,
18257                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18258                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18259
18260         { &hf_smb_nt_create_options_sync_io_nonalert,
18261                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18262                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18263
18264         { &hf_smb_nt_create_options_non_directory_file,
18265                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18266                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18267
18268         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
18269            and "NtOpenFile()"; is that sent over the wire?  Network
18270            Monitor thinks so, but its author may just have grabbed
18271            the flag bits from a system header file. */
18272
18273         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
18274            and "NtOpenFile()"; is that sent over the wire?  NetMon
18275            thinks so, but see previous comment. */
18276
18277         { &hf_smb_nt_create_options_no_ea_knowledge,
18278                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18279                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18280
18281         { &hf_smb_nt_create_options_eight_dot_three_only,
18282                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18283                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18284
18285         { &hf_smb_nt_create_options_random_access,
18286                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18287                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18288
18289         { &hf_smb_nt_create_options_delete_on_close,
18290                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18291                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18292
18293         /* 0x00002000 is "open by FID", or something such as that (which
18294            I suspect is like "open by inumber" on UNIX), at least in
18295            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
18296            wire?  NetMon thinks so, but see previous comment. */
18297
18298         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
18299            and "NtOpenFile()"; is that sent over the wire?  NetMon
18300            thinks so, but see previous comment. */
18301
18302         { &hf_smb_nt_share_access_read,
18303                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18304                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
18305
18306         { &hf_smb_nt_share_access_write,
18307                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18308                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
18309
18310         { &hf_smb_nt_share_access_delete,
18311                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18312                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
18313
18314         { &hf_smb_file_eattr_read_only,
18315                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18316                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18317
18318         { &hf_smb_file_eattr_hidden,
18319                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18320                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18321
18322         { &hf_smb_file_eattr_system,
18323                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18324                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18325
18326         { &hf_smb_file_eattr_volume,
18327                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18328                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18329
18330         { &hf_smb_file_eattr_directory,
18331                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18332                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18333
18334         { &hf_smb_file_eattr_archive,
18335                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18336                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18337
18338         { &hf_smb_file_eattr_device,
18339                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18340                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18341
18342         { &hf_smb_file_eattr_normal,
18343                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18344                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18345
18346         { &hf_smb_file_eattr_temporary,
18347                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18348                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18349
18350         { &hf_smb_file_eattr_sparse,
18351                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18352                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18353
18354         { &hf_smb_file_eattr_reparse,
18355                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18356                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18357
18358         { &hf_smb_file_eattr_compressed,
18359                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18360                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18361
18362         { &hf_smb_file_eattr_offline,
18363                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18364                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18365
18366         { &hf_smb_file_eattr_not_content_indexed,
18367                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18368                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18369
18370         { &hf_smb_file_eattr_encrypted,
18371                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18372                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18373
18374         { &hf_smb_sec_desc_len,
18375                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18376                 NULL, 0, "Security Descriptor Length", HFILL }},
18377
18378         { &hf_smb_nt_qsd_owner,
18379                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18380                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18381
18382         { &hf_smb_nt_qsd_group,
18383                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18384                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18385
18386         { &hf_smb_nt_qsd_dacl,
18387                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18388                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18389
18390         { &hf_smb_nt_qsd_sacl,
18391                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18392                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18393
18394         { &hf_smb_extended_attributes,
18395                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18396                 NULL, 0, "Extended Attributes", HFILL }},
18397
18398         { &hf_smb_oplock_level,
18399                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18400                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18401
18402         { &hf_smb_create_action,
18403                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18404                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18405
18406         { &hf_smb_file_id,
18407                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18408                 NULL, 0, "Server unique file ID", HFILL }},
18409
18410         { &hf_smb_ea_error_offset,
18411                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18412                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18413
18414         { &hf_smb_end_of_file,
18415                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18416                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18417
18418         { &hf_smb_replace,
18419                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
18420                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
18421
18422         { &hf_smb_root_dir_handle,
18423                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
18424                 NULL, 0, "Root directory handle", HFILL }},
18425
18426         { &hf_smb_target_name_len,
18427                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
18428                 NULL, 0, "Length of target file name", HFILL }},
18429
18430         { &hf_smb_target_name,
18431                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
18432                 NULL, 0, "Target file name", HFILL }},
18433
18434         { &hf_smb_device_type,
18435                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18436                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18437
18438         { &hf_smb_is_directory,
18439                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18440                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18441
18442         { &hf_smb_next_entry_offset,
18443                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18444                 NULL, 0, "Offset to next entry", HFILL }},
18445
18446         { &hf_smb_change_time,
18447                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18448                 NULL, 0, "Last Change Time", HFILL }},
18449
18450         { &hf_smb_setup_len,
18451                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18452                 NULL, 0, "Length of printer setup data", HFILL }},
18453
18454         { &hf_smb_print_mode,
18455                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18456                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18457
18458         { &hf_smb_print_identifier,
18459                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18460                 NULL, 0, "Identifier string for this print job", HFILL }},
18461
18462         { &hf_smb_restart_index,
18463                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18464                 NULL, 0, "Index of entry after last returned", HFILL }},
18465
18466         { &hf_smb_print_queue_date,
18467                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18468                 NULL, 0, "Date when this entry was queued", HFILL }},
18469
18470         { &hf_smb_print_queue_dos_date,
18471                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18472                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18473
18474         { &hf_smb_print_queue_dos_time,
18475                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18476                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18477
18478         { &hf_smb_print_status,
18479                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18480                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18481
18482         { &hf_smb_print_spool_file_number,
18483                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18484                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18485
18486         { &hf_smb_print_spool_file_size,
18487                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18488                 NULL, 0, "Number of bytes in spool file", HFILL }},
18489
18490         { &hf_smb_print_spool_file_name,
18491                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
18492                 NULL, 0, "Name of client that submitted this job", HFILL }},
18493
18494         { &hf_smb_start_index,
18495                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18496                 NULL, 0, "First queue entry to return", HFILL }},
18497
18498         { &hf_smb_originator_name,
18499                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18500                 NULL, 0, "Name of sender of message", HFILL }},
18501
18502         { &hf_smb_destination_name,
18503                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18504                 NULL, 0, "Name of recipient of message", HFILL }},
18505
18506         { &hf_smb_message_len,
18507                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18508                 NULL, 0, "Length of message", HFILL }},
18509
18510         { &hf_smb_message,
18511                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18512                 NULL, 0, "Message text", HFILL }},
18513
18514         { &hf_smb_mgid,
18515                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18516                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18517
18518         { &hf_smb_forwarded_name,
18519                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18520                 NULL, 0, "Recipient name being forwarded", HFILL }},
18521
18522         { &hf_smb_machine_name,
18523                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18524                 NULL, 0, "Name of target machine", HFILL }},
18525
18526         { &hf_smb_cancel_to,
18527                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18528                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18529
18530         { &hf_smb_trans2_subcmd,
18531                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
18532                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
18533
18534         { &hf_smb_trans_name,
18535                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18536                 NULL, 0, "Name of transaction", HFILL }},
18537
18538         { &hf_smb_transaction_flags_dtid,
18539                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18540                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18541
18542         { &hf_smb_transaction_flags_owt,
18543                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18544                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18545
18546         { &hf_smb_search_count,
18547                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18548                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18549
18550         { &hf_smb_search_pattern,
18551                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18552                 NULL, 0, "Search Pattern", HFILL }},
18553
18554         { &hf_smb_ff2_backup,
18555                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18556                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18557
18558         { &hf_smb_ff2_continue,
18559                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18560                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18561
18562         { &hf_smb_ff2_resume,
18563                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18564                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18565
18566         { &hf_smb_ff2_close_eos,
18567                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18568                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18569
18570         { &hf_smb_ff2_close,
18571                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18572                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18573
18574         { &hf_smb_ff2_information_level,
18575                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18576                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18577
18578         { &hf_smb_qpi_loi,
18579                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18580                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18581
18582         { &hf_smb_spi_loi,
18583                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18584                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18585
18586 #if 0
18587         { &hf_smb_sfi_writetru,
18588                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18589                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18590
18591         { &hf_smb_sfi_caching,
18592                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18593                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18594 #endif
18595
18596         { &hf_smb_storage_type,
18597                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18598                 NULL, 0, "Type of storage", HFILL }},
18599
18600         { &hf_smb_resume,
18601                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18602                 NULL, 0, "Resume Key", HFILL }},
18603
18604         { &hf_smb_max_referral_level,
18605                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18606                 NULL, 0, "Latest referral version number understood", HFILL }},
18607
18608         { &hf_smb_qfsi_information_level,
18609                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
18610                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18611
18612         { &hf_smb_nt_rename_level,
18613                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18614                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18615
18616         { &hf_smb_cluster_count,
18617                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18618                 NULL, 0, "Number of clusters", HFILL }},
18619
18620         { &hf_smb_number_of_links,
18621                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18622                 NULL, 0, "Number of hard links to the file", HFILL }},
18623
18624         { &hf_smb_delete_pending,
18625                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18626                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18627
18628         { &hf_smb_index_number,
18629                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
18630                 NULL, 0, "File system unique identifier", HFILL }},
18631
18632         { &hf_smb_current_offset,
18633                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18634                 NULL, 0, "Current offset in the file", HFILL }},
18635
18636         { &hf_smb_t2_alignment,
18637                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18638                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18639
18640         { &hf_smb_t2_stream_name_length,
18641                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18642                 NULL, 0, "Length of stream name", HFILL }},
18643
18644         { &hf_smb_t2_stream_size,
18645                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18646                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18647
18648         { &hf_smb_t2_stream_name,
18649                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18650                 NULL, 0, "Name of the stream", HFILL }},
18651
18652         { &hf_smb_t2_compressed_file_size,
18653                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18654                 NULL, 0, "Size of the compressed file", HFILL }},
18655
18656         { &hf_smb_t2_compressed_format,
18657                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18658                 NULL, 0, "Compression algorithm used", HFILL }},
18659
18660         { &hf_smb_t2_compressed_unit_shift,
18661                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18662                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18663
18664         { &hf_smb_t2_compressed_chunk_shift,
18665                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18666                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18667
18668         { &hf_smb_t2_compressed_cluster_shift,
18669                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18670                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18671
18672         { &hf_smb_t2_marked_for_deletion,
18673                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18674                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18675
18676         { &hf_smb_dfs_path_consumed,
18677                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18678                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18679
18680         { &hf_smb_dfs_num_referrals,
18681                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18682                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18683
18684         { &hf_smb_get_dfs_server_hold_storage,
18685                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18686                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18687
18688         { &hf_smb_get_dfs_fielding,
18689                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18690                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18691
18692         { &hf_smb_dfs_referral_version,
18693                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18694                 NULL, 0, "Version of referral element", HFILL }},
18695
18696         { &hf_smb_dfs_referral_size,
18697                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18698                 NULL, 0, "Size of referral element", HFILL }},
18699
18700         { &hf_smb_dfs_referral_server_type,
18701                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18702                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18703
18704         { &hf_smb_dfs_referral_flags_strip,
18705                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18706                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18707
18708         { &hf_smb_dfs_referral_node_offset,
18709                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18710                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18711
18712         { &hf_smb_dfs_referral_node,
18713                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18714                 NULL, 0, "Name of entity to visit next", HFILL }},
18715
18716         { &hf_smb_dfs_referral_proximity,
18717                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18718                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18719
18720         { &hf_smb_dfs_referral_ttl,
18721                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18722                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18723
18724         { &hf_smb_dfs_referral_path_offset,
18725                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18726                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18727
18728         { &hf_smb_dfs_referral_path,
18729                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18730                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18731
18732         { &hf_smb_dfs_referral_alt_path_offset,
18733                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18734                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18735
18736         { &hf_smb_dfs_referral_alt_path,
18737                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18738                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18739
18740         { &hf_smb_end_of_search,
18741                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18742                 NULL, 0, "Was last entry returned?", HFILL }},
18743
18744         { &hf_smb_last_name_offset,
18745                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18746                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18747
18748         { &hf_smb_fn_information_level,
18749                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18750                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18751
18752         { &hf_smb_monitor_handle,
18753                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18754                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18755
18756         { &hf_smb_change_count,
18757                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18758                 NULL, 0, "Number of changes to wait for", HFILL }},
18759
18760         { &hf_smb_file_index,
18761                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18762                 NULL, 0, "File index", HFILL }},
18763
18764         { &hf_smb_short_file_name,
18765                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18766                 NULL, 0, "Short (8.3) File Name", HFILL }},
18767
18768         { &hf_smb_short_file_name_len,
18769                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18770                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18771
18772         { &hf_smb_fs_id,
18773                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18774                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18775
18776         { &hf_smb_fs_guid,
18777                 { "FS GUID", "smb.fs_guid", FT_STRING, BASE_NONE,
18778                 NULL, 0, "File System GUID", HFILL }},
18779
18780         { &hf_smb_sector_unit,
18781                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18782                 NULL, 0, "Sectors per allocation unit", HFILL }},
18783
18784         { &hf_smb_fs_units,
18785                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18786                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18787
18788         { &hf_smb_fs_sector,
18789                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18790                 NULL, 0, "Bytes per sector", HFILL }},
18791
18792         { &hf_smb_avail_units,
18793                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18794                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18795
18796         { &hf_smb_volume_serial_num,
18797                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18798                 NULL, 0, "Volume serial number", HFILL }},
18799
18800         { &hf_smb_volume_label_len,
18801                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18802                 NULL, 0, "Length of volume label", HFILL }},
18803
18804         { &hf_smb_volume_label,
18805                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18806                 NULL, 0, "Volume label", HFILL }},
18807
18808         { &hf_smb_free_alloc_units64,
18809                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18810                 NULL, 0, "Number of free allocation units", HFILL }},
18811
18812         { &hf_smb_caller_free_alloc_units64,
18813                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18814                 NULL, 0, "Number of caller free allocation units", HFILL }},
18815
18816         { &hf_smb_actual_free_alloc_units64,
18817                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18818                 NULL, 0, "Number of actual free allocation units", HFILL }},
18819
18820         { &hf_smb_soft_quota_limit,
18821                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18822                 NULL, 0, "Soft Quota treshold", HFILL }},
18823
18824         { &hf_smb_hard_quota_limit,
18825                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18826                 NULL, 0, "Hard Quota limit", HFILL }},
18827
18828         { &hf_smb_user_quota_used,
18829                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18830                 NULL, 0, "How much Quota is used by this user", HFILL }},
18831
18832         { &hf_smb_max_name_len,
18833                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18834                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18835
18836         { &hf_smb_fs_name_len,
18837                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18838                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18839
18840         { &hf_smb_fs_name,
18841                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18842                 NULL, 0, "Name of filesystem", HFILL }},
18843
18844         { &hf_smb_device_char_removable,
18845                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18846                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18847
18848         { &hf_smb_device_char_read_only,
18849                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18850                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18851
18852         { &hf_smb_device_char_floppy,
18853                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18854                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18855
18856         { &hf_smb_device_char_write_once,
18857                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18858                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18859
18860         { &hf_smb_device_char_remote,
18861                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18862                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18863
18864         { &hf_smb_device_char_mounted,
18865                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18866                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18867
18868         { &hf_smb_device_char_virtual,
18869                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18870                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18871
18872         { &hf_smb_fs_attr_css,
18873                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18874                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18875
18876         { &hf_smb_fs_attr_cpn,
18877                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18878                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18879
18880         { &hf_smb_fs_attr_pacls,
18881                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18882                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18883
18884         { &hf_smb_fs_attr_fc,
18885                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18886                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18887
18888         { &hf_smb_fs_attr_vq,
18889                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18890                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18891
18892         { &hf_smb_fs_attr_dim,
18893                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18894                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18895
18896         { &hf_smb_fs_attr_vic,
18897                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18898                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18899
18900         { &hf_smb_sec_desc_revision,
18901                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18902                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18903
18904         { &hf_smb_sid,
18905                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18906                 NULL, 0, "SID: Security Identifier", HFILL }},
18907
18908         { &hf_smb_sid_revision,
18909                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18910                 NULL, 0, "Version of SID structure", HFILL }},
18911
18912         { &hf_smb_sid_num_auth,
18913                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18914                 NULL, 0, "Number of authorities for this SID", HFILL }},
18915
18916         { &hf_smb_acl_revision,
18917                 { "Revision", "smb.acl.revision", FT_UINT8, BASE_DEC,
18918                 NULL, 0, "Version of NT ACL structure", HFILL }},
18919
18920         { &hf_smb_acl_size,
18921                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18922                 NULL, 0, "Size of NT ACL structure", HFILL }},
18923
18924         { &hf_smb_acl_num_aces,
18925                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18926                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18927
18928         { &hf_smb_user_quota_offset,
18929                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18930                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18931
18932         { &hf_smb_ace_type,
18933                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18934                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18935
18936         { &hf_smb_pipe_write_len,
18937                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18938                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18939
18940         { &hf_smb_ace_size,
18941                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18942                 NULL, 0, "Size of this ACE", HFILL }},
18943
18944         { &hf_smb_ace_flags_object_inherit,
18945                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18946                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18947
18948         { &hf_smb_ace_flags_container_inherit,
18949                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18950                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18951
18952         { &hf_smb_ace_flags_non_propagate_inherit,
18953                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18954                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18955
18956         { &hf_smb_ace_flags_inherit_only,
18957                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18958                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18959
18960         { &hf_smb_ace_flags_inherited_ace,
18961                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18962                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18963
18964         { &hf_smb_ace_flags_successful_access,
18965                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18966                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18967
18968         { &hf_smb_ace_flags_failed_access,
18969                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18970                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18971
18972         { &hf_smb_sec_desc_type_owner_defaulted,
18973                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18974                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18975
18976         { &hf_smb_sec_desc_type_group_defaulted,
18977                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18978                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18979
18980         { &hf_smb_sec_desc_type_dacl_present,
18981                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18982                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18983
18984         { &hf_smb_sec_desc_type_dacl_defaulted,
18985                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18986                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18987
18988         { &hf_smb_sec_desc_type_sacl_present,
18989                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18990                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18991
18992         { &hf_smb_sec_desc_type_sacl_defaulted,
18993                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18994                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18995
18996         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18997                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18998                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18999
19000         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
19001                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
19002                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
19003
19004         { &hf_smb_sec_desc_type_dacl_auto_inherited,
19005                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
19006                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
19007
19008         { &hf_smb_sec_desc_type_sacl_auto_inherited,
19009                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
19010                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
19011
19012         { &hf_smb_sec_desc_type_dacl_protected,
19013                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
19014                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
19015
19016         { &hf_smb_sec_desc_type_sacl_protected,
19017                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
19018                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
19019
19020         { &hf_smb_sec_desc_type_self_relative,
19021                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
19022                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
19023
19024         { &hf_smb_quota_flags_deny_disk,
19025                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
19026                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
19027
19028         { &hf_smb_quota_flags_log_limit,
19029                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
19030                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
19031
19032         { &hf_smb_quota_flags_log_warning,
19033                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
19034                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
19035
19036         { &hf_smb_quota_flags_enabled,
19037                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
19038                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
19039
19040         { &hf_smb_segment_overlap,
19041                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
19042                         "Fragment overlaps with other fragments", HFILL }},
19043
19044         { &hf_smb_segment_overlap_conflict,
19045                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
19046                         "Overlapping fragments contained conflicting data", HFILL }},
19047
19048         { &hf_smb_segment_multiple_tails,
19049                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
19050                         "Several tails were found when defragmenting the packet", HFILL }},
19051
19052         { &hf_smb_segment_too_long_fragment,
19053                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
19054                         "Fragment contained data past end of packet", HFILL }},
19055
19056         { &hf_smb_segment_error,
19057                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19058                         "Defragmentation error due to illegal fragments", HFILL }},
19059
19060         { &hf_smb_segment,
19061                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
19062                         "SMB Segment", HFILL }},
19063
19064         { &hf_smb_segments,
19065                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
19066                         "SMB Segments", HFILL }},
19067
19068         { &hf_smb_unix_major_version,
19069           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
19070             NULL, 0, "UNIX Major Version", HFILL }},
19071
19072         { &hf_smb_unix_minor_version,
19073           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
19074             NULL, 0, "UNIX Minor Version", HFILL }},
19075
19076         { &hf_smb_unix_capability_fcntl,
19077           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
19078                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
19079
19080         { &hf_smb_unix_capability_posix_acl,
19081           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
19082                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
19083
19084         { &hf_smb_unix_file_size,
19085           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
19086             NULL, 0, "", HFILL }},
19087
19088         { &hf_smb_unix_file_num_bytes,
19089           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
19090             NULL, 0, "Number of bytes used to store the file", HFILL }},
19091
19092         { &hf_smb_unix_file_last_status,
19093           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
19094             NULL, 0, "", HFILL }},
19095
19096         { &hf_smb_unix_file_last_access,
19097           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
19098             NULL, 0, "", HFILL }},
19099
19100         { &hf_smb_unix_file_last_change,
19101           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
19102             NULL, 0, "", HFILL }},
19103
19104         { &hf_smb_unix_file_uid,
19105           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
19106             NULL, 0, "", HFILL }},
19107
19108         { &hf_smb_unix_file_gid,
19109           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
19110             NULL, 0, "", HFILL }},
19111
19112         { &hf_smb_unix_file_type,
19113           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
19114             VALS(unix_file_type_vals), 0, "", HFILL }},
19115
19116         { &hf_smb_unix_file_dev_major,
19117           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
19118             NULL, 0, "", HFILL }},
19119
19120         { &hf_smb_unix_file_dev_minor,
19121           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
19122             NULL, 0, "", HFILL }},
19123
19124         { &hf_smb_unix_file_unique_id,
19125           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
19126             NULL, 0, "", HFILL }},
19127
19128         { &hf_smb_unix_file_permissions,
19129           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
19130             NULL, 0, "", HFILL }},
19131
19132         { &hf_smb_unix_file_nlinks,
19133           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
19134             NULL, 0, "", HFILL }},
19135
19136         { &hf_smb_unix_file_link_dest,
19137           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
19138             BASE_NONE, NULL, 0, "", HFILL }},
19139
19140         { &hf_smb_unix_find_file_nextoffset,
19141           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
19142             NULL, 0, "", HFILL }},
19143
19144         { &hf_smb_unix_find_file_resumekey,
19145           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
19146             NULL, 0, "", HFILL }},
19147
19148                 /* Access masks */
19149
19150                 { &hf_smb_access_mask,
19151                   { "Access required", "smb.access_mask",
19152                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
19153                     HFILL }},
19154                 { &hf_access_generic_read,
19155                   { "Generic read", "nt.access_mask.generic_read",
19156                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19157                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
19158
19159                 { &hf_access_generic_write,
19160                   { "Generic write", "nt.access_mask.generic_write",
19161                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19162                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
19163
19164                 { &hf_access_generic_execute,
19165                   { "Generic execute", "nt.access_mask.generic_execute",
19166                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19167                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
19168
19169                 { &hf_access_generic_all,
19170                   { "Generic all", "nt.access_mask.generic_all",
19171                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19172                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
19173
19174                 { &hf_access_maximum_allowed,
19175                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
19176                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19177                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
19178
19179                 { &hf_access_sacl,
19180                   { "Access SACL", "nt.access_mask.access_sacl",
19181                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19182                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
19183
19184                 { &hf_access_standard_read_control,
19185                   { "Read control", "nt.access_mask.read_control",
19186                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19187                     READ_CONTROL_ACCESS, "Read control", HFILL }},
19188
19189                 { &hf_access_standard_delete,
19190                   { "Delete", "nt.access_mask.delete",
19191                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19192                     DELETE_ACCESS, "Delete", HFILL }},
19193
19194                 { &hf_access_standard_synchronise,
19195                   { "Synchronise", "nt.access_mask.synchronise",
19196                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19197                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
19198
19199                 { &hf_access_standard_write_dac,
19200                   { "Write DAC", "nt.access_mask.write_dac",
19201                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19202                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
19203
19204                 { &hf_access_standard_write_owner,
19205                   { "Write owner", "nt.access_mask.write_owner",
19206                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19207                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
19208
19209                 { &hf_access_specific_15,
19210                   { "Specific access, bit 15", "nt.access_mask.specific_15",
19211                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19212                     0x8000, "Specific access, bit 15", HFILL }},
19213
19214                 { &hf_access_specific_14,
19215                   { "Specific access, bit 14", "nt.access_mask.specific_14",
19216                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19217                     0x4000, "Specific access, bit 14", HFILL }},
19218
19219                 { &hf_access_specific_13,
19220                   { "Specific access, bit 13", "nt.access_mask.specific_13",
19221                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19222                     0x2000, "Specific access, bit 13", HFILL }},
19223
19224                 { &hf_access_specific_12,
19225                   { "Specific access, bit 12", "nt.access_mask.specific_12",
19226                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19227                     0x1000, "Specific access, bit 12", HFILL }},
19228
19229                 { &hf_access_specific_11,
19230                   { "Specific access, bit 11", "nt.access_mask.specific_11",
19231                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19232                     0x0800, "Specific access, bit 11", HFILL }},
19233
19234                 { &hf_access_specific_10,
19235                   { "Specific access, bit 10", "nt.access_mask.specific_10",
19236                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19237                     0x0400, "Specific access, bit 10", HFILL }},
19238
19239                 { &hf_access_specific_9,
19240                   { "Specific access, bit 9", "nt.access_mask.specific_9",
19241                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19242                     0x0200, "Specific access, bit 9", HFILL }},
19243
19244                 { &hf_access_specific_8,
19245                   { "Specific access, bit 8", "nt.access_mask.specific_8",
19246                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19247                     0x0100, "Specific access, bit 8", HFILL }},
19248
19249                 { &hf_access_specific_7,
19250                   { "Specific access, bit 7", "nt.access_mask.specific_7",
19251                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19252                     0x0080, "Specific access, bit 7", HFILL }},
19253
19254                 { &hf_access_specific_6,
19255                   { "Specific access, bit 6", "nt.access_mask.specific_6",
19256                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19257                     0x0040, "Specific access, bit 6", HFILL }},
19258
19259                 { &hf_access_specific_5,
19260                   { "Specific access, bit 5", "nt.access_mask.specific_5",
19261                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19262                     0x0020, "Specific access, bit 5", HFILL }},
19263
19264                 { &hf_access_specific_4,
19265                   { "Specific access, bit 4", "nt.access_mask.specific_4",
19266                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19267                     0x0010, "Specific access, bit 4", HFILL }},
19268
19269                 { &hf_access_specific_3,
19270                   { "Specific access, bit 3", "nt.access_mask.specific_3",
19271                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19272                     0x0008, "Specific access, bit 3", HFILL }},
19273
19274                 { &hf_access_specific_2,
19275                   { "Specific access, bit 2", "nt.access_mask.specific_2",
19276                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19277                     0x0004, "Specific access, bit 2", HFILL }},
19278
19279                 { &hf_access_specific_1,
19280                   { "Specific access, bit 1", "nt.access_mask.specific_1",
19281                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19282                     0x0002, "Specific access, bit 1", HFILL }},
19283
19284                 { &hf_access_specific_0,
19285                   { "Specific access, bit 0", "nt.access_mask.specific_0",
19286                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19287                     0x0001, "Specific access, bit 0", HFILL }}
19288         };
19289
19290         static gint *ett[] = {
19291                 &ett_smb,
19292                 &ett_smb_hdr,
19293                 &ett_smb_command,
19294                 &ett_smb_fileattributes,
19295                 &ett_smb_capabilities,
19296                 &ett_smb_aflags,
19297                 &ett_smb_dialect,
19298                 &ett_smb_dialects,
19299                 &ett_smb_mode,
19300                 &ett_smb_rawmode,
19301                 &ett_smb_flags,
19302                 &ett_smb_flags2,
19303                 &ett_smb_desiredaccess,
19304                 &ett_smb_search,
19305                 &ett_smb_file,
19306                 &ett_smb_openfunction,
19307                 &ett_smb_filetype,
19308                 &ett_smb_openaction,
19309                 &ett_smb_writemode,
19310                 &ett_smb_lock_type,
19311                 &ett_smb_ssetupandxaction,
19312                 &ett_smb_optionsup,
19313                 &ett_smb_time_date,
19314                 &ett_smb_move_copy_flags,
19315                 &ett_smb_file_attributes,
19316                 &ett_smb_search_resume_key,
19317                 &ett_smb_search_dir_info,
19318                 &ett_smb_unlocks,
19319                 &ett_smb_unlock,
19320                 &ett_smb_locks,
19321                 &ett_smb_lock,
19322                 &ett_smb_open_flags,
19323                 &ett_smb_ipc_state,
19324                 &ett_smb_open_action,
19325                 &ett_smb_setup_action,
19326                 &ett_smb_connect_flags,
19327                 &ett_smb_connect_support_bits,
19328                 &ett_smb_nt_access_mask,
19329                 &ett_smb_nt_create_bits,
19330                 &ett_smb_nt_create_options,
19331                 &ett_smb_nt_share_access,
19332                 &ett_smb_nt_security_flags,
19333                 &ett_smb_nt_trans_setup,
19334                 &ett_smb_nt_trans_data,
19335                 &ett_smb_nt_trans_param,
19336                 &ett_smb_nt_notify_completion_filter,
19337                 &ett_smb_nt_ioctl_flags,
19338                 &ett_smb_security_information_mask,
19339                 &ett_smb_print_queue_entry,
19340                 &ett_smb_transaction_flags,
19341                 &ett_smb_transaction_params,
19342                 &ett_smb_find_first2_flags,
19343 #if 0
19344                 &ett_smb_ioflag,
19345 #endif
19346                 &ett_smb_transaction_data,
19347                 &ett_smb_stream_info,
19348                 &ett_smb_dfs_referrals,
19349                 &ett_smb_dfs_referral,
19350                 &ett_smb_dfs_referral_flags,
19351                 &ett_smb_get_dfs_flags,
19352                 &ett_smb_ff2_data,
19353                 &ett_smb_device_characteristics,
19354                 &ett_smb_fs_attributes,
19355                 &ett_smb_segments,
19356                 &ett_smb_segment,
19357                 &ett_smb_sec_desc,
19358                 &ett_smb_sid,
19359                 &ett_smb_acl,
19360                 &ett_smb_ace,
19361                 &ett_smb_ace_flags,
19362                 &ett_smb_sec_desc_type,
19363                 &ett_smb_quotaflags,
19364                 &ett_smb_secblob,
19365                 &ett_smb_mac_support_flags,
19366                 &ett_nt_access_mask,
19367                 &ett_nt_access_mask_generic,
19368                 &ett_nt_access_mask_standard,
19369                 &ett_nt_access_mask_specific,
19370                 &ett_smb_unicode_password,
19371                 &ett_smb_ea,
19372                 &ett_smb_unix_capabilities
19373         };
19374         module_t *smb_module;
19375
19376         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19377             "SMB", "smb");
19378         proto_register_subtree_array(ett, array_length(ett));
19379         proto_register_field_array(proto_smb, hf, array_length(hf));
19380
19381         register_smb_common(proto_smb);
19382
19383         register_init_routine(&smb_init_protocol);
19384         smb_module = prefs_register_protocol(proto_smb, NULL);
19385         prefs_register_bool_preference(smb_module, "trans_reassembly",
19386                 "Reassemble SMB Transaction payload",
19387                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19388                 &smb_trans_reassembly);
19389         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19390                 "Reassemble DCERPC over SMB",
19391                 "Whether the dissector should reassemble DCERPC over SMB commands",
19392                 &smb_dcerpc_reassembly);
19393         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19394                 "Snoop SID to Name mappings",
19395                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19396                 &sid_name_snooping);
19397
19398         register_init_routine(smb_trans_reassembly_init);
19399         smb_tap = register_tap("smb");
19400 }
19401
19402 void
19403 proto_reg_handoff_smb(void)
19404 {
19405         dissector_handle_t smb_handle;
19406
19407         gssapi_handle = find_dissector("gssapi");
19408         ntlmssp_handle = find_dissector("ntlmssp");
19409
19410         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19411         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19412         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19413         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19414         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19415         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19416         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19417             smb_handle);
19418 }