various string related changes, mainly replace sprintf/snprintf by g_snprintf
[obnox/wireshark/wip.git] / packet-smb.c
1 /* packet-smb.c
2  * Routines for smb packet dissection
3  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
4  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
5  *
6  * $Id: packet-smb.c,v 1.387 2004/03/01 08:34:34 sahlberg Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@ethereal.com>
10  * Copyright 1998 Gerald Combs
11  *
12  * Copied from packet-pop.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #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
2344                         /* guid */
2345                         /* XXX - show it in the standard Microsoft format
2346                            for GUIDs? */
2347                         CHECK_BYTE_COUNT(16);
2348                         proto_tree_add_item(tree, hf_smb_server_guid,
2349                                 tvb, offset, 16, TRUE);
2350                         COUNT_BYTES(16);
2351
2352                         blob_item = proto_tree_add_item(
2353                                 tree, hf_smb_security_blob,
2354                                 tvb, offset, bc, TRUE);
2355
2356                         /* security blob */
2357                         /* 
2358                          * If Extended security and BCC == 16, then raw 
2359                          * NTLMSSP is in use. We need to save this info
2360                          */
2361  
2362                         if(bc){
2363                                 tvbuff_t *gssapi_tvb;
2364                                 proto_tree *gssapi_tree;
2365
2366                                 gssapi_tree = proto_item_add_subtree(
2367                                         blob_item, ett_smb_secblob);
2368
2369                                 gssapi_tvb = tvb_new_subset(
2370                                         tvb, offset, bc, bc);
2371
2372                                 call_dissector(
2373                                         gssapi_handle, gssapi_tvb, pinfo,
2374                                         gssapi_tree);
2375
2376                                 if (si->ct)
2377                                   si->ct->raw_ntlmssp = 0;
2378
2379                                 COUNT_BYTES(bc);
2380                         }
2381                         else { 
2382
2383                           /*
2384                            * There is no blob. We just have to make sure
2385                            * that subsequent routines know to call the 
2386                            * right things ...
2387                            */
2388
2389                           if (si->ct)
2390                             si->ct->raw_ntlmssp = 1;
2391
2392                         }
2393                 }
2394                 break;
2395         }
2396
2397         END_OF_SMB
2398
2399         return offset;
2400 }
2401
2402
2403 static int
2404 dissect_old_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2405 {
2406         smb_info_t *si = pinfo->private_data;
2407         int dn_len;
2408         const char *dn;
2409         guint8 wc;
2410         guint16 bc;
2411
2412         WORD_COUNT;
2413
2414         BYTE_COUNT;
2415
2416         /* buffer format */
2417         CHECK_BYTE_COUNT(1);
2418         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2419         COUNT_BYTES(1);
2420
2421         /* dir name */
2422         dn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &dn_len,
2423                 FALSE, FALSE, &bc);
2424         if (dn == NULL)
2425                 goto endofcommand;
2426         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, dn_len,
2427                 dn);
2428         COUNT_BYTES(dn_len);
2429
2430         if (check_col(pinfo->cinfo, COL_INFO)) {
2431                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Directory: %s", dn);
2432         }
2433
2434         END_OF_SMB
2435
2436         return offset;
2437 }
2438
2439 static int
2440 dissect_empty(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2441 {
2442         guint8 wc;
2443         guint16 bc;
2444
2445         WORD_COUNT;
2446
2447         BYTE_COUNT;
2448
2449         END_OF_SMB
2450
2451         return offset;
2452 }
2453
2454 static int
2455 dissect_echo_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2456 {
2457         guint16 ec, bc;
2458         guint8 wc;
2459
2460         WORD_COUNT;
2461
2462         /* echo count */
2463         ec = tvb_get_letohs(tvb, offset);
2464         proto_tree_add_uint(tree, hf_smb_echo_count, tvb, offset, 2, ec);
2465         offset += 2;
2466
2467         BYTE_COUNT;
2468
2469         if (bc != 0) {
2470                 /* echo data */
2471                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2472                 COUNT_BYTES(bc);
2473         }
2474
2475         END_OF_SMB
2476
2477         return offset;
2478 }
2479
2480 static int
2481 dissect_echo_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2482 {
2483         guint16 bc;
2484         guint8 wc;
2485
2486         WORD_COUNT;
2487
2488         /* echo sequence number */
2489         proto_tree_add_item(tree, hf_smb_echo_seq_num, tvb, offset, 2, TRUE);
2490         offset += 2;
2491
2492         BYTE_COUNT;
2493
2494         if (bc != 0) {
2495                 /* echo data */
2496                 proto_tree_add_item(tree, hf_smb_echo_data, tvb, offset, bc, TRUE);
2497                 COUNT_BYTES(bc);
2498         }
2499
2500         END_OF_SMB
2501
2502         return offset;
2503 }
2504
2505 static int
2506 dissect_tree_connect_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2507 {
2508         smb_info_t *si = pinfo->private_data;
2509         int an_len, pwlen;
2510         const char *an;
2511         guint8 wc;
2512         guint16 bc;
2513
2514         WORD_COUNT;
2515
2516         BYTE_COUNT;
2517
2518         /* buffer format */
2519         CHECK_BYTE_COUNT(1);
2520         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2521         COUNT_BYTES(1);
2522
2523         /* Path */
2524         an = get_unicode_or_ascii_string(tvb, &offset,
2525                 si->unicode, &an_len, FALSE, FALSE, &bc);
2526         if (an == NULL)
2527                 goto endofcommand;
2528         proto_tree_add_string(tree, hf_smb_path, tvb,
2529                 offset, an_len, an);
2530         COUNT_BYTES(an_len);
2531
2532         if (check_col(pinfo->cinfo, COL_INFO)) {
2533                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
2534         }
2535
2536         /* buffer format */
2537         CHECK_BYTE_COUNT(1);
2538         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2539         COUNT_BYTES(1);
2540
2541         /* password, ANSI */
2542         /* XXX - what if this runs past bc? */
2543         pwlen = tvb_strsize(tvb, offset);
2544         CHECK_BYTE_COUNT(pwlen);
2545         proto_tree_add_item(tree, hf_smb_password,
2546                 tvb, offset, pwlen, TRUE);
2547         COUNT_BYTES(pwlen);
2548
2549         /* buffer format */
2550         CHECK_BYTE_COUNT(1);
2551         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2552         COUNT_BYTES(1);
2553
2554         /* Service */
2555         an = get_unicode_or_ascii_string(tvb, &offset,
2556                 si->unicode, &an_len, FALSE, FALSE, &bc);
2557         if (an == NULL)
2558                 goto endofcommand;
2559         proto_tree_add_string(tree, hf_smb_service, tvb,
2560                 offset, an_len, an);
2561         COUNT_BYTES(an_len);
2562
2563         END_OF_SMB
2564
2565         return offset;
2566 }
2567
2568 static int
2569 dissect_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2570 {
2571         guint8 wc;
2572         guint16 bc;
2573
2574         WORD_COUNT;
2575
2576         /* Maximum Buffer Size */
2577         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
2578         offset += 2;
2579
2580         /* tid */
2581         proto_tree_add_item(tree, hf_smb_tid, tvb, offset, 2, TRUE);
2582         offset += 2;
2583
2584         BYTE_COUNT;
2585
2586         END_OF_SMB
2587
2588         return offset;
2589 }
2590
2591
2592 static const true_false_string tfs_of_create = {
2593         "Create file if it does not exist",
2594         "Fail if file does not exist"
2595 };
2596 static const value_string of_open[] = {
2597         { 0,            "Fail if file exists"},
2598         { 1,            "Open file if it exists"},
2599         { 2,            "Truncate file if it exists"},
2600         {0, NULL}
2601 };
2602 static int
2603 dissect_open_function(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2604 {
2605         guint16 mask;
2606         proto_item *item = NULL;
2607         proto_tree *tree = NULL;
2608
2609         mask = tvb_get_letohs(tvb, offset);
2610
2611         if(parent_tree){
2612                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2613                         "Open Function: 0x%04x", mask);
2614                 tree = proto_item_add_subtree(item, ett_smb_openfunction);
2615         }
2616
2617         proto_tree_add_boolean(tree, hf_smb_open_function_create,
2618                 tvb, offset, 2, mask);
2619         proto_tree_add_uint(tree, hf_smb_open_function_open,
2620                 tvb, offset, 2, mask);
2621
2622         offset += 2;
2623
2624         return offset;
2625 }
2626
2627
2628 static const true_false_string tfs_mf_file = {
2629         "Target must be a file",
2630         "Target needn't be a file"
2631 };
2632 static const true_false_string tfs_mf_dir = {
2633         "Target must be a directory",
2634         "Target needn't be a directory"
2635 };
2636 static const true_false_string tfs_mf_verify = {
2637         "MUST verify all writes",
2638         "Don't have to verify writes"
2639 };
2640 static int
2641 dissect_move_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2642 {
2643         guint16 mask;
2644         proto_item *item = NULL;
2645         proto_tree *tree = NULL;
2646
2647         mask = tvb_get_letohs(tvb, offset);
2648
2649         if(parent_tree){
2650                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2651                         "Flags: 0x%04x", mask);
2652                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2653         }
2654
2655         proto_tree_add_boolean(tree, hf_smb_move_flags_verify,
2656                 tvb, offset, 2, mask);
2657         proto_tree_add_boolean(tree, hf_smb_move_flags_dir,
2658                 tvb, offset, 2, mask);
2659         proto_tree_add_boolean(tree, hf_smb_move_flags_file,
2660                 tvb, offset, 2, mask);
2661
2662         offset += 2;
2663
2664         return offset;
2665 }
2666
2667 static const true_false_string tfs_cf_mode = {
2668         "ASCII",
2669         "Binary"
2670 };
2671 static const true_false_string tfs_cf_tree_copy = {
2672         "Copy is a tree copy",
2673         "Copy is a file copy"
2674 };
2675 static const true_false_string tfs_cf_ea_action = {
2676         "Fail copy",
2677         "Discard EAs"
2678 };
2679 static int
2680 dissect_copy_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
2681 {
2682         guint16 mask;
2683         proto_item *item = NULL;
2684         proto_tree *tree = NULL;
2685
2686         mask = tvb_get_letohs(tvb, offset);
2687
2688         if(parent_tree){
2689                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
2690                         "Flags: 0x%04x", mask);
2691                 tree = proto_item_add_subtree(item, ett_smb_move_copy_flags);
2692         }
2693
2694         proto_tree_add_boolean(tree, hf_smb_copy_flags_ea_action,
2695                 tvb, offset, 2, mask);
2696         proto_tree_add_boolean(tree, hf_smb_copy_flags_tree_copy,
2697                 tvb, offset, 2, mask);
2698         proto_tree_add_boolean(tree, hf_smb_copy_flags_verify,
2699                 tvb, offset, 2, mask);
2700         proto_tree_add_boolean(tree, hf_smb_copy_flags_source_mode,
2701                 tvb, offset, 2, mask);
2702         proto_tree_add_boolean(tree, hf_smb_copy_flags_dest_mode,
2703                 tvb, offset, 2, mask);
2704         proto_tree_add_boolean(tree, hf_smb_copy_flags_dir,
2705                 tvb, offset, 2, mask);
2706         proto_tree_add_boolean(tree, hf_smb_copy_flags_file,
2707                 tvb, offset, 2, mask);
2708
2709         offset += 2;
2710
2711         return offset;
2712 }
2713
2714 static int
2715 dissect_move_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2716 {
2717         smb_info_t *si = pinfo->private_data;
2718         int fn_len;
2719         guint16 tid;
2720         guint16 bc;
2721         guint8 wc;
2722         const char *fn;
2723
2724         WORD_COUNT;
2725
2726         /* tid */
2727         tid = tvb_get_letohs(tvb, offset);
2728         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2729                 "TID (target): 0x%04x", tid);
2730         offset += 2;
2731
2732         /* open function */
2733         offset = dissect_open_function(tvb, tree, offset);
2734
2735         /* move flags */
2736         offset = dissect_move_flags(tvb, tree, offset);
2737
2738         BYTE_COUNT;
2739
2740         /* buffer format */
2741         CHECK_BYTE_COUNT(1);
2742         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2743         COUNT_BYTES(1);
2744
2745         /* file name */
2746         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2747                 FALSE, FALSE, &bc);
2748         if (fn == NULL)
2749                 goto endofcommand;
2750         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2751                 fn_len, fn, "Old File Name: %s", fn);
2752         COUNT_BYTES(fn_len);
2753
2754         if (check_col(pinfo->cinfo, COL_INFO)) {
2755                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
2756         }
2757
2758         /* buffer format */
2759         CHECK_BYTE_COUNT(1);
2760         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2761         COUNT_BYTES(1);
2762
2763         /* file name */
2764         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2765                 FALSE, FALSE, &bc);
2766         if (fn == NULL)
2767                 goto endofcommand;
2768         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2769                 fn_len, fn, "New File Name: %s", fn);
2770         COUNT_BYTES(fn_len);
2771
2772         if (check_col(pinfo->cinfo, COL_INFO)) {
2773                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
2774         }
2775
2776         END_OF_SMB
2777
2778         return offset;
2779 }
2780
2781 static int
2782 dissect_copy_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2783 {
2784         smb_info_t *si = pinfo->private_data;
2785         int fn_len;
2786         guint16 tid;
2787         guint16 bc;
2788         guint8 wc;
2789         const char *fn;
2790
2791         WORD_COUNT;
2792
2793         /* tid */
2794         tid = tvb_get_letohs(tvb, offset);
2795         proto_tree_add_uint_format(tree, hf_smb_tid, tvb, offset, 2, tid,
2796                 "TID (target): 0x%04x", tid);
2797         offset += 2;
2798
2799         /* open function */
2800         offset = dissect_open_function(tvb, tree, offset);
2801
2802         /* copy flags */
2803         offset = dissect_copy_flags(tvb, tree, offset);
2804
2805         BYTE_COUNT;
2806
2807         /* buffer format */
2808         CHECK_BYTE_COUNT(1);
2809         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2810         COUNT_BYTES(1);
2811
2812         /* file name */
2813         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2814                 FALSE, FALSE, &bc);
2815         if (fn == NULL)
2816                 goto endofcommand;
2817         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2818                 fn_len, fn, "Source File Name: %s", fn);
2819         COUNT_BYTES(fn_len);
2820
2821         if (check_col(pinfo->cinfo, COL_INFO)) {
2822                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Source Name: %s", fn);
2823         }
2824
2825         /* buffer format */
2826         CHECK_BYTE_COUNT(1);
2827         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2828         COUNT_BYTES(1);
2829
2830         /* file name */
2831         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2832                 FALSE, FALSE, &bc);
2833         if (fn == NULL)
2834                 goto endofcommand;
2835         proto_tree_add_string_format(tree, hf_smb_file_name, tvb, offset,
2836                 fn_len, fn, "Destination File Name: %s", fn);
2837         COUNT_BYTES(fn_len);
2838
2839         if (check_col(pinfo->cinfo, COL_INFO)) {
2840                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Destination Name: %s", fn);
2841         }
2842
2843         END_OF_SMB
2844
2845         return offset;
2846 }
2847
2848 static int
2849 dissect_move_copy_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2850 {
2851         smb_info_t *si = pinfo->private_data;
2852         int fn_len;
2853         const char *fn;
2854         guint8 wc;
2855         guint16 bc;
2856
2857         WORD_COUNT;
2858
2859         /* # of files moved */
2860         proto_tree_add_item(tree, hf_smb_files_moved, tvb, offset, 2, TRUE);
2861         offset += 2;
2862
2863         BYTE_COUNT;
2864
2865         /* buffer format */
2866         CHECK_BYTE_COUNT(1);
2867         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2868         COUNT_BYTES(1);
2869
2870         /* file name */
2871         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2872                 FALSE, FALSE, &bc);
2873         if (fn == NULL)
2874                 goto endofcommand;
2875         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2876                 fn);
2877         COUNT_BYTES(fn_len);
2878
2879         END_OF_SMB
2880
2881         return offset;
2882 }
2883
2884 static int
2885 dissect_open_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2886 {
2887         smb_info_t *si = pinfo->private_data;
2888         int fn_len;
2889         const char *fn;
2890         guint8 wc;
2891         guint16 bc;
2892
2893         WORD_COUNT;
2894
2895         /* desired access */
2896         offset = dissect_access(tvb, tree, offset, "Desired");
2897
2898         /* Search Attributes */
2899         offset = dissect_search_attributes(tvb, tree, offset);
2900
2901         BYTE_COUNT;
2902
2903         /* buffer format */
2904         CHECK_BYTE_COUNT(1);
2905         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
2906         COUNT_BYTES(1);
2907
2908         /* file name */
2909         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
2910                 FALSE, FALSE, &bc);
2911         if (fn == NULL)
2912                 goto endofcommand;
2913         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
2914                 fn);
2915         COUNT_BYTES(fn_len);
2916
2917         if (check_col(pinfo->cinfo, COL_INFO)) {
2918                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
2919         }
2920
2921         END_OF_SMB
2922
2923         return offset;
2924 }
2925
2926 void
2927 add_fid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
2928     int len, guint16 fid)
2929 {
2930         proto_tree_add_uint(tree, hf_smb_fid, tvb, offset, len, fid);
2931         if (check_col(pinfo->cinfo, COL_INFO))
2932                 col_append_fstr(pinfo->cinfo, COL_INFO, ", FID: 0x%04x", fid);
2933 }
2934
2935 static int
2936 dissect_open_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2937 {
2938         guint8 wc;
2939         guint16 bc;
2940         guint16 fid;
2941
2942         WORD_COUNT;
2943
2944         /* fid */
2945         fid = tvb_get_letohs(tvb, offset);
2946         add_fid(tvb, pinfo, tree, offset, 2, fid);
2947         offset += 2;
2948
2949         /* File Attributes */
2950         offset = dissect_file_attributes(tvb, tree, offset, 2);
2951
2952         /* last write time */
2953         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
2954
2955         /* File Size */
2956         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
2957         offset += 4;
2958
2959         /* granted access */
2960         offset = dissect_access(tvb, tree, offset, "Granted");
2961
2962         BYTE_COUNT;
2963
2964         END_OF_SMB
2965
2966         return offset;
2967 }
2968
2969 static int
2970 dissect_fid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2971 {
2972         guint8 wc;
2973         guint16 bc;
2974         guint16 fid;
2975
2976         WORD_COUNT;
2977
2978         /* fid */
2979         fid = tvb_get_letohs(tvb, offset);
2980         add_fid(tvb, pinfo, tree, offset, 2, fid);
2981         offset += 2;
2982
2983         BYTE_COUNT;
2984
2985         END_OF_SMB
2986
2987         return offset;
2988 }
2989
2990 static int
2991 dissect_create_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
2992 {
2993         smb_info_t *si = pinfo->private_data;
2994         int fn_len;
2995         const char *fn;
2996         guint8 wc;
2997         guint16 bc;
2998
2999         WORD_COUNT;
3000
3001         /* file attributes */
3002         offset = dissect_file_attributes(tvb, tree, offset, 2);
3003
3004         /* creation time */
3005         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3006
3007         BYTE_COUNT;
3008
3009         /* buffer format */
3010         CHECK_BYTE_COUNT(1);
3011         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3012         COUNT_BYTES(1);
3013
3014         /* File Name */
3015         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3016                 FALSE, FALSE, &bc);
3017         if (fn == NULL)
3018                 goto endofcommand;
3019         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3020                 fn);
3021         COUNT_BYTES(fn_len);
3022
3023         if (check_col(pinfo->cinfo, COL_INFO)) {
3024                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3025         }
3026
3027         END_OF_SMB
3028
3029         return offset;
3030 }
3031
3032 static int
3033 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3034 {
3035         guint8 wc;
3036         guint16 bc, fid;
3037
3038         WORD_COUNT;
3039
3040         /* fid */
3041         fid = tvb_get_letohs(tvb, offset);
3042         add_fid(tvb, pinfo, tree, offset, 2, fid);
3043         offset += 2;
3044
3045         /* last write time */
3046         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3047
3048         BYTE_COUNT;
3049
3050         END_OF_SMB
3051
3052         return offset;
3053 }
3054
3055 static int
3056 dissect_delete_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3057 {
3058         smb_info_t *si = pinfo->private_data;
3059         int fn_len;
3060         const char *fn;
3061         guint8 wc;
3062         guint16 bc;
3063
3064         WORD_COUNT;
3065
3066         /* search attributes */
3067         offset = dissect_search_attributes(tvb, tree, offset);
3068
3069         BYTE_COUNT;
3070
3071         /* buffer format */
3072         CHECK_BYTE_COUNT(1);
3073         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3074         COUNT_BYTES(1);
3075
3076         /* file name */
3077         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3078                 FALSE, FALSE, &bc);
3079         if (fn == NULL)
3080                 goto endofcommand;
3081         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3082                 fn);
3083         COUNT_BYTES(fn_len);
3084
3085         if (check_col(pinfo->cinfo, COL_INFO)) {
3086                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3087         }
3088
3089         END_OF_SMB
3090
3091         return offset;
3092 }
3093
3094 static int
3095 dissect_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3096 {
3097         smb_info_t *si = pinfo->private_data;
3098         int fn_len;
3099         const char *fn;
3100         guint8 wc;
3101         guint16 bc;
3102
3103         WORD_COUNT;
3104
3105         /* search attributes */
3106         offset = dissect_search_attributes(tvb, tree, offset);
3107
3108         BYTE_COUNT;
3109
3110         /* buffer format */
3111         CHECK_BYTE_COUNT(1);
3112         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3113         COUNT_BYTES(1);
3114
3115         /* old file name */
3116         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3117                 FALSE, FALSE, &bc);
3118         if (fn == NULL)
3119                 goto endofcommand;
3120         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3121                 fn);
3122         COUNT_BYTES(fn_len);
3123
3124         if (check_col(pinfo->cinfo, COL_INFO)) {
3125                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3126         }
3127
3128         /* buffer format */
3129         CHECK_BYTE_COUNT(1);
3130         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3131         COUNT_BYTES(1);
3132
3133         /* file name */
3134         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3135                 FALSE, FALSE, &bc);
3136         if (fn == NULL)
3137                 goto endofcommand;
3138         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3139                 fn);
3140         COUNT_BYTES(fn_len);
3141
3142         if (check_col(pinfo->cinfo, COL_INFO)) {
3143                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3144         }
3145
3146         END_OF_SMB
3147
3148         return offset;
3149 }
3150
3151 static int
3152 dissect_nt_rename_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3153 {
3154         smb_info_t *si = pinfo->private_data;
3155         int fn_len;
3156         const char *fn;
3157         guint8 wc;
3158         guint16 bc;
3159
3160         WORD_COUNT;
3161
3162         /* search attributes */
3163         offset = dissect_search_attributes(tvb, tree, offset);
3164
3165         proto_tree_add_uint(tree, hf_smb_nt_rename_level, tvb, offset, 2, tvb_get_letohs(tvb, offset));
3166         offset += 2;
3167
3168         proto_tree_add_item(tree, hf_smb_cluster_count, tvb, offset, 4, TRUE);
3169         offset += 4;
3170
3171         BYTE_COUNT;
3172
3173         /* buffer format */
3174         CHECK_BYTE_COUNT(1);
3175         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3176         COUNT_BYTES(1);
3177
3178         /* old file name */
3179         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3180                 FALSE, FALSE, &bc);
3181         if (fn == NULL)
3182                 goto endofcommand;
3183         proto_tree_add_string(tree, hf_smb_old_file_name, tvb, offset, fn_len,
3184                 fn);
3185         COUNT_BYTES(fn_len);
3186
3187         if (check_col(pinfo->cinfo, COL_INFO)) {
3188                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Old Name: %s", fn);
3189         }
3190
3191         /* buffer format */
3192         CHECK_BYTE_COUNT(1);
3193         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3194         COUNT_BYTES(1);
3195
3196         /* file name */
3197         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3198                 FALSE, FALSE, &bc);
3199         if (fn == NULL)
3200                 goto endofcommand;
3201         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3202                 fn);
3203         COUNT_BYTES(fn_len);
3204
3205         if (check_col(pinfo->cinfo, COL_INFO)) {
3206                 col_append_fstr(pinfo->cinfo, COL_INFO, ", New Name: %s", fn);
3207         }
3208
3209         END_OF_SMB
3210
3211         return offset;
3212 }
3213
3214
3215 static int
3216 dissect_query_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3217 {
3218         smb_info_t *si = pinfo->private_data;
3219         guint16 bc;
3220         guint8 wc;
3221         const char *fn;
3222         int fn_len;
3223
3224         WORD_COUNT;
3225
3226         BYTE_COUNT;
3227
3228         /* Buffer Format */
3229         CHECK_BYTE_COUNT(1);
3230         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3231         COUNT_BYTES(1);
3232
3233         /* File Name */
3234         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3235                 FALSE, FALSE, &bc);
3236         if (fn == NULL)
3237                 goto endofcommand;
3238         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3239                 fn);
3240         COUNT_BYTES(fn_len);
3241
3242         if (check_col(pinfo->cinfo, COL_INFO)) {
3243                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3244         }
3245
3246         END_OF_SMB
3247
3248         return offset;
3249 }
3250
3251 static int
3252 dissect_query_information_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3253 {
3254         guint16 bc;
3255         guint8 wc;
3256
3257         WORD_COUNT;
3258
3259         /* File Attributes */
3260         offset = dissect_file_attributes(tvb, tree, offset, 2);
3261
3262         /* Last Write Time */
3263         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3264
3265         /* File Size */
3266         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
3267         offset += 4;
3268
3269         /* 10 reserved bytes */
3270         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3271         offset += 10;
3272
3273         BYTE_COUNT;
3274
3275         END_OF_SMB
3276
3277         return offset;
3278 }
3279
3280 static int
3281 dissect_set_information_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3282 {
3283         smb_info_t *si = pinfo->private_data;
3284         int fn_len;
3285         const char *fn;
3286         guint8 wc;
3287         guint16 bc;
3288
3289         WORD_COUNT;
3290
3291         /* file attributes */
3292         offset = dissect_file_attributes(tvb, tree, offset, 2);
3293
3294         /* last write time */
3295         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3296
3297         /* 10 reserved bytes */
3298         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
3299         offset += 10;
3300
3301         BYTE_COUNT;
3302
3303         /* buffer format */
3304         CHECK_BYTE_COUNT(1);
3305         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3306         COUNT_BYTES(1);
3307
3308         /* file name */
3309         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3310                 FALSE, FALSE, &bc);
3311         if (fn == NULL)
3312                 goto endofcommand;
3313         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3314                 fn);
3315         COUNT_BYTES(fn_len);
3316
3317         if (check_col(pinfo->cinfo, COL_INFO)) {
3318                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3319         }
3320
3321         END_OF_SMB
3322
3323         return offset;
3324 }
3325
3326 static int
3327 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3328 {
3329         guint8 wc;
3330         guint16 cnt=0, bc;
3331         guint32 ofs=0;
3332         smb_info_t *si;
3333         unsigned int fid;
3334
3335         WORD_COUNT;
3336
3337         /* fid */
3338         fid = tvb_get_letohs(tvb, offset);
3339         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
3340         offset += 2;
3341         if (!pinfo->fd->flags.visited) {
3342                 /* remember the FID for the processing of the response */
3343                 si = (smb_info_t *)pinfo->private_data;
3344                 si->sip->extra_info=(void *)fid;
3345         }
3346
3347         /* read count */
3348         cnt = tvb_get_letohs(tvb, offset);
3349         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3350         offset += 2;
3351
3352         /* offset */
3353         ofs = tvb_get_letohl(tvb, offset);
3354         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3355         offset += 4;
3356
3357         if (check_col(pinfo->cinfo, COL_INFO))
3358                 col_append_fstr(pinfo->cinfo, COL_INFO,
3359                                 ", %u byte%s at offset %u", cnt,
3360                                 (cnt == 1) ? "" : "s", ofs);
3361
3362         /* remaining */
3363         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3364         offset += 2;
3365
3366         BYTE_COUNT;
3367
3368         END_OF_SMB
3369
3370         return offset;
3371 }
3372
3373 int
3374 dissect_file_data(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 bc, guint16 datalen)
3375 {
3376         int tvblen;
3377
3378         if(bc>datalen){
3379                 /* We have some initial padding bytes. */
3380                 /* XXX - use the data offset here instead? */
3381                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3382                         TRUE);
3383                 offset += bc-datalen;
3384                 bc = datalen;
3385         }
3386         tvblen = tvb_length_remaining(tvb, offset);
3387         if(bc>tvblen){
3388                 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);
3389                 offset += tvblen;
3390         } else {
3391                 proto_tree_add_item(tree, hf_smb_file_data, tvb, offset, bc, TRUE);
3392                 offset += bc;
3393         }
3394         return offset;
3395 }
3396
3397 static int
3398 dissect_file_data_dcerpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3399     proto_tree *top_tree, int offset, guint16 bc, guint16 datalen, guint16 fid)
3400 {
3401         int tvblen;
3402         tvbuff_t *dcerpc_tvb;
3403
3404         if(bc>datalen){
3405                 /* We have some initial padding bytes. */
3406                 /* XXX - use the data offset here instead? */
3407                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, bc-datalen,
3408                         TRUE);
3409                 offset += bc-datalen;
3410                 bc = datalen;
3411         }
3412         tvblen = tvb_length_remaining(tvb, offset);
3413         dcerpc_tvb = tvb_new_subset(tvb, offset, tvblen, bc);
3414         dissect_pipe_dcerpc(dcerpc_tvb, pinfo, top_tree, tree, fid);
3415         if(bc>tvblen)
3416                 offset += tvblen;
3417         else
3418                 offset += bc;
3419         return offset;
3420 }
3421
3422 /*
3423  * transporting DCERPC over SMB seems to be implemented in various
3424  * ways. We might just assume it can be done by an almost random
3425  * mix of Trans/Read/Write calls
3426  *
3427  * if we suspect dcerpc, just send them all down to packet-smb-pipe.c
3428  * and let him sort them out
3429  */
3430 static int
3431 dissect_file_data_maybe_dcerpc(tvbuff_t *tvb, packet_info *pinfo,
3432     proto_tree *tree, proto_tree *top_tree, int offset, guint16 bc,
3433     guint16 datalen, guint32 ofs, guint16 fid)
3434 {
3435         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3436
3437         if( (si->sip && si->sip->flags&SMB_SIF_TID_IS_IPC) && (ofs==0) ){
3438                 /* dcerpc call */
3439                 return dissect_file_data_dcerpc(tvb, pinfo, tree,
3440                     top_tree, offset, bc, datalen, fid);
3441         } else {
3442                 /* ordinary file data */
3443                 return dissect_file_data(tvb, tree, offset, bc, datalen);
3444         }
3445 }
3446
3447 static int
3448 dissect_read_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3449 {
3450         guint16 cnt=0, bc;
3451         guint8 wc;
3452         smb_info_t *si = (smb_info_t *)pinfo->private_data;
3453         int fid=0;
3454
3455         WORD_COUNT;
3456
3457         /* read count */
3458         cnt = tvb_get_letohs(tvb, offset);
3459         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3460         offset += 2;
3461
3462         /* 8 reserved bytes */
3463         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3464         offset += 8;
3465
3466         /* If we have seen the request, then print which FID this refers to */
3467         /* first check if we have seen the request */
3468         if(si->sip != NULL && si->sip->frame_req>0){
3469                 fid=(int)si->sip->extra_info;
3470                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) fid);
3471         }
3472
3473         BYTE_COUNT;
3474
3475         /* buffer format */
3476         CHECK_BYTE_COUNT(1);
3477         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3478         COUNT_BYTES(1);
3479
3480         /* data len */
3481         CHECK_BYTE_COUNT(2);
3482         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3483         COUNT_BYTES(2);
3484
3485         /* file data, might be DCERPC on a pipe */
3486         if(bc){
3487                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3488                     top_tree, offset, bc, bc, 0, (guint16) fid);
3489                 bc = 0;
3490         }
3491
3492         END_OF_SMB
3493
3494         return offset;
3495 }
3496
3497 static int
3498 dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3499 {
3500         guint16 cnt, bc;
3501         guint8 wc;
3502
3503         WORD_COUNT;
3504
3505         /* read count */
3506         cnt = tvb_get_letohs(tvb, offset);
3507         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3508         offset += 2;
3509
3510         /* 8 reserved bytes */
3511         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
3512         offset += 8;
3513
3514         BYTE_COUNT;
3515
3516         /* buffer format */
3517         CHECK_BYTE_COUNT(1);
3518         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3519         COUNT_BYTES(1);
3520
3521         /* data len */
3522         CHECK_BYTE_COUNT(2);
3523         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3524         COUNT_BYTES(2);
3525
3526         END_OF_SMB
3527
3528         return offset;
3529 }
3530
3531
3532 static int
3533 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3534 {
3535         guint32 ofs=0;
3536         guint16 cnt=0, bc, fid=0;
3537         guint8 wc;
3538
3539         WORD_COUNT;
3540
3541         /* fid */
3542         fid = tvb_get_letohs(tvb, offset);
3543         add_fid(tvb, pinfo, tree, offset, 2, fid);
3544         offset += 2;
3545
3546         /* write count */
3547         cnt = tvb_get_letohs(tvb, offset);
3548         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3549         offset += 2;
3550
3551         /* offset */
3552         ofs = tvb_get_letohl(tvb, offset);
3553         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3554         offset += 4;
3555
3556         if (check_col(pinfo->cinfo, COL_INFO))
3557                 col_append_fstr(pinfo->cinfo, COL_INFO,
3558                                 ", %u byte%s at offset %u", cnt,
3559                                 (cnt == 1) ? "" : "s", ofs);
3560
3561         /* remaining */
3562         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
3563         offset += 2;
3564
3565         BYTE_COUNT;
3566
3567         /* buffer format */
3568         CHECK_BYTE_COUNT(1);
3569         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3570         COUNT_BYTES(1);
3571
3572         /* data len */
3573         CHECK_BYTE_COUNT(2);
3574         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
3575         COUNT_BYTES(2);
3576
3577         /* file data, might be DCERPC on a pipe */
3578         if (bc != 0) {
3579                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
3580                     top_tree, offset, bc, bc, ofs, fid);
3581                 bc = 0;
3582         }
3583
3584         END_OF_SMB
3585
3586         return offset;
3587 }
3588
3589 static int
3590 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3591 {
3592         guint8 wc;
3593         guint16 bc, cnt;
3594
3595         WORD_COUNT;
3596
3597         /* write count */
3598         cnt = tvb_get_letohs(tvb, offset);
3599         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3600         offset += 2;
3601
3602         if (check_col(pinfo->cinfo, COL_INFO))
3603                 col_append_fstr(pinfo->cinfo, COL_INFO,
3604                                 ", %u byte%s", cnt, (cnt == 1) ? "" : "s");
3605
3606         BYTE_COUNT;
3607
3608         END_OF_SMB
3609
3610         return offset;
3611 }
3612
3613 static int
3614 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3615 {
3616         guint8 wc;
3617         guint16 bc, fid;
3618
3619         WORD_COUNT;
3620
3621         /* fid */
3622         fid = tvb_get_letohs(tvb, offset);
3623         add_fid(tvb, pinfo, tree, offset, 2, fid);
3624         offset += 2;
3625
3626         /* lock count */
3627         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 4, TRUE);
3628         offset += 4;
3629
3630         /* offset */
3631         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3632         offset += 4;
3633
3634         BYTE_COUNT;
3635
3636         END_OF_SMB
3637
3638         return offset;
3639 }
3640
3641 static int
3642 dissect_create_temporary_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3643 {
3644         smb_info_t *si = pinfo->private_data;
3645         int fn_len;
3646         const char *fn;
3647         guint8 wc;
3648         guint16 bc;
3649
3650         WORD_COUNT;
3651
3652         /* 2 reserved bytes */
3653         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3654         offset += 2;
3655
3656         /* Creation time */
3657         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
3658
3659         BYTE_COUNT;
3660
3661         /* buffer format */
3662         CHECK_BYTE_COUNT(1);
3663         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3664         COUNT_BYTES(1);
3665
3666         /* directory name */
3667         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3668                 FALSE, FALSE, &bc);
3669         if (fn == NULL)
3670                 goto endofcommand;
3671         proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
3672                 fn);
3673         COUNT_BYTES(fn_len);
3674
3675         if (check_col(pinfo->cinfo, COL_INFO)) {
3676                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
3677         }
3678
3679         END_OF_SMB
3680
3681         return offset;
3682 }
3683
3684 static int
3685 dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3686 {
3687         smb_info_t *si = pinfo->private_data;
3688         int fn_len;
3689         const char *fn;
3690         guint8 wc;
3691         guint16 bc, fid;
3692
3693         WORD_COUNT;
3694
3695         /* fid */
3696         fid = tvb_get_letohs(tvb, offset);
3697         add_fid(tvb, pinfo, tree, offset, 2, fid);
3698         offset += 2;
3699
3700         BYTE_COUNT;
3701
3702         /* buffer format */
3703         CHECK_BYTE_COUNT(1);
3704         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
3705         COUNT_BYTES(1);
3706
3707         /* file name */
3708         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
3709                 FALSE, FALSE, &bc);
3710         if (fn == NULL)
3711                 goto endofcommand;
3712         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
3713                 fn);
3714         COUNT_BYTES(fn_len);
3715
3716         END_OF_SMB
3717
3718         return offset;
3719 }
3720
3721 static const value_string seek_mode_vals[] = {
3722         {0,     "From Start Of File"},
3723         {1,     "From Current Position"},
3724         {2,     "From End Of File"},
3725         {0,     NULL}
3726 };
3727
3728 static int
3729 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3730 {
3731         guint8 wc;
3732         guint16 bc, fid;
3733
3734         WORD_COUNT;
3735
3736         /* fid */
3737         fid = tvb_get_letohs(tvb, offset);
3738         add_fid(tvb, pinfo, tree, offset, 2, fid);
3739         offset += 2;
3740
3741         /* Seek Mode */
3742         proto_tree_add_item(tree, hf_smb_seek_mode, tvb, offset, 2, TRUE);
3743         offset += 2;
3744
3745         /* offset */
3746         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3747         offset += 4;
3748
3749         BYTE_COUNT;
3750
3751         END_OF_SMB
3752
3753         return offset;
3754 }
3755
3756 static int
3757 dissect_seek_file_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3758 {
3759         guint8 wc;
3760         guint16 bc;
3761
3762         WORD_COUNT;
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_set_information2_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3777 {
3778         guint8 wc;
3779         guint16 bc, fid;
3780
3781         WORD_COUNT;
3782
3783         /* fid */
3784         fid = tvb_get_letohs(tvb, offset);
3785         add_fid(tvb, pinfo, tree, offset, 2, fid);
3786         offset += 2;
3787
3788         /* create time */
3789         offset = dissect_smb_datetime(tvb, tree, offset,
3790                 hf_smb_create_time,
3791                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3792
3793         /* access time */
3794         offset = dissect_smb_datetime(tvb, tree, offset,
3795                 hf_smb_access_time,
3796                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3797
3798         /* last write time */
3799         offset = dissect_smb_datetime(tvb, tree, offset,
3800                 hf_smb_last_write_time,
3801                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3802
3803         BYTE_COUNT;
3804
3805         END_OF_SMB
3806
3807         return offset;
3808 }
3809
3810 static int
3811 dissect_query_information2_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3812 {
3813         guint8 wc;
3814         guint16 bc;
3815
3816         WORD_COUNT;
3817
3818         /* create time */
3819         offset = dissect_smb_datetime(tvb, tree, offset,
3820                 hf_smb_create_time,
3821                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
3822
3823         /* access time */
3824         offset = dissect_smb_datetime(tvb, tree, offset,
3825                 hf_smb_access_time,
3826                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
3827
3828         /* last write time */
3829         offset = dissect_smb_datetime(tvb, tree, offset,
3830                 hf_smb_last_write_time,
3831                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
3832
3833         /* data size */
3834         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
3835         offset += 4;
3836
3837         /* allocation size */
3838         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
3839         offset += 4;
3840
3841         /* File Attributes */
3842         offset = dissect_file_attributes(tvb, tree, offset, 2);
3843
3844         BYTE_COUNT;
3845
3846         END_OF_SMB
3847
3848         return offset;
3849 }
3850
3851 static int
3852 dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3853 {
3854         guint8 wc;
3855         guint16 cnt=0;
3856         guint16 bc, fid;
3857
3858         WORD_COUNT;
3859
3860         /* fid */
3861         fid = tvb_get_letohs(tvb, offset);
3862         add_fid(tvb, pinfo, tree, offset, 2, fid);
3863         offset += 2;
3864
3865         /* write count */
3866         cnt = tvb_get_letohs(tvb, offset);
3867         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
3868         offset += 2;
3869
3870         /* offset */
3871         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3872         offset += 4;
3873
3874         /* last write time */
3875         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
3876
3877         if(wc==12){
3878                 /* 12 reserved bytes */
3879                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 12, TRUE);
3880                 offset += 12;
3881         }
3882
3883         BYTE_COUNT;
3884
3885         /* 1 pad byte */
3886         CHECK_BYTE_COUNT(1);
3887         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
3888         COUNT_BYTES(1);
3889
3890         offset = dissect_file_data(tvb, tree, offset, cnt, cnt);
3891         bc = 0; /* XXX */
3892
3893         END_OF_SMB
3894
3895         return offset;
3896 }
3897
3898 static int
3899 dissect_write_and_close_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3900 {
3901         guint8 wc;
3902         guint16 bc;
3903
3904         WORD_COUNT;
3905
3906         /* write count */
3907         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
3908         offset += 2;
3909
3910         BYTE_COUNT;
3911
3912         END_OF_SMB
3913
3914         return offset;
3915 }
3916
3917 static int
3918 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3919 {
3920         guint8 wc;
3921         guint16 bc, fid;
3922         guint32 to;
3923
3924         WORD_COUNT;
3925
3926         /* fid */
3927         fid = tvb_get_letohs(tvb, offset);
3928         add_fid(tvb, pinfo, tree, offset, 2, fid);
3929         offset += 2;
3930
3931         /* offset */
3932         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
3933         offset += 4;
3934
3935         /* max count */
3936         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
3937         offset += 2;
3938
3939         /* min count */
3940         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
3941         offset += 2;
3942
3943         /* timeout */
3944         to = tvb_get_letohl(tvb, offset);
3945         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
3946         offset += 4;
3947
3948         /* 2 reserved bytes */
3949         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3950         offset += 2;
3951
3952         if(wc==10){
3953                 /* high offset */
3954                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
3955                 offset += 4;
3956         }
3957
3958         BYTE_COUNT;
3959
3960         END_OF_SMB
3961
3962         return offset;
3963 }
3964
3965 static int
3966 dissect_query_information_disk_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
3967 {
3968         guint8 wc;
3969         guint16 bc;
3970
3971         WORD_COUNT;
3972
3973         /* units */
3974         proto_tree_add_item(tree, hf_smb_units, tvb, offset, 2, TRUE);
3975         offset += 2;
3976
3977         /* bpu */
3978         proto_tree_add_item(tree, hf_smb_bpu, tvb, offset, 2, TRUE);
3979         offset += 2;
3980
3981         /* block size */
3982         proto_tree_add_item(tree, hf_smb_blocksize, tvb, offset, 2, TRUE);
3983         offset += 2;
3984
3985         /* free units */
3986         proto_tree_add_item(tree, hf_smb_freeunits, tvb, offset, 2, TRUE);
3987         offset += 2;
3988
3989         /* 2 reserved bytes */
3990         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
3991         offset += 2;
3992
3993         BYTE_COUNT;
3994
3995         END_OF_SMB
3996
3997         return offset;
3998 }
3999
4000 static int
4001 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4002 {
4003         guint8 wc;
4004         guint16 bc, fid;
4005
4006         WORD_COUNT;
4007
4008         /* fid */
4009         fid = tvb_get_letohs(tvb, offset);
4010         add_fid(tvb, pinfo, tree, offset, 2, fid);
4011         offset += 2;
4012
4013         /* offset */
4014         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4015         offset += 4;
4016
4017         /* max count */
4018         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4019         offset += 2;
4020
4021         /* min count */
4022         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
4023         offset += 2;
4024
4025         /* 6 reserved bytes */
4026         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
4027         offset += 6;
4028
4029         BYTE_COUNT;
4030
4031         END_OF_SMB
4032
4033         return offset;
4034 }
4035
4036 static int
4037 dissect_read_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4038 {
4039         guint16 datalen=0, bc;
4040         guint8 wc;
4041
4042         WORD_COUNT;
4043
4044         /* offset */
4045         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4046         offset += 4;
4047
4048         /* count */
4049         proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
4050         offset += 2;
4051
4052         /* 2 reserved bytes */
4053         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4054         offset += 2;
4055
4056         /* data compaction mode */
4057         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
4058         offset += 2;
4059
4060         /* 2 reserved bytes */
4061         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4062         offset += 2;
4063
4064         /* data len */
4065         datalen = tvb_get_letohs(tvb, offset);
4066         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4067         offset += 2;
4068
4069         /* data offset */
4070         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4071         offset += 2;
4072
4073         BYTE_COUNT;
4074
4075         /* file data */
4076         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4077         bc = 0;
4078
4079         END_OF_SMB
4080
4081         return offset;
4082 }
4083
4084
4085 static const true_false_string tfs_write_mode_write_through = {
4086         "WRITE THROUGH requested",
4087         "Write through not requested"
4088 };
4089 static const true_false_string tfs_write_mode_return_remaining = {
4090         "RETURN REMAINING (pipe/dev) requested",
4091         "DON'T return remaining (pipe/dev)"
4092 };
4093 static const true_false_string tfs_write_mode_raw = {
4094         "Use WriteRawNamedPipe (pipe)",
4095         "DON'T use WriteRawNamedPipe (pipe)"
4096 };
4097 static const true_false_string tfs_write_mode_message_start = {
4098         "This is the START of a MESSAGE (pipe)",
4099         "This is NOT the start of a message (pipe)"
4100 };
4101 static const true_false_string tfs_write_mode_connectionless = {
4102         "CONNECTIONLESS mode requested",
4103         "Connectionless mode NOT requested"
4104 };
4105
4106 #define WRITE_MODE_CONNECTIONLESS       0x0080
4107 #define WRITE_MODE_MESSAGE_START        0x0008
4108 #define WRITE_MODE_RAW                  0x0004
4109 #define WRITE_MODE_RETURN_REMAINING     0x0002
4110 #define WRITE_MODE_WRITE_THROUGH        0x0001
4111
4112 static int
4113 dissect_write_mode(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
4114 {
4115         guint16 mask;
4116         proto_item *item = NULL;
4117         proto_tree *tree = NULL;
4118
4119         mask = tvb_get_letohs(tvb, offset);
4120
4121         if(parent_tree){
4122                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4123                         "Write Mode: 0x%04x", mask);
4124                 tree = proto_item_add_subtree(item, ett_smb_rawmode);
4125         }
4126
4127         if(bm&WRITE_MODE_CONNECTIONLESS){
4128                 proto_tree_add_boolean(tree, hf_smb_write_mode_connectionless,
4129                         tvb, offset, 2, mask);
4130         }
4131         if(bm&WRITE_MODE_MESSAGE_START){
4132                 proto_tree_add_boolean(tree, hf_smb_write_mode_message_start,
4133                         tvb, offset, 2, mask);
4134         }
4135         if(bm&WRITE_MODE_RAW){
4136                 proto_tree_add_boolean(tree, hf_smb_write_mode_raw,
4137                         tvb, offset, 2, mask);
4138         }
4139         if(bm&WRITE_MODE_RETURN_REMAINING){
4140                 proto_tree_add_boolean(tree, hf_smb_write_mode_return_remaining,
4141                         tvb, offset, 2, mask);
4142         }
4143         if(bm&WRITE_MODE_WRITE_THROUGH){
4144                 proto_tree_add_boolean(tree, hf_smb_write_mode_write_through,
4145                         tvb, offset, 2, mask);
4146         }
4147
4148         offset += 2;
4149         return offset;
4150 }
4151
4152 static int
4153 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4154 {
4155         guint32 to;
4156         guint16 datalen=0, bc, fid;
4157         guint8 wc;
4158
4159         WORD_COUNT;
4160
4161         /* fid */
4162         fid = tvb_get_letohs(tvb, offset);
4163         add_fid(tvb, pinfo, tree, offset, 2, fid);
4164         offset += 2;
4165
4166         /* total data length */
4167         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4168         offset += 2;
4169
4170         /* 2 reserved bytes */
4171         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4172         offset += 2;
4173
4174         /* offset */
4175         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4176         offset += 4;
4177
4178         /* timeout */
4179         to = tvb_get_letohl(tvb, offset);
4180         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4181         offset += 4;
4182
4183         /* mode */
4184         offset = dissect_write_mode(tvb, tree, offset, 0x0003);
4185
4186         /* 4 reserved bytes */
4187         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
4188         offset += 4;
4189
4190         /* data len */
4191         datalen = tvb_get_letohs(tvb, offset);
4192         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4193         offset += 2;
4194
4195         /* data offset */
4196         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4197         offset += 2;
4198
4199         BYTE_COUNT;
4200
4201         /* file data */
4202         /* XXX - use the data offset to determine where the data starts? */
4203         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4204         bc = 0;
4205
4206         END_OF_SMB
4207
4208         return offset;
4209 }
4210
4211 static int
4212 dissect_write_raw_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4213 {
4214         guint8 wc;
4215         guint16 bc;
4216
4217         WORD_COUNT;
4218
4219         /* remaining */
4220         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
4221         offset += 2;
4222
4223         BYTE_COUNT;
4224
4225         END_OF_SMB
4226
4227         return offset;
4228 }
4229
4230 static int
4231 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4232 {
4233         guint32 to;
4234         guint16 datalen=0, bc, fid;
4235         guint8 wc;
4236
4237         WORD_COUNT;
4238
4239         /* fid */
4240         fid = tvb_get_letohs(tvb, offset);
4241         add_fid(tvb, pinfo, tree, offset, 2, fid);
4242         offset += 2;
4243
4244         /* total data length */
4245         proto_tree_add_item(tree, hf_smb_total_data_len, tvb, offset, 2, TRUE);
4246         offset += 2;
4247
4248         /* 2 reserved bytes */
4249         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4250         offset += 2;
4251
4252         /* offset */
4253         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
4254         offset += 4;
4255
4256         /* timeout */
4257         to = tvb_get_letohl(tvb, offset);
4258         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4259         offset += 4;
4260
4261         /* mode */
4262         offset = dissect_write_mode(tvb, tree, offset, 0x0083);
4263
4264         /* request mask */
4265         proto_tree_add_item(tree, hf_smb_request_mask, tvb, offset, 4, TRUE);
4266         offset += 4;
4267
4268         /* data len */
4269         datalen = tvb_get_letohs(tvb, offset);
4270         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
4271         offset += 2;
4272
4273         /* data offset */
4274         proto_tree_add_item(tree, hf_smb_data_offset, tvb, offset, 2, TRUE);
4275         offset += 2;
4276
4277         BYTE_COUNT;
4278
4279         /* file data */
4280         /* XXX - use the data offset to determine where the data starts? */
4281         offset = dissect_file_data(tvb, tree, offset, bc, datalen);
4282         bc = 0;
4283
4284         END_OF_SMB
4285
4286         return offset;
4287 }
4288
4289 static int
4290 dissect_write_mpx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4291 {
4292         guint8 wc;
4293         guint16 bc;
4294
4295         WORD_COUNT;
4296
4297         /* response mask */
4298         proto_tree_add_item(tree, hf_smb_response_mask, tvb, offset, 4, TRUE);
4299         offset += 4;
4300
4301         BYTE_COUNT;
4302
4303         END_OF_SMB
4304
4305         return offset;
4306 }
4307
4308 static int
4309 dissect_sid(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         /* sid */
4317         proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
4318         offset += 2;
4319
4320         BYTE_COUNT;
4321
4322         END_OF_SMB
4323
4324         return offset;
4325 }
4326
4327 static int
4328 dissect_search_resume_key(tvbuff_t *tvb, packet_info *pinfo,
4329     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4330     gboolean has_find_id)
4331 {
4332         proto_item *item = NULL;
4333         proto_tree *tree = NULL;
4334         smb_info_t *si = pinfo->private_data;
4335         int fn_len;
4336         const char *fn;
4337         char fname[11+1];
4338
4339         if(parent_tree){
4340                 item = proto_tree_add_text(parent_tree, tvb, offset, 21,
4341                         "Resume Key");
4342                 tree = proto_item_add_subtree(item, ett_smb_search_resume_key);
4343         }
4344
4345         /* reserved byte */
4346         CHECK_BYTE_COUNT_SUBR(1);
4347         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4348         COUNT_BYTES_SUBR(1);
4349
4350         /* file name */
4351         fn_len = 11;
4352         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4353                 TRUE, TRUE, bcp);
4354         CHECK_STRING_SUBR(fn);
4355         /* ensure that it's null-terminated */
4356         strncpy(fname, fn, 11);
4357         fname[11] = '\0';
4358         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, 11,
4359                 fname);
4360         COUNT_BYTES_SUBR(fn_len);
4361
4362         if (has_find_id) {
4363                 CHECK_BYTE_COUNT_SUBR(1);
4364                 proto_tree_add_item(tree, hf_smb_resume_find_id, tvb, offset, 1, TRUE);
4365                 COUNT_BYTES_SUBR(1);
4366
4367                 /* server cookie */
4368                 CHECK_BYTE_COUNT_SUBR(4);
4369                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 4, TRUE);
4370                 COUNT_BYTES_SUBR(4);
4371         } else {
4372                 /* server cookie */
4373                 CHECK_BYTE_COUNT_SUBR(5);
4374                 proto_tree_add_item(tree, hf_smb_resume_server_cookie, tvb, offset, 5, TRUE);
4375                 COUNT_BYTES_SUBR(5);
4376         }
4377
4378         /* client cookie */
4379         CHECK_BYTE_COUNT_SUBR(4);
4380         proto_tree_add_item(tree, hf_smb_resume_client_cookie, tvb, offset, 4, TRUE);
4381         COUNT_BYTES_SUBR(4);
4382
4383         *trunc = FALSE;
4384         return offset;
4385 }
4386
4387 static int
4388 dissect_search_dir_info(tvbuff_t *tvb, packet_info *pinfo,
4389     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc,
4390     gboolean has_find_id)
4391 {
4392         proto_item *item = NULL;
4393         proto_tree *tree = NULL;
4394         smb_info_t *si = pinfo->private_data;
4395         int fn_len;
4396         const char *fn;
4397         char fname[13+1];
4398
4399         if(parent_tree){
4400                 item = proto_tree_add_text(parent_tree, tvb, offset, 46,
4401                         "Directory Information");
4402                 tree = proto_item_add_subtree(item, ett_smb_search_dir_info);
4403         }
4404
4405         /* resume key */
4406         offset = dissect_search_resume_key(tvb, pinfo, tree, offset, bcp,
4407             trunc, has_find_id);
4408         if (*trunc)
4409                 return offset;
4410
4411         /* File Attributes */
4412         CHECK_BYTE_COUNT_SUBR(1);
4413         offset = dissect_dir_info_file_attributes(tvb, tree, offset);
4414         *bcp -= 1;
4415
4416         /* last write time */
4417         CHECK_BYTE_COUNT_SUBR(4);
4418         offset = dissect_smb_datetime(tvb, tree, offset,
4419                 hf_smb_last_write_time,
4420                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
4421                 TRUE);
4422         *bcp -= 4;
4423
4424         /* File Size */
4425         CHECK_BYTE_COUNT_SUBR(4);
4426         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
4427         COUNT_BYTES_SUBR(4);
4428
4429         /* file name */
4430         fn_len = 13;
4431         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4432                 TRUE, TRUE, bcp);
4433         CHECK_STRING_SUBR(fn);
4434         /* ensure that it's null-terminated */
4435         strncpy(fname, fn, 13);
4436         fname[13] = '\0';
4437         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4438                 fname);
4439         COUNT_BYTES_SUBR(fn_len);
4440
4441         *trunc = FALSE;
4442         return offset;
4443 }
4444
4445
4446 static int
4447 dissect_search_find_request(tvbuff_t *tvb, packet_info *pinfo,
4448     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4449     gboolean has_find_id)
4450 {
4451         smb_info_t *si = pinfo->private_data;
4452         int fn_len;
4453         const char *fn;
4454         guint16 rkl;
4455         guint8 wc;
4456         guint16 bc;
4457         gboolean trunc;
4458
4459         WORD_COUNT;
4460
4461         /* max count */
4462         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
4463         offset += 2;
4464
4465         /* Search Attributes */
4466         offset = dissect_search_attributes(tvb, tree, offset);
4467
4468         BYTE_COUNT;
4469
4470         /* buffer format */
4471         CHECK_BYTE_COUNT(1);
4472         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4473         COUNT_BYTES(1);
4474
4475         /* file name */
4476         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
4477                 TRUE, FALSE, &bc);
4478         if (fn == NULL)
4479                 goto endofcommand;
4480         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
4481                 fn);
4482         COUNT_BYTES(fn_len);
4483
4484         if (check_col(pinfo->cinfo, COL_INFO)) {
4485                 col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s", fn);
4486         }
4487
4488         /* buffer format */
4489         CHECK_BYTE_COUNT(1);
4490         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4491         COUNT_BYTES(1);
4492
4493         /* resume key length */
4494         CHECK_BYTE_COUNT(2);
4495         rkl = tvb_get_letohs(tvb, offset);
4496         proto_tree_add_uint(tree, hf_smb_resume_key_len, tvb, offset, 2, rkl);
4497         COUNT_BYTES(2);
4498
4499         /* resume key */
4500         if(rkl){
4501                 offset = dissect_search_resume_key(tvb, pinfo, tree, offset,
4502                     &bc, &trunc, has_find_id);
4503                 if (trunc)
4504                         goto endofcommand;
4505         }
4506
4507         END_OF_SMB
4508
4509         return offset;
4510 }
4511
4512 static int
4513 dissect_search_dir_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4514     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4515 {
4516         return dissect_search_find_request(tvb, pinfo, tree, offset,
4517             smb_tree, FALSE);
4518 }
4519
4520 static int
4521 dissect_find_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4522     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4523 {
4524         return dissect_search_find_request(tvb, pinfo, tree, offset,
4525             smb_tree, TRUE);
4526 }
4527
4528 static int
4529 dissect_find_close_request(tvbuff_t *tvb, packet_info *pinfo _U_,
4530     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4531 {
4532         return dissect_search_find_request(tvb, pinfo, tree, offset,
4533             smb_tree, TRUE);
4534 }
4535
4536 static int
4537 dissect_search_find_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4538     proto_tree *tree, int offset, proto_tree *smb_tree _U_,
4539     gboolean has_find_id)
4540 {
4541         guint16 count=0;
4542         guint8 wc;
4543         guint16 bc;
4544         gboolean trunc;
4545
4546         WORD_COUNT;
4547
4548         /* count */
4549         count = tvb_get_letohs(tvb, offset);
4550         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, count);
4551         offset += 2;
4552
4553         BYTE_COUNT;
4554
4555         /* buffer format */
4556         CHECK_BYTE_COUNT(1);
4557         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4558         COUNT_BYTES(1);
4559
4560         /* data len */
4561         CHECK_BYTE_COUNT(2);
4562         proto_tree_add_item(tree, hf_smb_data_len, tvb, offset, 2, TRUE);
4563         COUNT_BYTES(2);
4564
4565         while(count--){
4566                 offset = dissect_search_dir_info(tvb, pinfo, tree, offset,
4567                     &bc, &trunc, has_find_id);
4568                 if (trunc)
4569                         goto endofcommand;
4570         }
4571
4572         END_OF_SMB
4573
4574         return offset;
4575 }
4576
4577 static int
4578 dissect_search_dir_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4579 {
4580         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4581             FALSE);
4582 }
4583
4584 static int
4585 dissect_find_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4586 {
4587         return dissect_search_find_response(tvb, pinfo, tree, offset, smb_tree,
4588             TRUE);
4589 }
4590
4591 static int
4592 dissect_find_close_response(tvbuff_t *tvb, packet_info *pinfo _U_,
4593     proto_tree *tree, int offset, proto_tree *smb_tree _U_)
4594 {
4595         guint8 wc;
4596         guint16 bc;
4597         guint16 data_len;
4598
4599         WORD_COUNT;
4600
4601         /* reserved */
4602         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
4603         offset += 2;
4604
4605         BYTE_COUNT;
4606
4607         /* buffer format */
4608         CHECK_BYTE_COUNT(1);
4609         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
4610         COUNT_BYTES(1);
4611
4612         /* data len */
4613         CHECK_BYTE_COUNT(2);
4614         data_len = tvb_get_ntohs(tvb, offset);
4615         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, data_len);
4616         COUNT_BYTES(2);
4617
4618         if (data_len != 0) {
4619                 CHECK_BYTE_COUNT(data_len);
4620                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset,
4621                     data_len, TRUE);
4622                 COUNT_BYTES(data_len);
4623         }
4624
4625         END_OF_SMB
4626
4627         return offset;
4628 }
4629
4630 static const value_string locking_ol_vals[] = {
4631         {0,     "Client is not holding oplock on this file"},
4632         {1,     "Level 2 oplock currently held by client"},
4633         {0, NULL}
4634 };
4635
4636 static const true_false_string tfs_lock_type_large = {
4637         "Large file locking format requested",
4638         "Large file locking format not requested"
4639 };
4640 static const true_false_string tfs_lock_type_cancel = {
4641         "Cancel outstanding lock request",
4642         "Don't cancel outstanding lock request"
4643 };
4644 static const true_false_string tfs_lock_type_change = {
4645         "Change lock type",
4646         "Don't change lock type"
4647 };
4648 static const true_false_string tfs_lock_type_oplock = {
4649         "This is an oplock break notification/response",
4650         "This is not an oplock break notification/response"
4651 };
4652 static const true_false_string tfs_lock_type_shared = {
4653         "This is a shared lock",
4654         "This is an exclusive lock"
4655 };
4656 static int
4657 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4658 {
4659         guint8  wc, cmd=0xff, lt=0;
4660         guint16 andxoffset=0, un=0, ln=0, bc, fid;
4661         guint32 to;
4662         proto_item *litem = NULL;
4663         proto_tree *ltree = NULL;
4664         proto_item *it = NULL;
4665         proto_tree *tr = NULL;
4666         int old_offset = offset;
4667
4668         WORD_COUNT;
4669
4670         /* next smb command */
4671         cmd = tvb_get_guint8(tvb, offset);
4672         if(cmd!=0xff){
4673                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4674         } else {
4675                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4676         }
4677         offset += 1;
4678
4679         /* reserved byte */
4680         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4681         offset += 1;
4682
4683         /* andxoffset */
4684         andxoffset = tvb_get_letohs(tvb, offset);
4685         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4686         offset += 2;
4687
4688         /* fid */
4689         fid = tvb_get_letohs(tvb, offset);
4690         add_fid(tvb, pinfo, tree, offset, 2, fid);
4691         offset += 2;
4692
4693         /* lock type */
4694         lt = tvb_get_guint8(tvb, offset);
4695         if(tree){
4696                 litem = proto_tree_add_text(tree, tvb, offset, 1,
4697                         "Lock Type: 0x%02x", lt);
4698                 ltree = proto_item_add_subtree(litem, ett_smb_lock_type);
4699         }
4700         proto_tree_add_boolean(ltree, hf_smb_lock_type_large,
4701                 tvb, offset, 1, lt);
4702         proto_tree_add_boolean(ltree, hf_smb_lock_type_cancel,
4703                 tvb, offset, 1, lt);
4704         proto_tree_add_boolean(ltree, hf_smb_lock_type_change,
4705                 tvb, offset, 1, lt);
4706         proto_tree_add_boolean(ltree, hf_smb_lock_type_oplock,
4707                 tvb, offset, 1, lt);
4708         proto_tree_add_boolean(ltree, hf_smb_lock_type_shared,
4709                 tvb, offset, 1, lt);
4710         offset += 1;
4711
4712         /* oplock level */
4713         proto_tree_add_item(tree, hf_smb_locking_ol, tvb, offset, 1, TRUE);
4714         offset += 1;
4715
4716         /* timeout */
4717         to = tvb_get_letohl(tvb, offset);
4718         if (to == 0)
4719                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
4720         else if (to == 0xffffffff)
4721                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
4722         else
4723                 proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
4724         offset += 4;
4725
4726         /* number of unlocks */
4727         un = tvb_get_letohs(tvb, offset);
4728         proto_tree_add_uint(tree, hf_smb_number_of_unlocks, tvb, offset, 2, un);
4729         offset += 2;
4730
4731         /* number of locks */
4732         ln = tvb_get_letohs(tvb, offset);
4733         proto_tree_add_uint(tree, hf_smb_number_of_locks, tvb, offset, 2, ln);
4734         offset += 2;
4735
4736         BYTE_COUNT;
4737
4738         /* unlocks */
4739         if(un){
4740                 old_offset = offset;
4741
4742                 it = proto_tree_add_text(tree, tvb, offset, -1,
4743                         "Unlocks");
4744                 tr = proto_item_add_subtree(it, ett_smb_unlocks);
4745                 while(un--){
4746                         proto_item *litem = NULL;
4747                         proto_tree *ltree = NULL;
4748                         if(lt&0x10){
4749                                 guint8 buf[8];
4750                                 guint32 val;
4751
4752                                 /* large lock format */
4753                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4754                                         "Unlock");
4755                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4756
4757                                 /* PID */
4758                                 CHECK_BYTE_COUNT(2);
4759                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4760                                 COUNT_BYTES(2);
4761
4762                                 /* 2 reserved bytes */
4763                                 CHECK_BYTE_COUNT(2);
4764                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4765                                 COUNT_BYTES(2);
4766
4767                                 /* offset */
4768                                 CHECK_BYTE_COUNT(8);
4769                                 val=tvb_get_letohl(tvb, offset);
4770                                 buf[3]=(val>>24)&0xff;
4771                                 buf[2]=(val>>16)&0xff;
4772                                 buf[1]=(val>> 8)&0xff;
4773                                 buf[0]=(val    )&0xff;
4774                                 val=tvb_get_letohl(tvb, offset+4);
4775                                 buf[7]=(val>>24)&0xff;
4776                                 buf[6]=(val>>16)&0xff;
4777                                 buf[5]=(val>> 8)&0xff;
4778                                 buf[4]=(val    )&0xff;
4779                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4780                                 COUNT_BYTES(8);
4781
4782                                 /* length */
4783                                 CHECK_BYTE_COUNT(8);
4784                                 val=tvb_get_letohl(tvb, offset);
4785                                 buf[3]=(val>>24)&0xff;
4786                                 buf[2]=(val>>16)&0xff;
4787                                 buf[1]=(val>> 8)&0xff;
4788                                 buf[0]=(val    )&0xff;
4789                                 val=tvb_get_letohl(tvb, offset+4);
4790                                 buf[7]=(val>>24)&0xff;
4791                                 buf[6]=(val>>16)&0xff;
4792                                 buf[5]=(val>> 8)&0xff;
4793                                 buf[4]=(val    )&0xff;
4794                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4795                                 COUNT_BYTES(8);
4796                         } else {
4797                                 /* normal lock format */
4798                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4799                                         "Unlock");
4800                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4801
4802                                 /* PID */
4803                                 CHECK_BYTE_COUNT(2);
4804                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4805                                 COUNT_BYTES(2);
4806
4807                                 /* offset */
4808                                 CHECK_BYTE_COUNT(4);
4809                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4810                                 COUNT_BYTES(4);
4811
4812                                 /* lock count */
4813                                 CHECK_BYTE_COUNT(4);
4814                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4815                                 COUNT_BYTES(4);
4816                         }
4817                 }
4818                 proto_item_set_len(it, offset-old_offset);
4819                 it = NULL;
4820         }
4821
4822         /* locks */
4823         if(ln){
4824                 old_offset = offset;
4825
4826                 it = proto_tree_add_text(tree, tvb, offset, -1,
4827                         "Locks");
4828                 tr = proto_item_add_subtree(it, ett_smb_locks);
4829                 while(ln--){
4830                         proto_item *litem = NULL;
4831                         proto_tree *ltree = NULL;
4832                         if(lt&0x10){
4833                                 guint8 buf[8];
4834                                 guint32 val;
4835
4836                                 /* large lock format */
4837                                 litem = proto_tree_add_text(tr, tvb, offset, 20,
4838                                         "Lock");
4839                                 ltree = proto_item_add_subtree(litem, ett_smb_lock);
4840
4841                                 /* PID */
4842                                 CHECK_BYTE_COUNT(2);
4843                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4844                                 COUNT_BYTES(2);
4845
4846                                 /* 2 reserved bytes */
4847                                 CHECK_BYTE_COUNT(2);
4848                                 proto_tree_add_item(ltree, hf_smb_reserved, tvb, offset, 2, TRUE);
4849                                 COUNT_BYTES(2);
4850
4851                                 /* offset */
4852                                 CHECK_BYTE_COUNT(8);
4853                                 val=tvb_get_letohl(tvb, offset);
4854                                 buf[3]=(val    )&0xff;
4855                                 buf[2]=(val>> 8)&0xff;
4856                                 buf[1]=(val>>16)&0xff;
4857                                 buf[0]=(val>>24)&0xff;
4858                                 val=tvb_get_letohl(tvb, offset+4);
4859                                 buf[7]=(val    )&0xff;
4860                                 buf[6]=(val>> 8)&0xff;
4861                                 buf[5]=(val>>16)&0xff;
4862                                 buf[4]=(val>>24)&0xff;
4863                                 proto_tree_add_string(ltree, hf_smb_lock_long_offset, tvb, offset, 8, u64toa(buf));
4864                                 COUNT_BYTES(8);
4865
4866                                 /* length */
4867                                 CHECK_BYTE_COUNT(8);
4868                                 val=tvb_get_letohl(tvb, offset);
4869                                 buf[3]=(val    )&0xff;
4870                                 buf[2]=(val>> 8)&0xff;
4871                                 buf[1]=(val>>16)&0xff;
4872                                 buf[0]=(val>>24)&0xff;
4873                                 val=tvb_get_letohl(tvb, offset+4);
4874                                 buf[7]=(val    )&0xff;
4875                                 buf[6]=(val>> 8)&0xff;
4876                                 buf[5]=(val>>16)&0xff;
4877                                 buf[4]=(val>>24)&0xff;
4878                                 proto_tree_add_string(ltree, hf_smb_lock_long_length, tvb, offset, 8, u64toa(buf));
4879                                 COUNT_BYTES(8);
4880                         } else {
4881                                 /* normal lock format */
4882                                 litem = proto_tree_add_text(tr, tvb, offset, 10,
4883                                         "Unlock");
4884                                 ltree = proto_item_add_subtree(litem, ett_smb_unlock);
4885
4886                                 /* PID */
4887                                 CHECK_BYTE_COUNT(2);
4888                                 proto_tree_add_item(ltree, hf_smb_pid, tvb, offset, 2, TRUE);
4889                                 COUNT_BYTES(2);
4890
4891                                 /* offset */
4892                                 CHECK_BYTE_COUNT(4);
4893                                 proto_tree_add_item(ltree, hf_smb_offset, tvb, offset, 4, TRUE);
4894                                 COUNT_BYTES(4);
4895
4896                                 /* lock count */
4897                                 CHECK_BYTE_COUNT(4);
4898                                 proto_tree_add_item(ltree, hf_smb_count, tvb, offset, 4, TRUE);
4899                                 COUNT_BYTES(4);
4900                         }
4901                 }
4902                 proto_item_set_len(it, offset-old_offset);
4903                 it = NULL;
4904         }
4905
4906         END_OF_SMB
4907
4908         if (it != NULL) {
4909                 /*
4910                  * We ran out of byte count in the middle of dissecting
4911                  * the locks or the unlocks; set the site of the item
4912                  * we were dissecting.
4913                  */
4914                 proto_item_set_len(it, offset-old_offset);
4915         }
4916
4917         /* call AndXCommand (if there are any) */
4918         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4919
4920         return offset;
4921 }
4922
4923 static int
4924 dissect_locking_andx_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree)
4925 {
4926         guint8  wc, cmd=0xff;
4927         guint16 andxoffset=0;
4928         guint16 bc;
4929
4930         WORD_COUNT;
4931
4932         /* next smb command */
4933         cmd = tvb_get_guint8(tvb, offset);
4934         if(cmd!=0xff){
4935                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
4936         } else {
4937                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
4938         }
4939         offset += 1;
4940
4941         /* reserved byte */
4942         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
4943         offset += 1;
4944
4945         /* andxoffset */
4946         andxoffset = tvb_get_letohs(tvb, offset);
4947         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
4948         offset += 2;
4949
4950         BYTE_COUNT;
4951
4952         END_OF_SMB
4953
4954         /* call AndXCommand (if there are any) */
4955         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
4956
4957         return offset;
4958 }
4959
4960
4961 static const value_string oa_open_vals[] = {
4962         { 0,            "No action taken?"},
4963         { 1,            "The file existed and was opened"},
4964         { 2,            "The file did not exist but was created"},
4965         { 3,            "The file existed and was truncated"},
4966         { 0x8001,       "The file existed and was opened, and an OpLock was granted"}, 
4967         { 0x8002,       "The file did not exist but was created, and an OpLock was granted"},
4968         { 0x8002,       "The file existed and was truncated, and an OpLock was granted"},
4969         {0,     NULL}
4970 };
4971 static const true_false_string tfs_oa_lock = {
4972         "File is currently opened only by this user",
4973         "File is opened by another user (or mode not supported by server)"
4974 };
4975 static int
4976 dissect_open_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
4977 {
4978         guint16 mask;
4979         proto_item *item = NULL;
4980         proto_tree *tree = NULL;
4981
4982         mask = tvb_get_letohs(tvb, offset);
4983
4984         if(parent_tree){
4985                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
4986                         "Action: 0x%04x", mask);
4987                 tree = proto_item_add_subtree(item, ett_smb_open_action);
4988         }
4989
4990         proto_tree_add_boolean(tree, hf_smb_open_action_lock,
4991                 tvb, offset, 2, mask);
4992         proto_tree_add_uint(tree, hf_smb_open_action_open,
4993                 tvb, offset, 2, mask);
4994
4995         offset += 2;
4996
4997         return offset;
4998 }
4999
5000 static const true_false_string tfs_open_flags_add_info = {
5001         "Additional information requested",
5002         "Additional information not requested"
5003 };
5004 static const true_false_string tfs_open_flags_ex_oplock = {
5005         "Exclusive oplock requested",
5006         "Exclusive oplock not requested"
5007 };
5008 static const true_false_string tfs_open_flags_batch_oplock = {
5009         "Batch oplock requested",
5010         "Batch oplock not requested"
5011 };
5012 static const true_false_string tfs_open_flags_ealen = {
5013         "Total length of EAs requested",
5014         "Total length of EAs not requested"
5015 };
5016 static int
5017 dissect_open_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset, int bm)
5018 {
5019         guint16 mask;
5020         proto_item *item = NULL;
5021         proto_tree *tree = NULL;
5022
5023         mask = tvb_get_letohs(tvb, offset);
5024
5025         if(parent_tree){
5026                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5027                         "Flags: 0x%04x", mask);
5028                 tree = proto_item_add_subtree(item, ett_smb_open_flags);
5029         }
5030
5031         if(bm&0x0001){
5032                 proto_tree_add_boolean(tree, hf_smb_open_flags_add_info,
5033                         tvb, offset, 2, mask);
5034         }
5035         if(bm&0x0002){
5036                 proto_tree_add_boolean(tree, hf_smb_open_flags_ex_oplock,
5037                         tvb, offset, 2, mask);
5038         }
5039         if(bm&0x0004){
5040                 proto_tree_add_boolean(tree, hf_smb_open_flags_batch_oplock,
5041                         tvb, offset, 2, mask);
5042         }
5043         if(bm&0x0008){
5044                 proto_tree_add_boolean(tree, hf_smb_open_flags_ealen,
5045                         tvb, offset, 2, mask);
5046         }
5047
5048         offset += 2;
5049
5050         return offset;
5051 }
5052
5053 static const value_string filetype_vals[] = {
5054         { 0,            "Disk file or directory"},
5055         { 1,            "Named pipe in byte mode"},
5056         { 2,            "Named pipe in message mode"},
5057         { 3,            "Spooled printer"},
5058         {0, NULL}
5059 };
5060 static int
5061 dissect_open_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5062 {
5063         guint8  wc, cmd=0xff;
5064         guint16 andxoffset=0, bc;
5065         smb_info_t *si = pinfo->private_data;
5066         int fn_len;
5067         const char *fn;
5068
5069         WORD_COUNT;
5070
5071         /* next smb command */
5072         cmd = tvb_get_guint8(tvb, offset);
5073         if(cmd!=0xff){
5074                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5075         } else {
5076                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5077         }
5078         offset += 1;
5079
5080         /* reserved byte */
5081         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5082         offset += 1;
5083
5084         /* andxoffset */
5085         andxoffset = tvb_get_letohs(tvb, offset);
5086         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5087         offset += 2;
5088
5089         /* open flags */
5090         offset = dissect_open_flags(tvb, tree, offset, 0x0007);
5091
5092         /* desired access */
5093         offset = dissect_access(tvb, tree, offset, "Desired");
5094
5095         /* Search Attributes */
5096         offset = dissect_search_attributes(tvb, tree, offset);
5097
5098         /* File Attributes */
5099         offset = dissect_file_attributes(tvb, tree, offset, 2);
5100
5101         /* creation time */
5102         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_create_time);
5103
5104         /* open function */
5105         offset = dissect_open_function(tvb, tree, offset);
5106
5107         /* allocation size */
5108         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
5109         offset += 4;
5110
5111         /* 8 reserved bytes */
5112         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 8, TRUE);
5113         offset += 8;
5114
5115         BYTE_COUNT;
5116
5117         /* file name */
5118         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
5119                 FALSE, FALSE, &bc);
5120         if (fn == NULL)
5121                 goto endofcommand;
5122         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
5123                 fn);
5124         COUNT_BYTES(fn_len);
5125
5126         if (check_col(pinfo->cinfo, COL_INFO)) {
5127                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
5128         }
5129
5130         END_OF_SMB
5131
5132         /* call AndXCommand (if there are any) */
5133         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5134
5135         return offset;
5136 }
5137
5138 static const true_false_string tfs_ipc_state_nonblocking = {
5139         "Reads/writes return immediately if no data available",
5140         "Reads/writes block if no data available"
5141 };
5142 static const value_string ipc_state_endpoint_vals[] = {
5143         { 0,            "Consumer end of pipe"},
5144         { 1,            "Server end of pipe"},
5145         {0,     NULL}
5146 };
5147 static const value_string ipc_state_pipe_type_vals[] = {
5148         { 0,            "Byte stream pipe"},
5149         { 1,            "Message pipe"},
5150         {0,     NULL}
5151 };
5152 static const value_string ipc_state_read_mode_vals[] = {
5153         { 0,            "Read pipe as a byte stream"},
5154         { 1,            "Read messages from pipe"},
5155         {0,     NULL}
5156 };
5157
5158 int
5159 dissect_ipc_state(tvbuff_t *tvb, proto_tree *parent_tree, int offset,
5160     gboolean setstate)
5161 {
5162         guint16 mask;
5163         proto_item *item = NULL;
5164         proto_tree *tree = NULL;
5165
5166         mask = tvb_get_letohs(tvb, offset);
5167
5168         if(parent_tree){
5169                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5170                         "IPC State: 0x%04x", mask);
5171                 tree = proto_item_add_subtree(item, ett_smb_ipc_state);
5172         }
5173
5174         proto_tree_add_boolean(tree, hf_smb_ipc_state_nonblocking,
5175                 tvb, offset, 2, mask);
5176         if (!setstate) {
5177                 proto_tree_add_uint(tree, hf_smb_ipc_state_endpoint,
5178                         tvb, offset, 2, mask);
5179                 proto_tree_add_uint(tree, hf_smb_ipc_state_pipe_type,
5180                         tvb, offset, 2, mask);
5181         }
5182         proto_tree_add_uint(tree, hf_smb_ipc_state_read_mode,
5183                 tvb, offset, 2, mask);
5184         if (!setstate) {
5185                 proto_tree_add_uint(tree, hf_smb_ipc_state_icount,
5186                         tvb, offset, 2, mask);
5187         }
5188
5189         offset += 2;
5190
5191         return offset;
5192 }
5193
5194 static int
5195 dissect_open_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5196 {
5197         guint8  wc, cmd=0xff;
5198         guint16 andxoffset=0, bc;
5199         guint16 fid;
5200
5201         WORD_COUNT;
5202
5203         /* next smb command */
5204         cmd = tvb_get_guint8(tvb, offset);
5205         if(cmd!=0xff){
5206                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5207         } else {
5208                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5209         }
5210         offset += 1;
5211
5212         /* reserved byte */
5213         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5214         offset += 1;
5215
5216         /* andxoffset */
5217         andxoffset = tvb_get_letohs(tvb, offset);
5218         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5219         offset += 2;
5220
5221         /* fid */
5222         fid = tvb_get_letohs(tvb, offset);
5223         add_fid(tvb, pinfo, tree, offset, 2, fid);
5224         offset += 2;
5225
5226         /* File Attributes */
5227         offset = dissect_file_attributes(tvb, tree, offset, 2);
5228
5229         /* last write time */
5230         offset = dissect_smb_UTIME(tvb, tree, offset, hf_smb_last_write_time);
5231
5232         /* File Size */
5233         proto_tree_add_item(tree, hf_smb_file_size, tvb, offset, 4, TRUE);
5234         offset += 4;
5235
5236         /* granted access */
5237         offset = dissect_access(tvb, tree, offset, "Granted");
5238
5239         /* File Type */
5240         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
5241         offset += 2;
5242
5243         /* IPC State */
5244         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
5245
5246         /* open_action */
5247         offset = dissect_open_action(tvb, tree, offset);
5248
5249         /* server fid */
5250         proto_tree_add_item(tree, hf_smb_server_fid, tvb, offset, 4, TRUE);
5251         offset += 4;
5252
5253         /* 2 reserved bytes */
5254         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5255         offset += 2;
5256
5257         BYTE_COUNT;
5258
5259         END_OF_SMB
5260
5261         /* call AndXCommand (if there are any) */
5262         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5263
5264         return offset;
5265 }
5266
5267 static int
5268 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5269 {
5270         guint8  wc, cmd=0xff;
5271         guint16 andxoffset=0, bc, maxcnt_low;
5272         guint32 maxcnt_high;
5273         guint32 maxcnt=0;
5274         guint32 ofs = 0;
5275         smb_info_t *si;
5276         unsigned int fid;
5277
5278         WORD_COUNT;
5279
5280         /* next smb command */
5281         cmd = tvb_get_guint8(tvb, offset);
5282         if(cmd!=0xff){
5283                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5284         } else {
5285                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5286         }
5287         offset += 1;
5288
5289         /* reserved byte */
5290         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5291         offset += 1;
5292
5293         /* andxoffset */
5294         andxoffset = tvb_get_letohs(tvb, offset);
5295         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5296         offset += 2;
5297
5298         /* fid */
5299         fid = tvb_get_letohs(tvb, offset);
5300         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
5301         offset += 2;
5302         if (!pinfo->fd->flags.visited) {
5303                 /* remember the FID for the processing of the response */
5304                 si = (smb_info_t *)pinfo->private_data;
5305                 si->sip->extra_info=(void *)fid;
5306         }
5307
5308         /* offset */
5309         ofs = tvb_get_letohl(tvb, offset);
5310         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5311         offset += 4;
5312
5313         /* max count low */
5314         maxcnt_low = tvb_get_letohs(tvb, offset);
5315         proto_tree_add_uint(tree, hf_smb_max_count_low, tvb, offset, 2, maxcnt_low);
5316         offset += 2;
5317
5318         /* min count */
5319         proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
5320         offset += 2;
5321
5322         /*
5323          * max count high
5324          *
5325          * XXX - we should really only do this in case we have seen
5326          * LARGE FILE being negotiated.  Unfortunately, we might not
5327          * have seen the negotiation phase in the capture....
5328          *
5329          * XXX - this is shown as a ULONG in the SNIA SMB spec, i.e.
5330          * it's 32 bits, but the description says "High 16 bits of
5331          * MaxCount if CAP_LARGE_READX".
5332          *
5333          * The SMB File Sharing Protocol Extensions Version 2.0,
5334          * Document Version 3.3 spec doesn't speak of an extra 16
5335          * bits in max count, but it does show a 32-bit timeout
5336          * after the min count field.
5337          *
5338          * Perhaps the 32-bit timeout field was hijacked as a 16-bit
5339          * high count and a 16-bit reserved field.
5340          *
5341          * We fetch and display it as 32 bits.
5342          * 
5343          * XXX if maxcount high is 0xFFFFFFFF we assume it is just padding
5344          * bytes and we just ignore it.
5345          */
5346         maxcnt_high = tvb_get_letohl(tvb, offset);
5347         if(maxcnt_high==0xffffffff){
5348                 maxcnt_high=0;
5349         } else {
5350                 proto_tree_add_uint(tree, hf_smb_max_count_high, tvb, offset, 4, maxcnt_high);
5351         }
5352
5353         offset += 4;
5354
5355         maxcnt=maxcnt_high;
5356         maxcnt=(maxcnt<<16)|maxcnt_low;
5357
5358         if (check_col(pinfo->cinfo, COL_INFO))
5359                 col_append_fstr(pinfo->cinfo, COL_INFO,
5360                                 ", %u byte%s at offset %u", maxcnt,
5361                                 (maxcnt == 1) ? "" : "s", ofs);
5362
5363         /* remaining */
5364         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5365         offset += 2;
5366
5367         if(wc==12){
5368                 /* high offset */
5369                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5370                 offset += 4;
5371         }
5372
5373         BYTE_COUNT;
5374
5375         END_OF_SMB
5376
5377         /* call AndXCommand (if there are any) */
5378         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5379
5380         return offset;
5381 }
5382
5383 static int
5384 dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5385 {
5386         guint8  wc, cmd=0xff;
5387         guint16 andxoffset=0, bc, datalen_low, dataoffset=0;
5388         guint32 datalen=0, datalen_high;
5389         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5390         int fid=0;
5391
5392         WORD_COUNT;
5393
5394         /* next smb command */
5395         cmd = tvb_get_guint8(tvb, offset);
5396         if(cmd!=0xff){
5397                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5398         } else {
5399                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5400         }
5401         offset += 1;
5402
5403         /* reserved byte */
5404         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5405         offset += 1;
5406
5407         /* andxoffset */
5408         andxoffset = tvb_get_letohs(tvb, offset);
5409         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5410         offset += 2;
5411
5412         /* If we have seen the request, then print which FID this refers to */
5413         /* first check if we have seen the request */
5414         if(si->sip != NULL && si->sip->frame_req>0){
5415                 fid=(int)si->sip->extra_info;
5416                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) fid);
5417         }
5418
5419         /* remaining */
5420         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5421         offset += 2;
5422
5423         /* data compaction mode */
5424         proto_tree_add_item(tree, hf_smb_dcm, tvb, offset, 2, TRUE);
5425         offset += 2;
5426
5427         /* 2 reserved bytes */
5428         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5429         offset += 2;
5430
5431         /* data len low */
5432         datalen_low = tvb_get_letohs(tvb, offset);
5433         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5434         offset += 2;
5435
5436         /* data offset */
5437         dataoffset=tvb_get_letohs(tvb, offset);
5438         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5439         offset += 2;
5440
5441         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5442         /* data length high */
5443         datalen_high = tvb_get_letohl(tvb, offset);
5444         if(datalen_high==0xffffffff){
5445                 datalen_high=0;
5446         } else {
5447                 proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 4, datalen_high);
5448         }
5449         offset += 4;
5450
5451         datalen=datalen_high;
5452         datalen=(datalen<<16)|datalen_low;
5453
5454
5455         if (check_col(pinfo->cinfo, COL_INFO))
5456                 col_append_fstr(pinfo->cinfo, COL_INFO,
5457                                 ", %u byte%s", datalen,
5458                                 (datalen == 1) ? "" : "s");
5459
5460
5461         /* 6 reserved bytes */
5462         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 6, TRUE);
5463         offset += 6;
5464
5465         BYTE_COUNT;
5466
5467         /* file data, might be DCERPC on a pipe */
5468         if(bc){
5469                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5470                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
5471                 bc = 0;
5472         }
5473
5474         END_OF_SMB
5475
5476         /* call AndXCommand (if there are any) */
5477         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5478
5479         return offset;
5480 }
5481
5482 static int
5483 dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5484 {
5485         guint32 ofs=0;
5486         guint8  wc, cmd=0xff;
5487         guint16 andxoffset=0, bc, dataoffset=0, datalen_low, datalen_high;
5488         guint32 datalen=0;
5489         smb_info_t *si = (smb_info_t *)pinfo->private_data;
5490         unsigned int fid=0;
5491         guint16 mode = 0;
5492
5493         WORD_COUNT;
5494
5495         /* next smb command */
5496         cmd = tvb_get_guint8(tvb, offset);
5497         if(cmd!=0xff){
5498                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5499         } else {
5500                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5501         }
5502         offset += 1;
5503
5504         /* reserved byte */
5505         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5506         offset += 1;
5507
5508         /* andxoffset */
5509         andxoffset = tvb_get_letohs(tvb, offset);
5510         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5511         offset += 2;
5512
5513         /* fid */
5514         fid = tvb_get_letohs(tvb, offset);
5515         add_fid(tvb, pinfo, tree, offset, 2, (guint16) fid);
5516         offset += 2;
5517         if (!pinfo->fd->flags.visited) {
5518                 /* remember the FID for the processing of the response */
5519                 si->sip->extra_info=(void *)fid;
5520         }
5521
5522         /* offset */
5523         ofs = tvb_get_letohl(tvb, offset);
5524         proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
5525         offset += 4;
5526
5527         /* reserved */
5528         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5529         offset += 4;
5530
5531         /* mode */
5532         mode = tvb_get_letohs(tvb, offset);
5533         offset = dissect_write_mode(tvb, tree, offset, 0x000f);
5534
5535         /* remaining */
5536         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5537         offset += 2;
5538
5539         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5540         /* data length high */
5541         datalen_high = tvb_get_letohs(tvb, offset);
5542         proto_tree_add_uint(tree, hf_smb_data_len_high, tvb, offset, 2, datalen_high);
5543         offset += 2;
5544
5545         /* data len low */
5546         datalen_low = tvb_get_letohs(tvb, offset);
5547         proto_tree_add_uint(tree, hf_smb_data_len_low, tvb, offset, 2, datalen_low);
5548         offset += 2;
5549
5550         datalen=datalen_high;
5551         datalen=(datalen<<16)|datalen_low;
5552
5553         /* data offset */
5554         dataoffset=tvb_get_letohs(tvb, offset);
5555         proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
5556         offset += 2;
5557
5558         /* FIXME: handle Large (48-bit) byte/offset to COL_INFO */
5559         if (check_col(pinfo->cinfo, COL_INFO))
5560                 col_append_fstr(pinfo->cinfo, COL_INFO,
5561                                 ", %u byte%s at offset %u", datalen,
5562                                 (datalen == 1) ? "" : "s", ofs);
5563
5564         if(wc==14){
5565                 /* high offset */
5566                 proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
5567                 offset += 4;
5568         }
5569
5570         BYTE_COUNT;
5571
5572         /* if both the MessageStart and the  WriteRawNamedPipe flags are set
5573            the first two bytes of the payload is the length of the data.
5574            Assume that all WriteAndX PDUs that have MESSAGE_START set to
5575            be over the IPC$ share and thus they all transport DCERPC.
5576            (if we didnt already know that from the TreeConnect call)
5577         */
5578         if(mode&WRITE_MODE_MESSAGE_START){
5579                 if(mode&WRITE_MODE_RAW){
5580                         proto_tree_add_item(tree, hf_smb_pipe_write_len, tvb, offset, 2, TRUE);
5581                         offset += 2;
5582                         dataoffset += 2;
5583                         bc -= 2;
5584                         datalen -= 2;
5585                 }
5586                 if(!pinfo->fd->flags.visited){
5587                         /* In case we did not see the TreeConnect call,
5588                            store this TID here as well as a IPC TID 
5589                            so we know that future Read/Writes to this 
5590                            TID is (probably) DCERPC.
5591                         */
5592                         if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
5593                                 g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
5594                         }
5595                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
5596                 }
5597                 if(si->sip){
5598                         si->sip->flags|=SMB_SIF_TID_IS_IPC;
5599                 }
5600         }
5601
5602         /* file data, might be DCERPC on a pipe */
5603         if (bc != 0) {
5604                 offset = dissect_file_data_maybe_dcerpc(tvb, pinfo, tree,
5605                     top_tree, offset, bc, (guint16) datalen, 0, (guint16) fid);
5606                 bc = 0;
5607         }
5608
5609         END_OF_SMB
5610
5611         /* call AndXCommand (if there are any) */
5612         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5613
5614         return offset;
5615 }
5616
5617 static int
5618 dissect_write_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5619 {
5620         guint8  wc, cmd=0xff;
5621         guint16 andxoffset=0, bc, count_low, count_high;
5622         guint32 count=0;
5623         smb_info_t *si;
5624
5625         WORD_COUNT;
5626
5627         /* next smb command */
5628         cmd = tvb_get_guint8(tvb, offset);
5629         if(cmd!=0xff){
5630                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5631         } else {
5632                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5633         }
5634         offset += 1;
5635
5636         /* reserved byte */
5637         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5638         offset += 1;
5639
5640         /* andxoffset */
5641         andxoffset = tvb_get_letohs(tvb, offset);
5642         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5643         offset += 2;
5644
5645         /* If we have seen the request, then print which FID this refers to */
5646         si = (smb_info_t *)pinfo->private_data;
5647         /* first check if we have seen the request */
5648         if(si->sip != NULL && si->sip->frame_req>0){
5649                 add_fid(tvb, pinfo, tree, 0, 0, (guint16) GPOINTER_TO_UINT(si->sip->extra_info));
5650         }
5651
5652         /* write count low */
5653         count_low = tvb_get_letohs(tvb, offset);
5654         proto_tree_add_uint(tree, hf_smb_count_low, tvb, offset, 2, count_low);
5655         offset += 2;
5656
5657         /* remaining */
5658         proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
5659         offset += 2;
5660
5661         /* XXX we should really only do this in case we have seen LARGE FILE being negotiated */
5662         /* write count high */
5663         count_high = tvb_get_letohs(tvb, offset);
5664         proto_tree_add_uint(tree, hf_smb_count_high, tvb, offset, 2, count_high);
5665         offset += 2;
5666
5667         count=count_high;
5668         count=(count<<16)|count_low;
5669
5670         if (check_col(pinfo->cinfo, COL_INFO))
5671                 col_append_fstr(pinfo->cinfo, COL_INFO,
5672                                 ", %u byte%s", count,
5673                                 (count == 1) ? "" : "s");
5674
5675         /* 2 reserved bytes */
5676         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
5677         offset += 2;
5678
5679         BYTE_COUNT;
5680
5681         END_OF_SMB
5682
5683         /* call AndXCommand (if there are any) */
5684         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
5685
5686         return offset;
5687 }
5688
5689
5690 static const true_false_string tfs_setup_action_guest = {
5691         "Logged in as GUEST",
5692         "Not logged in as GUEST"
5693 };
5694 static int
5695 dissect_setup_action(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
5696 {
5697         guint16 mask;
5698         proto_item *item = NULL;
5699         proto_tree *tree = NULL;
5700
5701         mask = tvb_get_letohs(tvb, offset);
5702
5703         if(parent_tree){
5704                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
5705                         "Action: 0x%04x", mask);
5706                 tree = proto_item_add_subtree(item, ett_smb_setup_action);
5707         }
5708
5709         proto_tree_add_boolean(tree, hf_smb_setup_action_guest,
5710                 tvb, offset, 2, mask);
5711
5712         offset += 2;
5713
5714         return offset;
5715 }
5716
5717
5718 static int
5719 dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
5720 {
5721         guint8  wc, cmd=0xff;
5722         guint16 bc;
5723         guint16 andxoffset=0;
5724         smb_info_t *si = pinfo->private_data;
5725         int an_len;
5726         const char *an;
5727         int dn_len;
5728         const char *dn;
5729         guint16 pwlen=0;
5730         guint16 sbloblen=0;
5731         guint16 apwlen=0, upwlen=0;
5732
5733         WORD_COUNT;
5734
5735         /* next smb command */
5736         cmd = tvb_get_guint8(tvb, offset);
5737         if(cmd!=0xff){
5738                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
5739         } else {
5740                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
5741         }
5742         offset += 1;
5743
5744         /* reserved byte */
5745         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
5746         offset += 1;
5747
5748         /* andxoffset */
5749         andxoffset = tvb_get_letohs(tvb, offset);
5750         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
5751         offset += 2;
5752
5753         /* Maximum Buffer Size */
5754         proto_tree_add_item(tree, hf_smb_max_buf_size, tvb, offset, 2, TRUE);
5755         offset += 2;
5756
5757         /* Maximum Multiplex Count */
5758         proto_tree_add_item(tree, hf_smb_max_mpx_count, tvb, offset, 2, TRUE);
5759         offset += 2;
5760
5761         /* VC Number */
5762         proto_tree_add_item(tree, hf_smb_vc_num, tvb, offset, 2, TRUE);
5763         offset += 2;
5764
5765         /* session key */
5766         proto_tree_add_item(tree, hf_smb_session_key, tvb, offset, 4, TRUE);
5767         offset += 4;
5768
5769         switch (wc) {
5770         case 10:
5771                 /* password length, ASCII*/
5772                 pwlen = tvb_get_letohs(tvb, offset);
5773                 proto_tree_add_uint(tree, hf_smb_password_len,
5774                         tvb, offset, 2, pwlen);
5775                 offset += 2;
5776
5777                 /* 4 reserved bytes */
5778                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5779                 offset += 4;
5780
5781                 break;
5782
5783         case 12:
5784                 /* security blob length */
5785                 sbloblen = tvb_get_letohs(tvb, offset);
5786                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
5787                 offset += 2;
5788
5789                 /* 4 reserved bytes */
5790                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5791                 offset += 4;
5792
5793                 /* capabilities */
5794                 dissect_negprot_capabilities(tvb, tree, offset);
5795                 offset += 4;
5796
5797                 break;
5798
5799         case 13:
5800                 /* password length, ANSI*/
5801                 apwlen = tvb_get_letohs(tvb, offset);
5802                 proto_tree_add_uint(tree, hf_smb_ansi_password_len,
5803                         tvb, offset, 2, apwlen);
5804                 offset += 2;
5805
5806                 /* password length, Unicode*/
5807                 upwlen = tvb_get_letohs(tvb, offset);
5808                 proto_tree_add_uint(tree, hf_smb_unicode_password_len,
5809                         tvb, offset, 2, upwlen);
5810                 offset += 2;
5811
5812                 /* 4 reserved bytes */
5813                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
5814                 offset += 4;
5815
5816                 /* capabilities */
5817                 dissect_negprot_capabilities(tvb, tree, offset);
5818                 offset += 4;
5819
5820                 break;
5821         }
5822
5823         BYTE_COUNT;
5824
5825         if (wc==12) {
5826                 proto_item *blob_item;
5827
5828                 /* security blob */
5829
5830                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
5831                                                 tvb, offset, sbloblen, TRUE);
5832
5833                 /* As an optimization, because Windows is perverse,
5834                    we check to see if NTLMSSP is the first part of the 
5835                    blob, and if so, call the NTLMSSP dissector,
5836                    otherwise we call the GSS-API dissector. This is because
5837                    Windows can request RAW NTLMSSP, but will happily handle
5838                    a client that wraps NTLMSSP in SPNEGO
5839                 */
5840
5841                 if(sbloblen){
5842                         tvbuff_t *blob_tvb;
5843                         proto_tree *blob_tree;
5844
5845                         blob_tree = proto_item_add_subtree(blob_item, 
5846                                                            ett_smb_secblob);
5847                         CHECK_BYTE_COUNT(sbloblen);
5848
5849                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
5850                                                   sbloblen);
5851
5852                         if (si && si->ct && si->ct->raw_ntlmssp && 
5853                             !strncmp("NTLMSSP", 
5854                                      tvb_get_ptr(tvb, offset, 7), 7)) {
5855                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
5856                                          blob_tree);
5857
5858                         }
5859                         else {
5860                           call_dissector(gssapi_handle, blob_tvb, 
5861                                          pinfo, blob_tree);
5862                         }
5863
5864                         COUNT_BYTES(sbloblen);
5865                 }
5866
5867                 /* OS */
5868                 an = get_unicode_or_ascii_string(tvb, &offset,
5869                         si->unicode, &an_len, FALSE, FALSE, &bc);
5870                 if (an == NULL)
5871                         goto endofcommand;
5872                 proto_tree_add_string(tree, hf_smb_os, tvb,
5873                         offset, an_len, an);
5874                 COUNT_BYTES(an_len);
5875
5876                 /* LANMAN */
5877                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5878                  * padding/null string/whatever in front of this. W2K doesn't
5879                  * appear to. I suspect that's a bug that got fixed; I also
5880                  * suspect that, in practice, nobody ever looks at that field
5881                  * because the bug didn't appear to get fixed until NT 5.0....
5882                  */
5883                 an = get_unicode_or_ascii_string(tvb, &offset,
5884                         si->unicode, &an_len, FALSE, FALSE, &bc);
5885                 if (an == NULL)
5886                         goto endofcommand;
5887                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
5888                         offset, an_len, an);
5889                 COUNT_BYTES(an_len);
5890
5891                 /* Primary domain */
5892                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5893                  * byte in front of this, at least if all the strings are
5894                  * ASCII and the account name is empty. Another bug?
5895                  */
5896                 dn = get_unicode_or_ascii_string(tvb, &offset,
5897                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5898                 if (dn == NULL)
5899                         goto endofcommand;
5900                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5901                         offset, dn_len, dn);
5902                 COUNT_BYTES(dn_len);
5903         } else {
5904                 switch (wc) {
5905
5906                 case 10:
5907                         if(pwlen){
5908                                 /* password, ASCII */
5909                                 CHECK_BYTE_COUNT(pwlen);
5910                                 proto_tree_add_item(tree, hf_smb_password,
5911                                         tvb, offset, pwlen, TRUE);
5912                                 COUNT_BYTES(pwlen);
5913                         }
5914
5915                         break;
5916
5917                 case 13:
5918                         if(apwlen){
5919                                 /* password, ANSI */
5920                                 CHECK_BYTE_COUNT(apwlen);
5921                                 proto_tree_add_item(tree, hf_smb_ansi_password,
5922                                         tvb, offset, apwlen, TRUE);
5923                                 COUNT_BYTES(apwlen);
5924                         }
5925
5926                         if(upwlen){
5927                                 proto_item *item;
5928
5929                                 /* password, Unicode */
5930                                 CHECK_BYTE_COUNT(upwlen);
5931                                 item = proto_tree_add_item(tree, hf_smb_unicode_password,
5932                                         tvb, offset, upwlen, TRUE);
5933
5934                                 if (upwlen > 24) {
5935                                         proto_tree *subtree;
5936
5937                                         subtree = proto_item_add_subtree(item, ett_smb_unicode_password);
5938
5939                                         dissect_ntlmv2_response(
5940                                                 tvb, subtree, offset, upwlen);
5941                                 }
5942
5943                                 COUNT_BYTES(upwlen);
5944                         }
5945
5946                         break;
5947                 }
5948
5949                 /* Account Name */
5950                 an = get_unicode_or_ascii_string(tvb, &offset,
5951                         si->unicode, &an_len, FALSE, FALSE, &bc);
5952                 if (an == NULL)
5953                         goto endofcommand;
5954                 proto_tree_add_string(tree, hf_smb_account, tvb, offset, an_len,
5955                         an);
5956                 COUNT_BYTES(an_len);
5957
5958                 /* Primary domain */
5959                 /* XXX - pre-W2K NT systems sometimes appear to stick an extra
5960                  * byte in front of this, at least if all the strings are
5961                  * ASCII and the account name is empty. Another bug?
5962                  */
5963                 dn = get_unicode_or_ascii_string(tvb, &offset,
5964                         si->unicode, &dn_len, FALSE, FALSE, &bc);
5965                 if (dn == NULL)
5966                         goto endofcommand;
5967                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
5968                         offset, dn_len, dn);
5969                 COUNT_BYTES(dn_len);
5970
5971                 if (check_col(pinfo->cinfo, COL_INFO)) {
5972                         col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
5973
5974                         if (!dn[0] && !an[0])
5975                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5976                                                 "anonymous");
5977                         else
5978                                 col_append_fstr(pinfo->cinfo, COL_INFO,
5979                                                 "%s\\%s", dn,an);
5980                 }
5981
5982                 /* OS */
5983                 an = get_unicode_or_ascii_string(tvb, &offset,
5984                         si->unicode, &an_len, FALSE, FALSE, &bc);
5985                 if (an == NULL)
5986                         goto endofcommand;
5987                 proto_tree_add_string(tree, hf_smb_os, tvb,
5988                         offset, an_len, an);
5989                 COUNT_BYTES(an_len);
5990
5991                 /* LANMAN */
5992                 /* XXX - pre-W2K NT systems appear to stick an extra 2 bytes of
5993                  * padding/null string/whatever in front of this. W2K doesn't
5994                  * appear to. I suspect that's a bug that got fixed; I also
5995                  * suspect that, in practice, nobody ever looks at that field
5996                  * because the bug didn't appear to get fixed until NT 5.0....
5997                  */
5998                 an = get_unicode_or_ascii_string(tvb, &offset,
5999                         si->unicode, &an_len, FALSE, FALSE, &bc);
6000                 if (an == NULL)
6001                         goto endofcommand;
6002                 proto_tree_add_string(tree, hf_smb_lanman, tvb,
6003                         offset, an_len, an);
6004                 COUNT_BYTES(an_len);
6005         }
6006
6007         END_OF_SMB
6008
6009         /* call AndXCommand (if there are any) */
6010         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6011
6012         return offset;
6013 }
6014
6015 static int
6016 dissect_session_setup_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6017 {
6018         guint8  wc, cmd=0xff;
6019         guint16 andxoffset=0, bc;
6020         guint16 sbloblen=0;
6021         smb_info_t *si = pinfo->private_data;
6022         int an_len;
6023         const char *an;
6024
6025         WORD_COUNT;
6026
6027         /* next smb command */
6028         cmd = tvb_get_guint8(tvb, offset);
6029         if(cmd!=0xff){
6030                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6031         } else {
6032                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6033         }
6034         offset += 1;
6035
6036         /* reserved byte */
6037         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6038         offset += 1;
6039
6040         /* andxoffset */
6041         andxoffset = tvb_get_letohs(tvb, offset);
6042         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6043         offset += 2;
6044
6045         /* flags */
6046         offset = dissect_setup_action(tvb, tree, offset);
6047
6048         if(wc==4){
6049                 /* security blob length */
6050                 sbloblen = tvb_get_letohs(tvb, offset);
6051                 proto_tree_add_uint(tree, hf_smb_security_blob_len, tvb, offset, 2, sbloblen);
6052                 offset += 2;
6053         }
6054
6055         BYTE_COUNT;
6056
6057         if(wc==4) {
6058                 proto_item *blob_item;
6059
6060                 /* security blob */
6061
6062                 blob_item = proto_tree_add_item(tree, hf_smb_security_blob,
6063                                                 tvb, offset, sbloblen, TRUE);
6064
6065                 if(sbloblen){
6066                         tvbuff_t *blob_tvb;
6067                         proto_tree *blob_tree;
6068
6069                         blob_tree = proto_item_add_subtree(blob_item, 
6070                                                            ett_smb_secblob);
6071                         CHECK_BYTE_COUNT(sbloblen);
6072
6073                         blob_tvb = tvb_new_subset(tvb, offset, sbloblen, 
6074                                                     sbloblen);
6075
6076                         if (si && si->ct && si->ct->raw_ntlmssp && 
6077                             !strncmp("NTLMSSP", 
6078                                      tvb_get_ptr(tvb, offset, 7), 7)) {
6079                           call_dissector(ntlmssp_handle, blob_tvb, pinfo,
6080                                          blob_tree);
6081
6082                         }
6083                         else {
6084                           call_dissector(gssapi_handle, blob_tvb, pinfo, 
6085                                          blob_tree);
6086
6087                         }
6088
6089                         COUNT_BYTES(sbloblen);
6090                 }
6091         }
6092
6093         /* OS */
6094         an = get_unicode_or_ascii_string(tvb, &offset,
6095                 si->unicode, &an_len, FALSE, FALSE, &bc);
6096         if (an == NULL)
6097                 goto endofcommand;
6098         proto_tree_add_string(tree, hf_smb_os, tvb,
6099                 offset, an_len, an);
6100         COUNT_BYTES(an_len);
6101
6102         /* LANMAN */
6103         an = get_unicode_or_ascii_string(tvb, &offset,
6104                 si->unicode, &an_len, FALSE, FALSE, &bc);
6105         if (an == NULL)
6106                 goto endofcommand;
6107         proto_tree_add_string(tree, hf_smb_lanman, tvb,
6108                 offset, an_len, an);
6109         COUNT_BYTES(an_len);
6110
6111         if(wc==3) {
6112                 /* Primary domain */
6113                 an = get_unicode_or_ascii_string(tvb, &offset,
6114                         si->unicode, &an_len, FALSE, FALSE, &bc);
6115                 if (an == NULL)
6116                         goto endofcommand;
6117                 proto_tree_add_string(tree, hf_smb_primary_domain, tvb,
6118                         offset, an_len, an);
6119                 COUNT_BYTES(an_len);
6120         }
6121
6122         END_OF_SMB
6123
6124         /* call AndXCommand (if there are any) */
6125         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6126
6127         return offset;
6128 }
6129
6130
6131 static int
6132 dissect_empty_andx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6133 {
6134         guint8  wc, cmd=0xff;
6135         guint16 andxoffset=0;
6136         guint16 bc;
6137
6138         WORD_COUNT;
6139
6140         /* next smb command */
6141         cmd = tvb_get_guint8(tvb, offset);
6142         if(cmd!=0xff){
6143                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6144         } else {
6145                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6146         }
6147         offset += 1;
6148
6149         /* reserved byte */
6150         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6151         offset += 1;
6152
6153         /* andxoffset */
6154         andxoffset = tvb_get_letohs(tvb, offset);
6155         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6156         offset += 2;
6157
6158         BYTE_COUNT;
6159
6160         END_OF_SMB
6161
6162         /* call AndXCommand (if there are any) */
6163         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6164
6165         return offset;
6166 }
6167
6168
6169 static const true_false_string tfs_connect_support_search = {
6170         "Exclusive search bits supported",
6171         "Exclusive search bits not supported"
6172 };
6173 static const true_false_string tfs_connect_support_in_dfs = {
6174         "Share is in Dfs",
6175         "Share isn't in Dfs"
6176 };
6177
6178 static int
6179 dissect_connect_support_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6180 {
6181         guint16 mask;
6182         proto_item *item = NULL;
6183         proto_tree *tree = NULL;
6184
6185         mask = tvb_get_letohs(tvb, offset);
6186
6187         if(parent_tree){
6188                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6189                         "Optional Support: 0x%04x", mask);
6190                 tree = proto_item_add_subtree(item, ett_smb_connect_support_bits);
6191         }
6192
6193         proto_tree_add_boolean(tree, hf_smb_connect_support_search,
6194                 tvb, offset, 2, mask);
6195         proto_tree_add_boolean(tree, hf_smb_connect_support_in_dfs,
6196                 tvb, offset, 2, mask);
6197
6198         offset += 2;
6199
6200         return offset;
6201 }
6202
6203 static const true_false_string tfs_disconnect_tid = {
6204         "DISCONNECT TID",
6205         "Do NOT disconnect TID"
6206 };
6207
6208 static int
6209 dissect_connect_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6210 {
6211         guint16 mask;
6212         proto_item *item = NULL;
6213         proto_tree *tree = NULL;
6214
6215         mask = tvb_get_letohs(tvb, offset);
6216
6217         if(parent_tree){
6218                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
6219                         "Flags: 0x%04x", mask);
6220                 tree = proto_item_add_subtree(item, ett_smb_connect_flags);
6221         }
6222
6223         proto_tree_add_boolean(tree, hf_smb_connect_flags_dtid,
6224                 tvb, offset, 2, mask);
6225
6226         offset += 2;
6227
6228         return offset;
6229 }
6230
6231 static int
6232 dissect_tree_connect_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6233 {
6234         guint8  wc, cmd=0xff;
6235         guint16 bc;
6236         guint16 andxoffset=0, pwlen=0;
6237         smb_info_t *si = pinfo->private_data;
6238         int an_len;
6239         const char *an;
6240
6241         WORD_COUNT;
6242
6243         /* next smb command */
6244         cmd = tvb_get_guint8(tvb, offset);
6245         if(cmd!=0xff){
6246                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6247         } else {
6248                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6249         }
6250         offset += 1;
6251
6252         /* reserved byte */
6253         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6254         offset += 1;
6255
6256         /* andxoffset */
6257         andxoffset = tvb_get_letohs(tvb, offset);
6258         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6259         offset += 2;
6260
6261         /* flags */
6262         offset = dissect_connect_flags(tvb, tree, offset);
6263
6264         /* password length*/
6265         pwlen = tvb_get_letohs(tvb, offset);
6266         proto_tree_add_uint(tree, hf_smb_password_len, tvb, offset, 2, pwlen);
6267         offset += 2;
6268
6269         BYTE_COUNT;
6270
6271         /* password */
6272         CHECK_BYTE_COUNT(pwlen);
6273         proto_tree_add_item(tree, hf_smb_password,
6274                 tvb, offset, pwlen, TRUE);
6275         COUNT_BYTES(pwlen);
6276
6277         /* Path */
6278         an = get_unicode_or_ascii_string(tvb, &offset,
6279                 si->unicode, &an_len, FALSE, FALSE, &bc);
6280         if (an == NULL)
6281                 goto endofcommand;
6282         proto_tree_add_string(tree, hf_smb_path, tvb,
6283                 offset, an_len, an);
6284         COUNT_BYTES(an_len);
6285
6286         if (check_col(pinfo->cinfo, COL_INFO)) {
6287                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", an);
6288         }
6289
6290         /*
6291          * NOTE: the Service string is always ASCII, even if the
6292          * "strings are Unicode" bit is set in the flags2 field
6293          * of the SMB.
6294          */
6295
6296         /* Service */
6297         /* XXX - what if this runs past bc? */
6298         an_len = tvb_strsize(tvb, offset);
6299         CHECK_BYTE_COUNT(an_len);
6300         an = tvb_get_ptr(tvb, offset, an_len);
6301         proto_tree_add_string(tree, hf_smb_service, tvb,
6302                 offset, an_len, an);
6303         COUNT_BYTES(an_len);
6304
6305         END_OF_SMB
6306
6307         /* call AndXCommand (if there are any) */
6308         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6309
6310         return offset;
6311 }
6312
6313
6314 static int
6315 dissect_tree_connect_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
6316 {
6317         guint8  wc, wleft, cmd=0xff;
6318         guint16 andxoffset=0;
6319         guint16 bc;
6320         int an_len;
6321         const char *an;
6322         smb_info_t *si = pinfo->private_data;
6323
6324         WORD_COUNT;
6325
6326         wleft = wc;     /* this is at least 1 */
6327
6328         /* next smb command */
6329         cmd = tvb_get_guint8(tvb, offset);
6330         if(cmd!=0xff){
6331                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
6332         } else {
6333                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
6334         }
6335         offset += 1;
6336
6337         /* reserved byte */
6338         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
6339         offset += 1;
6340
6341         wleft--;
6342         if (wleft == 0)
6343                 goto bytecount;
6344
6345         /* andxoffset */
6346         andxoffset = tvb_get_letohs(tvb, offset);
6347         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
6348         offset += 2;
6349         wleft--;
6350         if (wleft == 0)
6351                 goto bytecount;
6352
6353         /* flags */
6354         offset = dissect_connect_support_bits(tvb, tree, offset);
6355         wleft--;
6356
6357         /* XXX - I've seen captures where this is 7, but I have no
6358            idea how to dissect it.  I'm guessing the third word
6359            contains connect support bits, which looks plausible
6360            from the values I've seen. */
6361
6362         while (wleft != 0) {
6363                 proto_tree_add_text(tree, tvb, offset, 2,
6364                     "Word parameter: 0x%04x", tvb_get_letohs(tvb, offset));
6365                 offset += 2;
6366                 wleft--;
6367         }
6368
6369         BYTE_COUNT;
6370
6371         /*
6372          * NOTE: even though the SNIA CIFS spec doesn't say there's
6373          * a "Service" string if there's a word count of 2, the
6374          * document at
6375          *
6376          *      ftp://ftp.microsoft.com/developr/drg/CIFS/dosextp.txt
6377          *
6378          * (it's in an ugly format - text intended to be sent to a
6379          * printer, with backspaces and overstrikes used for boldfacing
6380          * and underlining; UNIX "col -b" can be used to strip the
6381          * overstrikes out) says there's a "Service" string there, and
6382          * some network traffic has it.
6383          */
6384
6385         /*
6386          * NOTE: the Service string is always ASCII, even if the
6387          * "strings are Unicode" bit is set in the flags2 field
6388          * of the SMB.
6389          */
6390
6391         /* Service */
6392         /* XXX - what if this runs past bc? */
6393         an_len = tvb_strsize(tvb, offset);
6394         CHECK_BYTE_COUNT(an_len);
6395         an = tvb_get_ptr(tvb, offset, an_len);
6396         proto_tree_add_string(tree, hf_smb_service, tvb,
6397                 offset, an_len, an);
6398         COUNT_BYTES(an_len);
6399
6400         /* Now when we know the service type, store it so that we know it for later commands down
6401            this tree */
6402         if(!pinfo->fd->flags.visited){
6403                 /* Remove any previous entry for this TID */
6404                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
6405                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
6406                 }
6407                 if(strcmp(an,"IPC") == 0){
6408                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
6409                 } else {
6410                         g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_NORMAL);
6411                 }
6412         }
6413
6414
6415         if(wc==3){
6416                 if (bc != 0) {
6417                         /*
6418                          * Sometimes this isn't present.
6419                          */
6420
6421                         /* Native FS */
6422                         an = get_unicode_or_ascii_string(tvb, &offset,
6423                                 si->unicode, &an_len, /*TRUE*/FALSE, FALSE,
6424                                 &bc);
6425                         if (an == NULL)
6426                                 goto endofcommand;
6427                         proto_tree_add_string(tree, hf_smb_fs, tvb,
6428                                 offset, an_len, an);
6429                         COUNT_BYTES(an_len);
6430                 }
6431         }
6432
6433         END_OF_SMB
6434
6435         /* call AndXCommand (if there are any) */
6436         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
6437
6438         return offset;
6439 }
6440
6441
6442
6443 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6444    NT Transaction command  begins here
6445    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
6446 #define NT_TRANS_CREATE         1
6447 #define NT_TRANS_IOCTL          2
6448 #define NT_TRANS_SSD            3
6449 #define NT_TRANS_NOTIFY         4
6450 #define NT_TRANS_RENAME         5
6451 #define NT_TRANS_QSD            6
6452 #define NT_TRANS_GET_USER_QUOTA 7
6453 #define NT_TRANS_SET_USER_QUOTA 8
6454 const value_string nt_cmd_vals[] = {
6455         {NT_TRANS_CREATE,               "NT CREATE"},
6456         {NT_TRANS_IOCTL,                "NT IOCTL"},
6457         {NT_TRANS_SSD,                  "NT SET SECURITY DESC"},
6458         {NT_TRANS_NOTIFY,               "NT NOTIFY"},
6459         {NT_TRANS_RENAME,               "NT RENAME"},
6460         {NT_TRANS_QSD,                  "NT QUERY SECURITY DESC"},
6461         {NT_TRANS_GET_USER_QUOTA,       "NT GET USER QUOTA"},
6462         {NT_TRANS_SET_USER_QUOTA,       "NT SET USER QUOTA"},
6463         {0, NULL}
6464 };
6465
6466 static const value_string nt_ioctl_isfsctl_vals[] = {
6467         {0,     "Device IOCTL"},
6468         {1,     "FS control : FSCTL"},
6469         {0, NULL}
6470 };
6471
6472 #define NT_IOCTL_FLAGS_ROOT_HANDLE      0x01
6473 static const true_false_string tfs_nt_ioctl_flags_root_handle = {
6474         "Apply the command to share root handle (MUST BE Dfs)",
6475         "Apply to this share",
6476 };
6477
6478 static const value_string nt_notify_action_vals[] = {
6479         {1,     "ADDED (object was added"},
6480         {2,     "REMOVED (object was removed)"},
6481         {3,     "MODIFIED (object was modified)"},
6482         {4,     "RENAMED_OLD_NAME (this is the old name of object)"},
6483         {5,     "RENAMED_NEW_NAME (this is the new name of object)"},
6484         {6,     "ADDED_STREAM (a stream was added)"},
6485         {7,     "REMOVED_STREAM (a stream was removed)"},
6486         {8,     "MODIFIED_STREAM (a stream was modified)"},
6487         {0, NULL}
6488 };
6489
6490 static const value_string watch_tree_vals[] = {
6491         {0,     "Current directory only"},
6492         {1,     "Subdirectories also"},
6493         {0, NULL}
6494 };
6495
6496 #define NT_NOTIFY_STREAM_WRITE  0x00000800
6497 #define NT_NOTIFY_STREAM_SIZE   0x00000400
6498 #define NT_NOTIFY_STREAM_NAME   0x00000200
6499 #define NT_NOTIFY_SECURITY      0x00000100
6500 #define NT_NOTIFY_EA            0x00000080
6501 #define NT_NOTIFY_CREATION      0x00000040
6502 #define NT_NOTIFY_LAST_ACCESS   0x00000020
6503 #define NT_NOTIFY_LAST_WRITE    0x00000010
6504 #define NT_NOTIFY_SIZE          0x00000008
6505 #define NT_NOTIFY_ATTRIBUTES    0x00000004
6506 #define NT_NOTIFY_DIR_NAME      0x00000002
6507 #define NT_NOTIFY_FILE_NAME     0x00000001
6508 static const true_false_string tfs_nt_notify_stream_write = {
6509         "Notify on changes to STREAM WRITE",
6510         "Do NOT notify on changes to stream write",
6511 };
6512 static const true_false_string tfs_nt_notify_stream_size = {
6513         "Notify on changes to STREAM SIZE",
6514         "Do NOT notify on changes to stream size",
6515 };
6516 static const true_false_string tfs_nt_notify_stream_name = {
6517         "Notify on changes to STREAM NAME",
6518         "Do NOT notify on changes to stream name",
6519 };
6520 static const true_false_string tfs_nt_notify_security = {
6521         "Notify on changes to SECURITY",
6522         "Do NOT notify on changes to security",
6523 };
6524 static const true_false_string tfs_nt_notify_ea = {
6525         "Notify on changes to EA",
6526         "Do NOT notify on changes to EA",
6527 };
6528 static const true_false_string tfs_nt_notify_creation = {
6529         "Notify on changes to CREATION TIME",
6530         "Do NOT notify on changes to creation time",
6531 };
6532 static const true_false_string tfs_nt_notify_last_access = {
6533         "Notify on changes to LAST ACCESS TIME",
6534         "Do NOT notify on changes to last access time",
6535 };
6536 static const true_false_string tfs_nt_notify_last_write = {
6537         "Notify on changes to LAST WRITE TIME",
6538         "Do NOT notify on changes to last write time",
6539 };
6540 static const true_false_string tfs_nt_notify_size = {
6541         "Notify on changes to SIZE",
6542         "Do NOT notify on changes to size",
6543 };
6544 static const true_false_string tfs_nt_notify_attributes = {
6545         "Notify on changes to ATTRIBUTES",
6546         "Do NOT notify on changes to attributes",
6547 };
6548 static const true_false_string tfs_nt_notify_dir_name = {
6549         "Notify on changes to DIR NAME",
6550         "Do NOT notify on changes to dir name",
6551 };
6552 static const true_false_string tfs_nt_notify_file_name = {
6553         "Notify on changes to FILE NAME",
6554         "Do NOT notify on changes to file name",
6555 };
6556
6557 static const value_string create_disposition_vals[] = {
6558         {0,     "Supersede (supersede existing file (if it exists))"},
6559         {1,     "Open (if file exists open it, else fail)"},
6560         {2,     "Create (if file exists fail, else create it)"},
6561         {3,     "Open If (if file exists open it, else create it)"},
6562         {4,     "Overwrite (if file exists overwrite, else fail)"},
6563         {5,     "Overwrite If (if file exists overwrite, else create it)"},
6564         {0, NULL}
6565 };
6566
6567 static const value_string impersonation_level_vals[] = {
6568         {0,     "Anonymous"},
6569         {1,     "Identification"},
6570         {2,     "Impersonation"},
6571         {3,     "Delegation"},
6572         {0, NULL}
6573 };
6574
6575 static const true_false_string tfs_nt_security_flags_context_tracking = {
6576         "Security tracking mode is DYNAMIC",
6577         "Security tracking mode is STATIC",
6578 };
6579
6580 static const true_false_string tfs_nt_security_flags_effective_only = {
6581         "ONLY ENABLED aspects of the client's security context are available",
6582         "ALL aspects of the client's security context are available",
6583 };
6584
6585 static const true_false_string tfs_nt_create_bits_oplock = {
6586         "Requesting OPLOCK",
6587         "Does NOT request oplock"
6588 };
6589
6590 static const true_false_string tfs_nt_create_bits_boplock = {
6591         "Requesting BATCH OPLOCK",
6592         "Does NOT request batch oplock"
6593 };
6594
6595 /*
6596  * XXX - must be a directory, and can be a file, or can be a directory,
6597  * and must be a file?
6598  */
6599 static const true_false_string tfs_nt_create_bits_dir = {
6600         "Target of open MUST be a DIRECTORY",
6601         "Target of open can be a file"
6602 };
6603
6604 static const true_false_string tfs_nt_create_bits_ext_resp = {
6605   "Extended responses required",
6606   "Extended responses NOT required"
6607 };
6608
6609 static const true_false_string tfs_nt_access_mask_generic_read = {
6610         "GENERIC READ is set",
6611         "Generic read is NOT set"
6612 };
6613 static const true_false_string tfs_nt_access_mask_generic_write = {
6614         "GENERIC WRITE is set",
6615         "Generic write is NOT set"
6616 };
6617 static const true_false_string tfs_nt_access_mask_generic_execute = {
6618         "GENERIC EXECUTE is set",
6619         "Generic execute is NOT set"
6620 };
6621 static const true_false_string tfs_nt_access_mask_generic_all = {
6622         "GENERIC ALL is set",
6623         "Generic all is NOT set"
6624 };
6625 static const true_false_string tfs_nt_access_mask_maximum_allowed = {
6626         "MAXIMUM ALLOWED is set",
6627         "Maximum allowed is NOT set"
6628 };
6629 static const true_false_string tfs_nt_access_mask_system_security = {
6630         "SYSTEM SECURITY is set",
6631         "System security is NOT set"
6632 };
6633 static const true_false_string tfs_nt_access_mask_synchronize = {
6634         "Can wait on handle to SYNCHRONIZE on completion of I/O",
6635         "Can NOT wait on handle to synchronize on completion of I/O"
6636 };
6637 static const true_false_string tfs_nt_access_mask_write_owner = {
6638         "Can WRITE OWNER (take ownership)",
6639         "Can NOT write owner (take ownership)"
6640 };
6641 static const true_false_string tfs_nt_access_mask_write_dac = {
6642         "OWNER may WRITE the DAC",
6643         "Owner may NOT write to the DAC"
6644 };
6645 static const true_false_string tfs_nt_access_mask_read_control = {
6646         "READ ACCESS to owner, group and ACL of the SID",
6647         "Read access is NOT granted to owner, group and ACL of the SID"
6648 };
6649 static const true_false_string tfs_nt_access_mask_delete = {
6650         "DELETE access",
6651         "NO delete access"
6652 };
6653 static const true_false_string tfs_nt_access_mask_write_attributes = {
6654         "WRITE ATTRIBUTES access",
6655         "NO write attributes access"
6656 };
6657 static const true_false_string tfs_nt_access_mask_read_attributes = {
6658         "READ ATTRIBUTES access",
6659         "NO read attributes access"
6660 };
6661 static const true_false_string tfs_nt_access_mask_delete_child = {
6662         "DELETE CHILD access",
6663         "NO delete child access"
6664 };
6665 static const true_false_string tfs_nt_access_mask_execute = {
6666         "EXECUTE access",
6667         "NO execute access"
6668 };
6669 static const true_false_string tfs_nt_access_mask_write_ea = {
6670         "WRITE EXTENDED ATTRIBUTES access",
6671         "NO write extended attributes access"
6672 };
6673 static const true_false_string tfs_nt_access_mask_read_ea = {
6674         "READ EXTENDED ATTRIBUTES access",
6675         "NO read extended attributes access"
6676 };
6677 static const true_false_string tfs_nt_access_mask_append = {
6678         "APPEND access",
6679         "NO append access"
6680 };
6681 static const true_false_string tfs_nt_access_mask_write = {
6682         "WRITE access",
6683         "NO write access"
6684 };
6685 static const true_false_string tfs_nt_access_mask_read = {
6686         "READ access",
6687         "NO read access"
6688 };
6689
6690 static const true_false_string tfs_nt_share_access_delete = {
6691         "Object can be shared for DELETE",
6692         "Object can NOT be shared for delete"
6693 };
6694 static const true_false_string tfs_nt_share_access_write = {
6695         "Object can be shared for WRITE",
6696         "Object can NOT be shared for write"
6697 };
6698 static const true_false_string tfs_nt_share_access_read = {
6699         "Object can be shared for READ",
6700         "Object can NOT be shared for read"
6701 };
6702
6703 static const value_string oplock_level_vals[] = {
6704         {0,     "No oplock granted"},
6705         {1,     "Exclusive oplock granted"},
6706         {2,     "Batch oplock granted"},
6707         {3,     "Level II oplock granted"},
6708         {0, NULL}
6709 };
6710
6711 static const value_string device_type_vals[] = {
6712         {0x00000001,    "Beep"},
6713         {0x00000002,    "CDROM"},
6714         {0x00000003,    "CDROM Filesystem"},
6715         {0x00000004,    "Controller"},
6716         {0x00000005,    "Datalink"},
6717         {0x00000006,    "Dfs"},
6718         {0x00000007,    "Disk"},
6719         {0x00000008,    "Disk Filesystem"},
6720         {0x00000009,    "Filesystem"},
6721         {0x0000000a,    "Inport Port"},
6722         {0x0000000b,    "Keyboard"},
6723         {0x0000000c,    "Mailslot"},
6724         {0x0000000d,    "MIDI-In"},
6725         {0x0000000e,    "MIDI-Out"},
6726         {0x0000000f,    "Mouse"},
6727         {0x00000010,    "Multi UNC Provider"},
6728         {0x00000011,    "Named Pipe"},
6729         {0x00000012,    "Network"},
6730         {0x00000013,    "Network Browser"},
6731         {0x00000014,    "Network Filesystem"},
6732         {0x00000015,    "NULL"},
6733         {0x00000016,    "Parallel Port"},
6734         {0x00000017,    "Physical card"},
6735         {0x00000018,    "Printer"},
6736         {0x00000019,    "Scanner"},
6737         {0x0000001a,    "Serial Mouse port"},
6738         {0x0000001b,    "Serial port"},
6739         {0x0000001c,    "Screen"},
6740         {0x0000001d,    "Sound"},
6741         {0x0000001e,    "Streams"},
6742         {0x0000001f,    "Tape"},
6743         {0x00000020,    "Tape Filesystem"},
6744         {0x00000021,    "Transport"},
6745         {0x00000022,    "Unknown"},
6746         {0x00000023,    "Video"},
6747         {0x00000024,    "Virtual Disk"},
6748         {0x00000025,    "WAVE-In"},
6749         {0x00000026,    "WAVE-Out"},
6750         {0x00000027,    "8042 Port"},
6751         {0x00000028,    "Network Redirector"},
6752         {0x00000029,    "Battery"},
6753         {0x0000002a,    "Bus Extender"},
6754         {0x0000002b,    "Modem"},
6755         {0x0000002c,    "VDM"},
6756         {0,     NULL}
6757 };
6758
6759 static const value_string is_directory_vals[] = {
6760         {0,     "This is NOT a directory"},
6761         {1,     "This is a DIRECTORY"},
6762         {0, NULL}
6763 };
6764
6765 typedef struct _nt_trans_data {
6766         int subcmd;
6767         guint32 sd_len;
6768         guint32 ea_len;
6769 } nt_trans_data;
6770
6771
6772
6773 static int
6774 dissect_nt_security_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6775 {
6776         guint8 mask;
6777         proto_item *item = NULL;
6778         proto_tree *tree = NULL;
6779
6780         mask = tvb_get_guint8(tvb, offset);
6781
6782         if(parent_tree){
6783                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
6784                         "Security Flags: 0x%02x", mask);
6785                 tree = proto_item_add_subtree(item, ett_smb_nt_security_flags);
6786         }
6787
6788         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_context_tracking,
6789                 tvb, offset, 1, mask);
6790         proto_tree_add_boolean(tree, hf_smb_nt_security_flags_effective_only,
6791                 tvb, offset, 1, mask);
6792
6793         offset += 1;
6794
6795         return offset;
6796 }
6797
6798 static int
6799 dissect_nt_share_access(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6800 {
6801         guint32 mask;
6802         proto_item *item = NULL;
6803         proto_tree *tree = NULL;
6804
6805         mask = tvb_get_letohl(tvb, offset);
6806
6807         if(parent_tree){
6808                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6809                         "Share Access: 0x%08x", mask);
6810                 tree = proto_item_add_subtree(item, ett_smb_nt_share_access);
6811         }
6812
6813         proto_tree_add_boolean(tree, hf_smb_nt_share_access_delete,
6814                 tvb, offset, 4, mask);
6815         proto_tree_add_boolean(tree, hf_smb_nt_share_access_write,
6816                 tvb, offset, 4, mask);
6817         proto_tree_add_boolean(tree, hf_smb_nt_share_access_read,
6818                 tvb, offset, 4, mask);
6819
6820         offset += 4;
6821
6822         return offset;
6823 }
6824
6825 /* FIXME: need to call dissect_nt_access_mask() instead */
6826
6827 static int
6828 dissect_smb_access_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6829 {
6830         guint32 mask;
6831         proto_item *item = NULL;
6832         proto_tree *tree = NULL;
6833
6834         mask = tvb_get_letohl(tvb, offset);
6835
6836         if(parent_tree){
6837                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6838                         "Access Mask: 0x%08x", mask);
6839                 tree = proto_item_add_subtree(item, ett_smb_nt_access_mask);
6840         }
6841
6842         /*
6843          * Some of these bits come from
6844          *
6845          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6846          *
6847          * and others come from the section on ZwOpenFile in "Windows(R)
6848          * NT(R)/2000 Native API Reference".
6849          */
6850         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_read,
6851                 tvb, offset, 4, mask);
6852         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_write,
6853                 tvb, offset, 4, mask);
6854         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_execute,
6855                 tvb, offset, 4, mask);
6856         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_generic_all,
6857                 tvb, offset, 4, mask);
6858         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_maximum_allowed,
6859                 tvb, offset, 4, mask);
6860         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_system_security,
6861                 tvb, offset, 4, mask);
6862         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_synchronize,
6863                 tvb, offset, 4, mask);
6864         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_owner,
6865                 tvb, offset, 4, mask);
6866         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_dac,
6867                 tvb, offset, 4, mask);
6868         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_control,
6869                 tvb, offset, 4, mask);
6870         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete,
6871                 tvb, offset, 4, mask);
6872         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_attributes,
6873                 tvb, offset, 4, mask);
6874         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_attributes,
6875                 tvb, offset, 4, mask);
6876         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_delete_child,
6877                 tvb, offset, 4, mask);
6878         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_execute,
6879                 tvb, offset, 4, mask);
6880         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write_ea,
6881                 tvb, offset, 4, mask);
6882         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read_ea,
6883                 tvb, offset, 4, mask);
6884         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_append,
6885                 tvb, offset, 4, mask);
6886         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_write,
6887                 tvb, offset, 4, mask);
6888         proto_tree_add_boolean(tree, hf_smb_nt_access_mask_read,
6889                 tvb, offset, 4, mask);
6890
6891         offset += 4;
6892
6893         return offset;
6894 }
6895
6896 static int
6897 dissect_nt_create_bits(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6898 {
6899         guint32 mask;
6900         proto_item *item = NULL;
6901         proto_tree *tree = NULL;
6902
6903         mask = tvb_get_letohl(tvb, offset);
6904
6905         if(parent_tree){
6906                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
6907                         "Create Flags: 0x%08x", mask);
6908                 tree = proto_item_add_subtree(item, ett_smb_nt_create_bits);
6909         }
6910
6911         /*
6912          * XXX - it's 0x00000016 in at least one capture, but
6913          * Network Monitor doesn't say what the 0x00000010 bit is.
6914          * Does the Win32 API documentation, or NT Native API book,
6915          * suggest anything?
6916          *
6917          * That is the extended response desired bit ... RJS, from Samba
6918          * Well, maybe. Samba thinks it is, and uses it to encode
6919          * OpLock granted as the high order bit of the Action field
6920          * in the response. However, Windows does not do that. Or at least
6921          * Win2K doesn't.
6922          */
6923         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_ext_resp,
6924                                tvb, offset, 4, mask);
6925         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_dir,
6926                 tvb, offset, 4, mask);
6927         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_boplock,
6928                 tvb, offset, 4, mask);
6929         proto_tree_add_boolean(tree, hf_smb_nt_create_bits_oplock,
6930                 tvb, offset, 4, mask);
6931
6932         offset += 4;
6933
6934         return offset;
6935 }
6936
6937 /*
6938  * XXX - there are some more flags in the description of "ZwOpenFile()"
6939  * in "Windows(R) NT(R)/2000 Native API Reference"; do those go over
6940  * the wire as well?  (The spec at
6941  *
6942  *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
6943  *
6944  * says that "the FILE_NO_INTERMEDIATE_BUFFERING option is not exported
6945  * via the SMB protocol.  The NT redirector should convert this option
6946  * to FILE_WRITE_THROUGH."
6947  *
6948  * The "Sync I/O Alert" and "Sync I/O Nonalert" are given the bit
6949  * values one would infer from their position in the list of flags for
6950  * "ZwOpenFile()".  Most of the others probably have those values
6951  * as well, although "8.3 only" would collide with FILE_OPEN_FOR_RECOVERY,
6952  * which might go over the wire (for the benefit of backup/restore software).
6953  */
6954 static const true_false_string tfs_nt_create_options_directory = {
6955         "File being created/opened must be a directory",
6956         "File being created/opened must not be a directory"
6957 };
6958 static const true_false_string tfs_nt_create_options_write_through = {
6959         "Writes should flush buffered data before completing",
6960         "Writes need not flush buffered data before completing"
6961 };
6962 static const true_false_string tfs_nt_create_options_sequential_only = {
6963         "The file will only be accessed sequentially",
6964         "The file might not only be accessed sequentially"
6965 };
6966 static const true_false_string tfs_nt_create_options_sync_io_alert = {
6967         "All operations SYNCHRONOUS, waits subject to termination from alert",
6968         "Operations NOT necessarily synchronous"
6969 };
6970 static const true_false_string tfs_nt_create_options_sync_io_nonalert = {
6971         "All operations SYNCHRONOUS, waits not subject to alert",
6972         "Operations NOT necessarily synchronous"
6973 };
6974 static const true_false_string tfs_nt_create_options_non_directory = {
6975         "File being created/opened must not be a directory",
6976         "File being created/opened must be a directory"
6977 };
6978 static const true_false_string tfs_nt_create_options_no_ea_knowledge = {
6979         "The client does not understand extended attributes",
6980         "The client understands extended attributes"
6981 };
6982 static const true_false_string tfs_nt_create_options_eight_dot_three_only = {
6983         "The client understands only 8.3 file names",
6984         "The client understands long file names"
6985 };
6986 static const true_false_string tfs_nt_create_options_random_access = {
6987         "The file will be accessed randomly",
6988         "The file will not be accessed randomly"
6989 };
6990 static const true_false_string tfs_nt_create_options_delete_on_close = {
6991         "The file should be deleted when it is closed",
6992         "The file should not be deleted when it is closed"
6993 };
6994
6995 static int
6996 dissect_nt_create_options(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
6997 {
6998         guint32 mask;
6999         proto_item *item = NULL;
7000         proto_tree *tree = NULL;
7001
7002         mask = tvb_get_letohl(tvb, offset);
7003
7004         if(parent_tree){
7005                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7006                         "Create Options: 0x%08x", mask);
7007                 tree = proto_item_add_subtree(item, ett_smb_nt_create_options);
7008         }
7009
7010         /*
7011          * From
7012          *
7013          *      http://www.samba.org/samba/ftp/specs/smb-nt01.doc
7014          */
7015         proto_tree_add_boolean(tree, hf_smb_nt_create_options_directory_file,
7016                 tvb, offset, 4, mask);
7017         proto_tree_add_boolean(tree, hf_smb_nt_create_options_write_through,
7018                 tvb, offset, 4, mask);
7019         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sequential_only,
7020                 tvb, offset, 4, mask);
7021         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_alert,
7022                 tvb, offset, 4, mask);
7023         proto_tree_add_boolean(tree, hf_smb_nt_create_options_sync_io_nonalert,
7024                 tvb, offset, 4, mask);
7025         proto_tree_add_boolean(tree, hf_smb_nt_create_options_non_directory_file,
7026                 tvb, offset, 4, mask);
7027         proto_tree_add_boolean(tree, hf_smb_nt_create_options_no_ea_knowledge,
7028                 tvb, offset, 4, mask);
7029         proto_tree_add_boolean(tree, hf_smb_nt_create_options_eight_dot_three_only,
7030                 tvb, offset, 4, mask);
7031         proto_tree_add_boolean(tree, hf_smb_nt_create_options_random_access,
7032                 tvb, offset, 4, mask);
7033         proto_tree_add_boolean(tree, hf_smb_nt_create_options_delete_on_close,
7034                 tvb, offset, 4, mask);
7035
7036         offset += 4;
7037
7038         return offset;
7039 }
7040
7041 static int
7042 dissect_nt_notify_completion_filter(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7043 {
7044         guint32 mask;
7045         proto_item *item = NULL;
7046         proto_tree *tree = NULL;
7047
7048         mask = tvb_get_letohl(tvb, offset);
7049
7050         if(parent_tree){
7051                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7052                         "Completion Filter: 0x%08x", mask);
7053                 tree = proto_item_add_subtree(item, ett_smb_nt_notify_completion_filter);
7054         }
7055
7056         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_write,
7057                 tvb, offset, 4, mask);
7058         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_size,
7059                 tvb, offset, 4, mask);
7060         proto_tree_add_boolean(tree, hf_smb_nt_notify_stream_name,
7061                 tvb, offset, 4, mask);
7062         proto_tree_add_boolean(tree, hf_smb_nt_notify_security,
7063                 tvb, offset, 4, mask);
7064         proto_tree_add_boolean(tree, hf_smb_nt_notify_ea,
7065                 tvb, offset, 4, mask);
7066         proto_tree_add_boolean(tree, hf_smb_nt_notify_creation,
7067                 tvb, offset, 4, mask);
7068         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_access,
7069                 tvb, offset, 4, mask);
7070         proto_tree_add_boolean(tree, hf_smb_nt_notify_last_write,
7071                 tvb, offset, 4, mask);
7072         proto_tree_add_boolean(tree, hf_smb_nt_notify_size,
7073                 tvb, offset, 4, mask);
7074         proto_tree_add_boolean(tree, hf_smb_nt_notify_attributes,
7075                 tvb, offset, 4, mask);
7076         proto_tree_add_boolean(tree, hf_smb_nt_notify_dir_name,
7077                 tvb, offset, 4, mask);
7078         proto_tree_add_boolean(tree, hf_smb_nt_notify_file_name,
7079                 tvb, offset, 4, mask);
7080
7081         offset += 4;
7082         return offset;
7083 }
7084
7085 static int
7086 dissect_nt_ioctl_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7087 {
7088         guint8 mask;
7089         proto_item *item = NULL;
7090         proto_tree *tree = NULL;
7091
7092         mask = tvb_get_guint8(tvb, offset);
7093
7094         if(parent_tree){
7095                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7096                         "Completion Filter: 0x%02x", mask);
7097                 tree = proto_item_add_subtree(item, ett_smb_nt_ioctl_flags);
7098         }
7099
7100         proto_tree_add_boolean(tree, hf_smb_nt_ioctl_flags_root_handle,
7101                 tvb, offset, 1, mask);
7102
7103         offset += 1;
7104         return offset;
7105 }
7106
7107 /*
7108  * From the section on ZwQuerySecurityObject in "Windows(R) NT(R)/2000
7109  * Native API Reference".
7110  */
7111 static const true_false_string tfs_nt_qsd_owner = {
7112         "Requesting OWNER security information",
7113         "NOT requesting owner security information",
7114 };
7115
7116 static const true_false_string tfs_nt_qsd_group = {
7117         "Requesting GROUP security information",
7118         "NOT requesting group security information",
7119 };
7120
7121 static const true_false_string tfs_nt_qsd_dacl = {
7122         "Requesting DACL security information",
7123         "NOT requesting DACL security information",
7124 };
7125
7126 static const true_false_string tfs_nt_qsd_sacl = {
7127         "Requesting SACL security information",
7128         "NOT requesting SACL security information",
7129 };
7130
7131 #define NT_QSD_OWNER    0x00000001
7132 #define NT_QSD_GROUP    0x00000002
7133 #define NT_QSD_DACL     0x00000004
7134 #define NT_QSD_SACL     0x00000008
7135
7136 static int
7137 dissect_security_information_mask(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
7138 {
7139         guint32 mask;
7140         proto_item *item = NULL;
7141         proto_tree *tree = NULL;
7142
7143         mask = tvb_get_letohl(tvb, offset);
7144
7145         if(parent_tree){
7146                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
7147                         "Security Information: 0x%08x", mask);
7148                 tree = proto_item_add_subtree(item, ett_smb_security_information_mask);
7149         }
7150
7151         proto_tree_add_boolean(tree, hf_smb_nt_qsd_owner,
7152                 tvb, offset, 4, mask);
7153         proto_tree_add_boolean(tree, hf_smb_nt_qsd_group,
7154                 tvb, offset, 4, mask);
7155         proto_tree_add_boolean(tree, hf_smb_nt_qsd_dacl,
7156                 tvb, offset, 4, mask);
7157         proto_tree_add_boolean(tree, hf_smb_nt_qsd_sacl,
7158                 tvb, offset, 4, mask);
7159
7160         offset += 4;
7161
7162         return offset;
7163 }
7164
7165 static void
7166 free_g_string(void *arg)
7167 {
7168         g_string_free(arg, TRUE);
7169 }
7170
7171 /* Dissect a NT SID.  Label it with 'name' and return a string version of
7172    the SID in the 'sid_str' parameter which must be freed by the caller.
7173    hf_sid can be -1 if the caller doesnt care what name is used and then 
7174    "smb.sid" will be the default instead. If the caller wants a more
7175    appropriate hf field, it will just pass a FT_STRING hf field here
7176 */
7177
7178 int
7179 dissect_nt_sid(tvbuff_t *tvb, int offset, proto_tree *parent_tree, char *name,
7180                char **sid_str, int hf_sid)
7181 {
7182         proto_item *item = NULL;
7183         proto_tree *tree = NULL;
7184         int old_offset = offset, sa_offset = offset;
7185         gboolean rid_present;
7186         guint rid=0;
7187         int rid_offset=0;
7188         guint8 revision;
7189         int rev_offset;
7190         guint8 num_auth;
7191         int na_offset;
7192         guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
7193         int i;
7194         GString *gstr;
7195         char sid_string[245];
7196         char *sid_name;
7197
7198         if(hf_sid==-1){
7199                 hf_sid=hf_smb_sid;
7200         }
7201
7202         /* revision of sid */
7203         revision = tvb_get_guint8(tvb, offset);
7204         rev_offset = offset;
7205         offset += 1;
7206
7207         switch(revision){
7208         case 1:
7209         case 2:  /* Not sure what the different revision numbers mean */
7210           /* number of authorities*/
7211           num_auth = tvb_get_guint8(tvb, offset);
7212           na_offset = offset;
7213           offset += 1;
7214
7215           /* XXX perhaps we should have these thing searchable?
7216              a new FT_xxx thingie? SMB is quite common!*/
7217           /* identifier authorities */
7218
7219           for(i=0;i<6;i++){
7220             auth = (auth << 8) + tvb_get_guint8(tvb, offset);
7221
7222             offset++;
7223           }
7224
7225           sa_offset = offset;
7226
7227           gstr = g_string_new("");
7228
7229           CLEANUP_PUSH(free_g_string, gstr);
7230
7231           /* sub authorities, leave RID to last */
7232           for(i=0; i < (num_auth > 4?(num_auth - 1):num_auth); i++){
7233             /*
7234              * XXX should not be letohl but native byteorder according to
7235              * Samba header files.
7236              *
7237              * However, considering that there were never any NT ports
7238              * to big-endian platforms (PowerPC and MIPS ran little-endian,
7239              * and IA-64 runs little-endian, as does x86-64), we can (?)
7240              * assume that non le byte encodings will be "uncommon"?
7241              */
7242              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"),
7243                   tvb_get_letohl(tvb, offset));
7244              offset+=4;
7245           }
7246
7247
7248           if (num_auth > 4) {
7249             rid = tvb_get_letohl(tvb, offset);
7250             rid_present=TRUE;
7251             rid_offset=offset;
7252             offset+=4;
7253             sprintf(sid_string, "S-1-%u-%s-%u", auth, gstr->str, rid);
7254           } else {
7255             rid_present=FALSE;
7256             sprintf(sid_string, "S-1-%u-%s", auth, gstr->str);
7257           }
7258
7259           sid_name=NULL;
7260           if(sid_name_snooping){
7261             sid_name=find_sid_name(sid_string);
7262           }
7263
7264           if(parent_tree){
7265             if(sid_name){
7266               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);
7267             } else {
7268               item = proto_tree_add_string_format(parent_tree, hf_sid, tvb, old_offset, offset-old_offset, sid_string, "%s: %s", name, sid_string);
7269             }
7270             tree = proto_item_add_subtree(item, ett_smb_sid);
7271           }
7272
7273           proto_tree_add_item(tree, hf_smb_sid_revision, tvb, rev_offset, 1, TRUE);
7274           proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, na_offset, 1, TRUE);
7275           proto_tree_add_text(tree, tvb, na_offset+1, 6, "Authority: %u", auth);
7276           proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
7277
7278           if(rid_present){
7279             proto_tree_add_text(tree, tvb, rid_offset, 4, "RID: %u", rid);
7280           }
7281
7282           if(sid_str){
7283             if(sid_name){
7284               *sid_str = g_strdup_printf("%s (%s)", sid_string, sid_name);
7285             } else {
7286               *sid_str = g_strdup(sid_string);
7287             }
7288           }
7289
7290           CLEANUP_CALL_AND_POP;
7291         }
7292
7293
7294         return offset;
7295 }
7296
7297
7298 static const value_string ace_type_vals[] = {
7299   { 0, "Access Allowed"},
7300   { 1, "Access Denied"},
7301   { 2, "System Audit"},
7302   { 3, "System Alarm"},
7303   { 0, NULL}
7304 };
7305 static const true_false_string tfs_ace_flags_object_inherit = {
7306   "Subordinate files will inherit this ACE",
7307   "Subordinate files will not inherit this ACE"
7308 };
7309 static const true_false_string tfs_ace_flags_container_inherit = {
7310   "Subordinate containers will inherit this ACE",
7311   "Subordinate containers will not inherit this ACE"
7312 };
7313 static const true_false_string tfs_ace_flags_non_propagate_inherit = {
7314   "Subordinate object will not propagate the inherited ACE further",
7315   "Subordinate object will propagate the inherited ACE further"
7316 };
7317 static const true_false_string tfs_ace_flags_inherit_only = {
7318   "This ACE does not apply to the current object",
7319   "This ACE applies to the current object"
7320 };
7321 static const true_false_string tfs_ace_flags_inherited_ace = {
7322   "This ACE was inherited from its parent object",
7323   "This ACE was not inherited from its parent object"
7324 };
7325 static const true_false_string tfs_ace_flags_successful_access = {
7326   "Successful accesses will be audited",
7327   "Successful accesses will not be audited"
7328 };
7329 static const true_false_string tfs_ace_flags_failed_access = {
7330   "Failed accesses will be audited",
7331   "Failed accesses will not be audited"
7332 };
7333
7334 #define APPEND_ACE_TEXT(flag, item, string) \
7335         if(flag){                                                       \
7336                 if(item)                                                \
7337                         proto_item_append_text(item, string, sep);      \
7338                 sep = ", ";                                             \
7339         }
7340
7341 static int
7342 dissect_nt_v2_ace_flags(tvbuff_t *tvb, int offset, proto_tree *parent_tree,
7343                         guint8 *data)
7344 {
7345         proto_item *item = NULL;
7346         proto_tree *tree = NULL;
7347         guint8 mask;
7348         char *sep = " ";
7349
7350         mask = tvb_get_guint8(tvb, offset);
7351
7352         if (data)
7353                 *data = mask;
7354
7355
7356         if(parent_tree){
7357                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
7358                                            "NT ACE Flags: 0x%02x", mask);
7359                 tree = proto_item_add_subtree(item, ett_smb_ace_flags);
7360         }
7361
7362         proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
7363                        tvb, offset, 1, mask);
7364         APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
7365
7366         proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
7367                        tvb, offset, 1, mask);
7368         APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
7369
7370         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
7371                        tvb, offset, 1, mask);
7372         APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
7373
7374         proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
7375                        tvb, offset, 1, mask);
7376         APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
7377
7378         proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
7379                        tvb, offset, 1, mask);
7380         APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
7381
7382         proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
7383                        tvb, offset, 1, mask);
7384         APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
7385
7386         proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
7387                        tvb, offset, 1, mask);
7388         APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
7389
7390
7391         offset += 1;
7392         return offset;
7393 }
7394
7395 /* Dissect an access mask.  All this stuff is kind of explained at MSDN:
7396
7397 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/windows_2000_windows_nt_access_mask_format.asp
7398
7399 */
7400
7401 static gint ett_nt_access_mask = -1;
7402 static gint ett_nt_access_mask_generic = -1;
7403 static gint ett_nt_access_mask_standard = -1;
7404 static gint ett_nt_access_mask_specific = -1;
7405
7406 static int hf_access_sacl = -1;
7407 static int hf_access_maximum_allowed = -1;
7408 static int hf_access_generic_read = -1;
7409 static int hf_access_generic_write = -1;
7410 static int hf_access_generic_execute = -1;
7411 static int hf_access_generic_all = -1;
7412 static int hf_access_standard_delete = -1;
7413 static int hf_access_standard_read_control = -1;
7414 static int hf_access_standard_synchronise = -1;
7415 static int hf_access_standard_write_dac = -1;
7416 static int hf_access_standard_write_owner = -1;
7417 static int hf_access_specific_15 = -1;
7418 static int hf_access_specific_14 = -1;
7419 static int hf_access_specific_13 = -1;
7420 static int hf_access_specific_12 = -1;
7421 static int hf_access_specific_11 = -1;
7422 static int hf_access_specific_10 = -1;
7423 static int hf_access_specific_9 = -1;
7424 static int hf_access_specific_8 = -1;
7425 static int hf_access_specific_7 = -1;
7426 static int hf_access_specific_6 = -1;
7427 static int hf_access_specific_5 = -1;
7428 static int hf_access_specific_4 = -1;
7429 static int hf_access_specific_3 = -1;
7430 static int hf_access_specific_2 = -1;
7431 static int hf_access_specific_1 = -1;
7432 static int hf_access_specific_0 = -1;
7433
7434 /* Map generic permissions to specific permissions */
7435
7436 static void map_generic_access(guint32 *access_mask, 
7437                                struct generic_mapping *mapping)
7438 {
7439         if (*access_mask & GENERIC_READ_ACCESS) {
7440                 *access_mask &= ~GENERIC_READ_ACCESS;
7441                 *access_mask |= mapping->generic_read;
7442         }
7443
7444         if (*access_mask & GENERIC_WRITE_ACCESS) {
7445                 *access_mask &= ~GENERIC_WRITE_ACCESS;
7446                 *access_mask |= mapping->generic_write;
7447         }
7448
7449         if (*access_mask & GENERIC_EXECUTE_ACCESS) {
7450                 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
7451                 *access_mask |= mapping->generic_execute;
7452         }
7453
7454         if (*access_mask & GENERIC_ALL_ACCESS) {
7455                 *access_mask &= ~GENERIC_ALL_ACCESS;
7456                 *access_mask |= mapping->generic_all;
7457         }
7458 }
7459
7460 /* Map standard permissions to specific permissions */
7461
7462 static void map_standard_access(guint32 *access_mask,
7463                                 struct standard_mapping *mapping)
7464 {
7465         if (*access_mask & READ_CONTROL_ACCESS) {
7466                 *access_mask &= ~READ_CONTROL_ACCESS;
7467                 *access_mask |= mapping->std_read;
7468         }
7469
7470         if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
7471                             SYNCHRONIZE_ACCESS)) {
7472                 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|
7473                                   WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
7474                 *access_mask |= mapping->std_all;
7475         }
7476
7477 }
7478
7479 int
7480 dissect_nt_access_mask(tvbuff_t *tvb, gint offset, packet_info *pinfo,
7481                        proto_tree *tree, guint8 *drep, int hfindex,
7482                        struct access_mask_info *ami)
7483 {
7484         proto_item *item;
7485         proto_tree *subtree, *generic_tree, *standard_tree, *specific_tree;
7486         guint32 access;
7487
7488         if (drep != NULL) {
7489                 /*
7490                  * Called from a DCE RPC protocol dissector, for a
7491                  * protocol where a 32-bit NDR integer contains
7492                  * an NT access mask; extract the access mask
7493                  * with an NDR call.
7494                  */
7495                 offset = dissect_ndr_uint32(tvb, offset, pinfo, NULL, drep,
7496                                             hfindex, &access);
7497         } else {
7498                 /*
7499                  * Called from SMB, where the access mask is just a
7500                  * 4-byte little-endian quantity with no special
7501                  * NDR alignment requirement; extract it with
7502                  * "tvb_get_letohl()".
7503                  */
7504                 access = tvb_get_letohl(tvb, offset);
7505                 offset += 4;
7506         }
7507
7508         item = proto_tree_add_uint(tree, hfindex, tvb, offset - 4, 4, access);
7509
7510         subtree = proto_item_add_subtree(item, ett_nt_access_mask);
7511
7512         /* Generic access rights */
7513
7514         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7515                                    "Generic rights: 0x%08x",
7516                                    access & GENERIC_RIGHTS_MASK);
7517
7518         generic_tree = proto_item_add_subtree(
7519                 item, ett_nt_access_mask_generic);
7520
7521         proto_tree_add_boolean(
7522                 generic_tree, hf_access_generic_read, tvb, offset - 4, 4,
7523                 access);
7524
7525         proto_tree_add_boolean(
7526                 generic_tree, hf_access_generic_write, tvb, offset - 4, 4,
7527                 access);
7528
7529         proto_tree_add_boolean(
7530                 generic_tree, hf_access_generic_execute, tvb, offset - 4, 4,
7531                 access);
7532
7533         proto_tree_add_boolean(
7534                 generic_tree, hf_access_generic_all, tvb, offset - 4, 4,
7535                 access);
7536
7537         /* Reserved (??) */
7538
7539         proto_tree_add_boolean(
7540                 subtree, hf_access_maximum_allowed, tvb, offset - 4, 4,
7541                 access);
7542
7543         /* Access system security */
7544
7545         proto_tree_add_boolean(
7546                 subtree, hf_access_sacl, tvb, offset - 4, 4,
7547                 access);
7548
7549         /* Standard access rights */
7550
7551         item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7552                                    "Standard rights: 0x%08x",
7553                                    access & STANDARD_RIGHTS_MASK);
7554
7555         standard_tree = proto_item_add_subtree(
7556                 item, ett_nt_access_mask_standard);
7557
7558         proto_tree_add_boolean(
7559                 standard_tree, hf_access_standard_synchronise, tvb, 
7560                 offset - 4, 4, access);
7561
7562         proto_tree_add_boolean(
7563                 standard_tree, hf_access_standard_write_owner, tvb, 
7564                 offset - 4, 4, access);
7565
7566         proto_tree_add_boolean(
7567                 standard_tree, hf_access_standard_write_dac, tvb, 
7568                 offset - 4, 4, access);
7569
7570         proto_tree_add_boolean(
7571                 standard_tree, hf_access_standard_read_control, tvb, 
7572                 offset - 4, 4, access);
7573
7574         proto_tree_add_boolean(
7575                 standard_tree, hf_access_standard_delete, tvb, offset - 4, 4,
7576                 access);
7577
7578         /* Specific access rights.  Call the specific_rights_fn
7579            pointer if we have one, otherwise just display bits 0-15 in
7580            boring fashion. */
7581
7582         if (ami && ami->specific_rights_name)
7583                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7584                                            "%s specific rights: 0x%08x",
7585                                            ami->specific_rights_name,
7586                                            access & SPECIFIC_RIGHTS_MASK);
7587         else
7588                 item = proto_tree_add_text(subtree, tvb, offset - 4, 4,
7589                                            "Specific rights: 0x%08x",
7590                                            access & SPECIFIC_RIGHTS_MASK);
7591
7592         specific_tree = proto_item_add_subtree(
7593                 item, ett_nt_access_mask_specific);
7594
7595         if (ami && ami->specific_rights_fn) {
7596                 guint32 mapped_access = access;
7597                 proto_tree *specific_mapped;
7598
7599                 specific_mapped = proto_item_add_subtree(
7600                         item, ett_nt_access_mask_specific);
7601
7602                 ami->specific_rights_fn(
7603                         tvb, offset - 4, specific_tree, access);
7604
7605                 if (ami->generic_mapping)
7606                         map_generic_access(&access, ami->generic_mapping);
7607                 
7608                 if (ami->standard_mapping)
7609                         map_standard_access(&access, ami->standard_mapping);
7610
7611                 if (access != mapped_access) {
7612                         ami->specific_rights_fn(
7613                                 tvb, offset - 4, specific_mapped, 
7614                                 mapped_access);
7615                 }
7616                 
7617                 return offset;
7618         }
7619
7620         proto_tree_add_boolean(
7621                 specific_tree, hf_access_specific_15, tvb, offset - 4, 4,
7622                 access);
7623
7624         proto_tree_add_boolean(
7625                 specific_tree, hf_access_specific_14, tvb, offset - 4, 4,
7626                 access);
7627
7628         proto_tree_add_boolean(
7629                 specific_tree, hf_access_specific_13, tvb, offset - 4, 4,
7630                 access);
7631
7632         proto_tree_add_boolean(
7633                 specific_tree, hf_access_specific_12, tvb, offset - 4, 4,
7634                 access);
7635
7636         proto_tree_add_boolean(
7637                 specific_tree, hf_access_specific_11, tvb, offset - 4, 4,
7638                 access);
7639
7640         proto_tree_add_boolean(
7641                 specific_tree, hf_access_specific_10, tvb, offset - 4, 4,
7642                 access);
7643
7644         proto_tree_add_boolean(
7645                 specific_tree, hf_access_specific_9, tvb, offset - 4, 4,
7646                 access);
7647
7648         proto_tree_add_boolean(
7649                 specific_tree, hf_access_specific_8, tvb, offset - 4, 4,
7650                 access);
7651
7652         proto_tree_add_boolean(
7653                 specific_tree, hf_access_specific_7, tvb, offset - 4, 4,
7654                 access);
7655
7656         proto_tree_add_boolean(
7657                 specific_tree, hf_access_specific_6, tvb, offset - 4, 4,
7658                 access);
7659
7660         proto_tree_add_boolean(
7661                 specific_tree, hf_access_specific_5, tvb, offset - 4, 4,
7662                 access);
7663
7664         proto_tree_add_boolean(
7665                 specific_tree, hf_access_specific_4, tvb, offset - 4, 4,
7666                 access);
7667
7668         proto_tree_add_boolean(
7669                 specific_tree, hf_access_specific_3, tvb, offset - 4, 4,
7670                 access);
7671
7672         proto_tree_add_boolean(
7673                 specific_tree, hf_access_specific_2, tvb, offset - 4, 4,
7674                 access);
7675
7676         proto_tree_add_boolean(
7677                 specific_tree, hf_access_specific_1, tvb, offset - 4, 4,
7678                 access);
7679
7680         proto_tree_add_boolean(
7681                 specific_tree, hf_access_specific_0, tvb, offset - 4, 4,
7682                 access);
7683
7684         return offset;
7685 }
7686
7687 static int hf_smb_access_mask = -1;
7688
7689 static int
7690 dissect_nt_v2_ace(tvbuff_t *tvb, int offset, packet_info *pinfo,
7691                   proto_tree *parent_tree, guint8 *drep,
7692                   struct access_mask_info *ami)
7693 {
7694         proto_item *item = NULL;
7695         proto_tree *tree = NULL;
7696         int old_offset = offset;
7697         guint16 size;
7698         char *sid_str = NULL;
7699         guint8 type;
7700         guint8 flags;
7701
7702         if(parent_tree){
7703                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7704                                            "NT ACE: ");
7705                 tree = proto_item_add_subtree(item, ett_smb_ace);
7706         }
7707
7708         /* type */
7709         type = tvb_get_guint8(tvb, offset);
7710         proto_tree_add_uint(tree, hf_smb_ace_type, tvb, offset, 1, type);
7711         offset += 1;
7712
7713         /* flags */
7714         offset = dissect_nt_v2_ace_flags(tvb, offset, tree, &flags);
7715
7716         /* size */
7717         size = tvb_get_letohs(tvb, offset);
7718         proto_tree_add_uint(tree, hf_smb_ace_size, tvb, offset, 2, size);
7719         offset += 2;
7720
7721         /* access mask */
7722         offset = dissect_nt_access_mask(
7723                 tvb, offset, pinfo, tree, drep, hf_smb_access_mask, ami);
7724
7725         /* SID */
7726         offset = dissect_nt_sid(tvb, offset, tree, "ACE", &sid_str, -1);
7727
7728         if (item)
7729                 proto_item_append_text(
7730                         item, "%s, flags 0x%02x, %s", sid_str, flags,
7731                         val_to_str(type, ace_type_vals, "Unknown ACE type (0x%02x)"));
7732
7733         g_free(sid_str);
7734
7735         proto_item_set_len(item, offset-old_offset);
7736
7737         /* Sometimes there is some spare space at the end of the ACE so use
7738            the size field to work out where the end is. */
7739
7740         return old_offset + size;
7741 }
7742
7743 static int
7744 dissect_nt_acl(tvbuff_t *tvb, int offset, packet_info *pinfo,
7745                proto_tree *parent_tree, guint8 *drep, char *name,
7746                struct access_mask_info *ami)
7747 {
7748         proto_item *item = NULL;
7749         proto_tree *tree = NULL;
7750         int old_offset = offset;
7751         guint8  revision;
7752         guint32 num_aces;
7753
7754         if(parent_tree){
7755                 item = proto_tree_add_text(parent_tree, tvb, offset, -1,
7756                                            "NT %s ACL", name);
7757                 tree = proto_item_add_subtree(item, ett_smb_acl);
7758         }
7759
7760         /* revision */
7761         revision = tvb_get_guint8(tvb, offset);
7762         proto_tree_add_uint(tree, hf_smb_acl_revision,
7763                 tvb, offset, 1, revision);
7764         offset += 2;
7765
7766         switch(revision){
7767         case 2:  /* only version we will ever see of this structure?*/
7768         case 3:
7769           /* size */
7770           proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
7771           offset += 2;
7772
7773           /* number of ace structures */
7774           num_aces = tvb_get_letohl(tvb, offset);
7775           proto_tree_add_uint(tree, hf_smb_acl_num_aces,
7776                               tvb, offset, 4, num_aces);
7777           offset += 4;
7778
7779           while(num_aces--){
7780             offset=dissect_nt_v2_ace(
7781                     tvb, offset, pinfo, tree, drep, ami);
7782           }
7783         }
7784
7785         proto_item_set_len(item, offset-old_offset);
7786         return offset;
7787 }
7788
7789 static const true_false_string tfs_sec_desc_type_owner_defaulted = {
7790   "OWNER is DEFAULTED",
7791   "Owner is NOT defaulted"
7792 };
7793 static const true_false_string tfs_sec_desc_type_group_defaulted = {
7794   "GROUP is DEFAULTED",
7795   "Group is NOT defaulted"
7796 };
7797 static const true_false_string tfs_sec_desc_type_dacl_present = {
7798   "DACL is PRESENT",
7799   "DACL is NOT present"
7800 };
7801 static const true_false_string tfs_sec_desc_type_dacl_defaulted = {
7802   "DACL is DEFAULTED",
7803   "DACL is NOT defaulted"
7804 };
7805 static const true_false_string tfs_sec_desc_type_sacl_present = {
7806   "SACL is PRESENT",
7807   "SACL is NOT present"
7808 };
7809 static const true_false_string tfs_sec_desc_type_sacl_defaulted = {
7810   "SACL is DEFAULTED",
7811   "SACL is NOT defaulted"
7812 };
7813 static const true_false_string tfs_sec_desc_type_dacl_auto_inherit_req = {
7814   "DACL has AUTO INHERIT REQUIRED",
7815   "DACL does NOT require auto inherit"
7816 };
7817 static const true_false_string tfs_sec_desc_type_sacl_auto_inherit_req = {
7818   "SACL has AUTO INHERIT REQUIRED",
7819   "SACL does NOT require auto inherit"
7820 };
7821 static const true_false_string tfs_sec_desc_type_dacl_auto_inherited = {
7822   "DACL is AUTO INHERITED",
7823   "DACL is NOT auto inherited"
7824 };
7825 static const true_false_string tfs_sec_desc_type_sacl_auto_inherited = {
7826   "SACL is AUTO INHERITED",
7827   "SACL is NOT auto inherited"
7828 };
7829 static const true_false_string tfs_sec_desc_type_dacl_protected = {
7830   "The DACL is PROTECTED",
7831   "The DACL is NOT protected"
7832 };
7833 static const true_false_string tfs_sec_desc_type_sacl_protected = {
7834   "The SACL is PROTECTED",
7835   "The SACL is NOT protected"
7836 };
7837 static const true_false_string tfs_sec_desc_type_self_relative = {
7838   "This SecDesc is SELF RELATIVE",
7839   "This SecDesc is NOT self relative"
7840 };
7841
7842
7843 static int
7844 dissect_nt_sec_desc_type(tvbuff_t *tvb, int offset, proto_tree *parent_tree)
7845 {
7846         proto_item *item = NULL;
7847         proto_tree *tree = NULL;
7848         guint16 mask;
7849
7850         mask = tvb_get_letohs(tvb, offset);
7851         if(parent_tree){
7852                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
7853                                            "Type: 0x%04x", mask);
7854                 tree = proto_item_add_subtree(item, ett_smb_sec_desc_type);
7855         }
7856
7857         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_self_relative,
7858                                tvb, offset, 2, mask);
7859         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_protected,
7860                                tvb, offset, 2, mask);
7861         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_protected,
7862                                tvb, offset, 2, mask);
7863         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherited,
7864                                tvb, offset, 2, mask);
7865         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherited,
7866                                tvb, offset, 2, mask);
7867         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_auto_inherit_req,
7868                                tvb, offset, 2, mask);
7869         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_auto_inherit_req,
7870                                tvb, offset, 2, mask);
7871         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_defaulted,
7872                                tvb, offset, 2, mask);
7873         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_sacl_present,
7874                                tvb, offset, 2, mask);
7875         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_defaulted,
7876                                tvb, offset, 2, mask);
7877         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_dacl_present,
7878                                tvb, offset, 2, mask);
7879         proto_tree_add_boolean(tree,hf_smb_sec_desc_type_group_defaulted,
7880                                tvb, offset, 2, mask);
7881         proto_tree_add_boolean(tree, hf_smb_sec_desc_type_owner_defaulted,
7882                                tvb, offset, 2, mask);
7883
7884
7885         offset += 2;
7886         return offset;
7887 }
7888
7889 int
7890 dissect_nt_sec_desc(tvbuff_t *tvb, int offset, packet_info *pinfo,
7891                     proto_tree *parent_tree, guint8 *drep, int len, 
7892                     struct access_mask_info *ami)
7893 {
7894         proto_item *item = NULL;
7895         proto_tree *tree = NULL;
7896         guint8 revision;
7897         int old_offset = offset;
7898         guint32 owner_sid_offset;
7899         guint32 group_sid_offset;
7900         guint32 sacl_offset;
7901         guint32 dacl_offset;
7902
7903         if(parent_tree){
7904                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
7905                                            "NT Security Descriptor");
7906                 tree = proto_item_add_subtree(item, ett_smb_sec_desc);
7907         }
7908
7909         /* revision */
7910         revision = tvb_get_guint8(tvb, offset);
7911         proto_tree_add_uint(tree, hf_smb_sec_desc_revision,
7912                 tvb, offset, 1, revision);
7913         offset += 1;
7914
7915         /* next byte should be zero, for now just ignore it */
7916         offset += 1;
7917
7918
7919         switch(revision){
7920         case 1:  /* only version we will ever see of this structure?*/
7921           /* type */
7922           offset = dissect_nt_sec_desc_type(tvb, offset, tree);
7923
7924           /* offset to owner sid */
7925           owner_sid_offset = tvb_get_letohl(tvb, offset);
7926           proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %u", owner_sid_offset);
7927           offset += 4;
7928
7929           /* offset to group sid */
7930           group_sid_offset = tvb_get_letohl(tvb, offset);
7931           proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %u", group_sid_offset);
7932           offset += 4;
7933
7934           /* offset to sacl */
7935           sacl_offset = tvb_get_letohl(tvb, offset);
7936           proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %u", sacl_offset);
7937           offset += 4;
7938
7939           /* offset to dacl */
7940           dacl_offset = tvb_get_letohl(tvb, offset);
7941           proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %u", dacl_offset);
7942           offset += 4;
7943
7944           /*owner SID*/
7945           if(owner_sid_offset){
7946             if (len == -1)
7947               offset = dissect_nt_sid(tvb, offset, tree, "Owner", NULL, -1);
7948             else
7949               dissect_nt_sid(
7950                       tvb, old_offset+owner_sid_offset, tree, "Owner", NULL, -1);
7951           }
7952
7953           /*group SID*/
7954           if(group_sid_offset){
7955             dissect_nt_sid(
7956                     tvb, old_offset+group_sid_offset, tree, "Group", NULL, -1);
7957           }
7958
7959           /* sacl */
7960           if(sacl_offset){
7961             dissect_nt_acl(tvb, old_offset+sacl_offset, pinfo, tree, 
7962                            drep, "System (SACL)", ami);
7963           }
7964
7965           /* dacl */
7966           if(dacl_offset){
7967             dissect_nt_acl(tvb, old_offset+dacl_offset, pinfo, tree, 
7968                            drep, "User (DACL)", ami);
7969           }
7970
7971         }
7972
7973         return offset+len;
7974 }
7975
7976 static int
7977 dissect_nt_user_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
7978 {
7979         int old_offset, old_sid_offset;
7980         guint32 qsize;
7981
7982         do {
7983                 old_offset=offset;
7984
7985                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7986                 qsize=tvb_get_letohl(tvb, offset);
7987                 proto_tree_add_uint(tree, hf_smb_user_quota_offset, tvb, offset, 4, qsize);
7988                 COUNT_BYTES_TRANS_SUBR(4);
7989
7990                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
7991                 /* length of SID */
7992                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
7993                 COUNT_BYTES_TRANS_SUBR(4);
7994
7995                 /* 16 unknown bytes */
7996                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
7997                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
7998                             offset, 8, TRUE);
7999                 COUNT_BYTES_TRANS_SUBR(8);
8000
8001                 /* number of bytes for used quota */
8002                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8003                 proto_tree_add_item(tree, hf_smb_user_quota_used, tvb, offset, 8, TRUE);
8004                 COUNT_BYTES_TRANS_SUBR(8);
8005
8006                 /* number of bytes for quota warning */
8007                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8008                 proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
8009                 COUNT_BYTES_TRANS_SUBR(8);
8010
8011                 /* number of bytes for quota limit */
8012                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
8013                 proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
8014                 COUNT_BYTES_TRANS_SUBR(8);
8015
8016                 /* SID of the user */
8017                 old_sid_offset=offset;
8018                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8019                 *bcp -= (offset-old_sid_offset);
8020
8021                 if(qsize){
8022                         offset = old_offset+qsize;
8023                 }
8024         }while(qsize);
8025
8026
8027         return offset;
8028 }
8029
8030
8031 static int
8032 dissect_nt_trans_data_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int bc, nt_trans_data *ntd)
8033 {
8034         proto_item *item = NULL;
8035         proto_tree *tree = NULL;
8036         smb_info_t *si;
8037         int old_offset = offset;
8038         guint16 bcp=bc; /* XXX fixme */
8039
8040         si = (smb_info_t *)pinfo->private_data;
8041
8042         if(parent_tree){
8043                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
8044                                 "%s Data",
8045                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8046                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8047         }
8048
8049         switch(ntd->subcmd){
8050         case NT_TRANS_CREATE:
8051                 /* security descriptor */
8052                 if(ntd->sd_len){
8053                         offset = dissect_nt_sec_desc(
8054                                 tvb, offset, pinfo, tree, NULL, ntd->sd_len, 
8055                                 NULL);
8056                 }
8057
8058                 /* extended attributes */
8059                 if(ntd->ea_len){
8060                         proto_tree_add_item(tree, hf_smb_extended_attributes, tvb, offset, ntd->ea_len, TRUE);
8061                         offset += ntd->ea_len;
8062                 }
8063
8064                 break;
8065         case NT_TRANS_IOCTL:
8066                 /* ioctl data */
8067                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, bc, TRUE);
8068                 offset += bc;
8069
8070                 break;
8071         case NT_TRANS_SSD:
8072                 offset = dissect_nt_sec_desc(
8073                         tvb, offset, pinfo, tree, NULL, bc, NULL);
8074                 break;
8075         case NT_TRANS_NOTIFY:
8076                 break;
8077         case NT_TRANS_RENAME:
8078                 /* XXX not documented */
8079                 break;
8080         case NT_TRANS_QSD:
8081                 break;
8082         case NT_TRANS_GET_USER_QUOTA:
8083                 /* unknown 4 bytes */
8084                 proto_tree_add_item(tree, hf_smb_unknown, tvb,
8085                             offset, 4, TRUE);
8086                 offset += 4;
8087
8088                 /* length of SID */
8089                 proto_tree_add_text(tree, tvb, offset, 4, "Length of SID: %d", tvb_get_letohl(tvb, offset));
8090                 offset +=4;
8091
8092                 offset = dissect_nt_sid(tvb, offset, tree, "Quota", NULL, -1);
8093                 break;
8094         case NT_TRANS_SET_USER_QUOTA:
8095                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8096                 break;
8097         }
8098
8099         /* ooops there were data we didnt know how to process */
8100         if((offset-old_offset) < bc){
8101                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset,
8102                     bc - (offset-old_offset), TRUE);
8103                 offset += bc - (offset-old_offset);
8104         }
8105
8106         return offset;
8107 }
8108
8109 static int
8110 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)
8111 {
8112         proto_item *item = NULL;
8113         proto_tree *tree = NULL;
8114         smb_info_t *si;
8115         guint32 fn_len;
8116         const char *fn;
8117
8118         si = (smb_info_t *)pinfo->private_data;
8119
8120         if(parent_tree){
8121                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8122                                 "%s Parameters",
8123                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8124                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8125         }
8126
8127         switch(ntd->subcmd){
8128         case NT_TRANS_CREATE:
8129                 /* Create flags */
8130                 offset = dissect_nt_create_bits(tvb, tree, offset);
8131                 bc -= 4;
8132
8133                 /* root directory fid */
8134                 proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
8135                 COUNT_BYTES(4);
8136
8137                 /* nt access mask */
8138                 offset = dissect_smb_access_mask(tvb, tree, offset);
8139                 bc -= 4;
8140
8141                 /* allocation size */
8142                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8143                 COUNT_BYTES(8);
8144
8145                 /* Extended File Attributes */
8146                 offset = dissect_file_ext_attr(tvb, tree, offset);
8147                 bc -= 4;
8148
8149                 /* share access */
8150                 offset = dissect_nt_share_access(tvb, tree, offset);
8151                 bc -= 4;
8152
8153                 /* create disposition */
8154                 proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
8155                 COUNT_BYTES(4);
8156
8157                 /* create options */
8158                 offset = dissect_nt_create_options(tvb, tree, offset);
8159                 bc -= 4;
8160
8161                 /* sd length */
8162                 ntd->sd_len = tvb_get_letohl(tvb, offset);
8163                 proto_tree_add_uint(tree, hf_smb_sd_length, tvb, offset, 4, ntd->sd_len);
8164                 COUNT_BYTES(4);
8165
8166                 /* ea length */
8167                 ntd->ea_len = tvb_get_letohl(tvb, offset);
8168                 proto_tree_add_uint(tree, hf_smb_ea_list_length, tvb, offset, 4, ntd->ea_len);
8169                 COUNT_BYTES(4);
8170
8171                 /* file name len */
8172                 fn_len = (guint32)tvb_get_letohl(tvb, offset);
8173                 proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8174                 COUNT_BYTES(4);
8175
8176                 /* impersonation level */
8177                 proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
8178                 COUNT_BYTES(4);
8179
8180                 /* security flags */
8181                 offset = dissect_nt_security_flags(tvb, tree, offset);
8182                 bc -= 1;
8183
8184                 /* file name */
8185                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8186                 if (fn != NULL) {
8187                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8188                                 fn);
8189                         COUNT_BYTES(fn_len);
8190                 }
8191
8192                 break;
8193         case NT_TRANS_IOCTL:
8194                 break;
8195         case NT_TRANS_SSD: {
8196                 guint16 fid;
8197
8198                 /* fid */
8199                 fid = tvb_get_letohs(tvb, offset);
8200                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8201                 offset += 2;
8202
8203                 /* 2 reserved bytes */
8204                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8205                 offset += 2;
8206
8207                 /* security information */
8208                 offset = dissect_security_information_mask(tvb, tree, offset);
8209                 break;
8210         }
8211         case NT_TRANS_NOTIFY:
8212                 break;
8213         case NT_TRANS_RENAME:
8214                 /* XXX not documented */
8215                 break;
8216         case NT_TRANS_QSD: {
8217                 guint16 fid;
8218
8219                 /* fid */
8220                 fid = tvb_get_letohs(tvb, offset);
8221                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8222                 offset += 2;
8223
8224                 /* 2 reserved bytes */
8225                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8226                 offset += 2;
8227
8228                 /* security information */
8229                 offset = dissect_security_information_mask(tvb, tree, offset);
8230                 break;
8231         }
8232         case NT_TRANS_GET_USER_QUOTA:
8233                 /* not decoded yet */
8234                 break;
8235         case NT_TRANS_SET_USER_QUOTA:
8236                 /* not decoded yet */
8237                 break;
8238         }
8239
8240         return offset;
8241 }
8242
8243 static int
8244 dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len, nt_trans_data *ntd)
8245 {
8246         proto_item *item = NULL;
8247         proto_tree *tree = NULL;
8248         smb_info_t *si;
8249         int old_offset = offset;
8250
8251         si = (smb_info_t *)pinfo->private_data;
8252
8253         if(parent_tree){
8254                 item = proto_tree_add_text(parent_tree, tvb, offset, len,
8255                                 "%s Setup",
8256                                 val_to_str(ntd->subcmd, nt_cmd_vals, "Unknown NT transaction (%u)"));
8257                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8258         }
8259
8260         switch(ntd->subcmd){
8261         case NT_TRANS_CREATE:
8262                 break;
8263         case NT_TRANS_IOCTL: {
8264                 guint16 fid;
8265
8266                 /* function code */
8267                 proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
8268                 offset += 4;
8269
8270                 /* fid */
8271                 fid = tvb_get_letohs(tvb, offset);
8272                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8273                 offset += 2;
8274
8275                 /* isfsctl */
8276                 proto_tree_add_item(tree, hf_smb_nt_ioctl_isfsctl, tvb, offset, 1, TRUE);
8277                 offset += 1;
8278
8279                 /* isflags */
8280                 offset = dissect_nt_ioctl_flags(tvb, tree, offset);
8281
8282                 break;
8283         }
8284         case NT_TRANS_SSD:
8285                 break;
8286         case NT_TRANS_NOTIFY: {
8287                 guint16 fid;
8288
8289                 /* completion filter */
8290                 offset = dissect_nt_notify_completion_filter(tvb, tree, offset);
8291
8292                 /* fid */
8293                 fid = tvb_get_letohs(tvb, offset);
8294                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8295                 offset += 2;
8296
8297                 /* watch tree */
8298                 proto_tree_add_item(tree, hf_smb_nt_notify_watch_tree, tvb, offset, 1, TRUE);
8299                 offset += 1;
8300
8301                 /* reserved byte */
8302                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8303                 offset += 1;
8304
8305                 break;
8306         }
8307         case NT_TRANS_RENAME:
8308                 /* XXX not documented */
8309                 break;
8310         case NT_TRANS_QSD:
8311                 break;
8312         case NT_TRANS_GET_USER_QUOTA:
8313                 /* not decoded yet */
8314                 break;
8315         case NT_TRANS_SET_USER_QUOTA:
8316                 /* not decoded yet */
8317                 break;
8318         }
8319
8320         return old_offset+len;
8321 }
8322
8323
8324 static int
8325 dissect_nt_transaction_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8326 {
8327         guint8 wc, sc;
8328         guint32 pc=0, po=0, pd, dc=0, od=0, dd;
8329         smb_info_t *si;
8330         smb_saved_info_t *sip;
8331         int subcmd;
8332         nt_trans_data ntd;
8333         guint16 bc;
8334         int padcnt;
8335         smb_nt_transact_info_t *nti;
8336
8337         si = (smb_info_t *)pinfo->private_data;
8338         sip = si->sip;
8339
8340         WORD_COUNT;
8341
8342         if(wc>=19){
8343                 /* primary request */
8344                 /* max setup count */
8345                 proto_tree_add_item(tree, hf_smb_max_setup_count, tvb, offset, 1, TRUE);
8346                 offset += 1;
8347
8348                 /* 2 reserved bytes */
8349                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
8350                 offset += 2;
8351         } else {
8352                 /* secondary request */
8353                 /* 3 reserved bytes */
8354                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8355                 offset += 3;
8356         }
8357
8358
8359         /* total param count */
8360         proto_tree_add_item(tree, hf_smb_total_param_count, tvb, offset, 4, TRUE);
8361         offset += 4;
8362
8363         /* total data count */
8364         proto_tree_add_item(tree, hf_smb_total_data_count, tvb, offset, 4, TRUE);
8365         offset += 4;
8366
8367         if(wc>=19){
8368                 /* primary request */
8369                 /* max param count */
8370                 proto_tree_add_item(tree, hf_smb_max_param_count, tvb, offset, 4, TRUE);
8371                 offset += 4;
8372
8373                 /* max data count */
8374                 proto_tree_add_item(tree, hf_smb_max_data_count, tvb, offset, 4, TRUE);
8375                 offset += 4;
8376         }
8377
8378         /* param count */
8379         pc = tvb_get_letohl(tvb, offset);
8380         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8381         offset += 4;
8382
8383         /* param offset */
8384         po = tvb_get_letohl(tvb, offset);
8385         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8386         offset += 4;
8387
8388         /* param displacement */
8389         if(wc>=19){
8390                 /* primary request*/
8391                 pd = 0;
8392         } else {
8393                 /* secondary request */
8394                 pd = tvb_get_letohl(tvb, offset);
8395                 proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8396                 offset += 4;
8397         }
8398
8399         /* data count */
8400         dc = tvb_get_letohl(tvb, offset);
8401         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8402         offset += 4;
8403
8404         /* data offset */
8405         od = tvb_get_letohl(tvb, offset);
8406         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8407         offset += 4;
8408
8409         /* data displacement */
8410         if(wc>=19){
8411                 /* primary request */
8412                 dd = 0;
8413         } else {
8414                 /* secondary request */
8415                 dd = tvb_get_letohl(tvb, offset);
8416                 proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8417                 offset += 4;
8418         }
8419
8420         /* setup count */
8421         if(wc>=19){
8422                 /* primary request */
8423                 sc = tvb_get_guint8(tvb, offset);
8424                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8425                 offset += 1;
8426         } else {
8427                 /* secondary request */
8428                 sc = 0;
8429         }
8430
8431         /* function */
8432         if(wc>=19){
8433                 /* primary request */
8434                 subcmd = tvb_get_letohs(tvb, offset);
8435                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, offset, 2, subcmd);
8436                 if(check_col(pinfo->cinfo, COL_INFO)){
8437                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8438                                 val_to_str(subcmd, nt_cmd_vals, "<unknown>"));
8439                 }
8440                 ntd.subcmd = subcmd;
8441                 if (!si->unidir) {
8442                         if(!pinfo->fd->flags.visited){
8443                                 /*
8444                                  * Allocate a new smb_nt_transact_info_t
8445                                  * structure.
8446                                  */
8447                                 nti = g_mem_chunk_alloc(smb_nt_transact_info_chunk);
8448                                 nti->subcmd = subcmd;
8449                                 sip->extra_info = nti;
8450                         }
8451                 }
8452         } else {
8453                 /* secondary request */
8454                 if(check_col(pinfo->cinfo, COL_INFO)){
8455                         col_append_fstr(pinfo->cinfo, COL_INFO, " (secondary request)");
8456                 }
8457         }
8458         offset += 2;
8459
8460         /* this is a padding byte */
8461         if(offset%1){
8462                 /* pad byte */
8463                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 1, TRUE);
8464                 offset += 1;
8465         }
8466
8467         /* if there were any setup bytes, decode them */
8468         if(sc){
8469                 dissect_nt_trans_setup_request(tvb, pinfo, offset, tree, sc*2, &ntd);
8470                 offset += sc*2;
8471         }
8472
8473         BYTE_COUNT;
8474
8475         /* parameters */
8476         if(po>(guint32)offset){
8477                 /* We have some initial padding bytes.
8478                 */
8479                 padcnt = po-offset;
8480                 if (padcnt > bc)
8481                         padcnt = bc;
8482                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8483                 COUNT_BYTES(padcnt);
8484         }
8485         if(pc){
8486                 CHECK_BYTE_COUNT(pc);
8487                 dissect_nt_trans_param_request(tvb, pinfo, offset, tree, pc, &ntd, bc);
8488                 COUNT_BYTES(pc);
8489         }
8490
8491         /* data */
8492         if(od>(guint32)offset){
8493                 /* We have some initial padding bytes.
8494                 */
8495                 padcnt = od-offset;
8496                 if (padcnt > bc)
8497                         padcnt = bc;
8498                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8499                 COUNT_BYTES(padcnt);
8500         }
8501         if(dc){
8502                 CHECK_BYTE_COUNT(dc);
8503                 dissect_nt_trans_data_request(
8504                         tvb, pinfo, offset, tree, dc, &ntd);
8505                 COUNT_BYTES(dc);
8506         }
8507
8508         END_OF_SMB
8509
8510         return offset;
8511 }
8512
8513
8514
8515 static int
8516 dissect_nt_trans_data_response(tvbuff_t *tvb, packet_info *pinfo,
8517                                int offset, proto_tree *parent_tree, int len,
8518                                nt_trans_data *ntd _U_)
8519 {
8520         proto_item *item = NULL;
8521         proto_tree *tree = NULL;
8522         smb_info_t *si;
8523         smb_nt_transact_info_t *nti;
8524         guint16 bcp;
8525
8526         si = (smb_info_t *)pinfo->private_data;
8527         if (si->sip != NULL)
8528                 nti = si->sip->extra_info;
8529         else
8530                 nti = NULL;
8531
8532         if(parent_tree){
8533                 if(nti != NULL){
8534                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8535                                 "%s Data",
8536                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8537                 } else {
8538                         /*
8539                          * We never saw the request to which this is a
8540                          * response.
8541                          */
8542                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8543                                 "Unknown NT Transaction Data (matching request not seen)");
8544                 }
8545                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_data);
8546         }
8547
8548         if (nti == NULL) {
8549                 offset += len;
8550                 return offset;
8551         }
8552         switch(nti->subcmd){
8553         case NT_TRANS_CREATE:
8554                 break;
8555         case NT_TRANS_IOCTL:
8556                 /* ioctl data */
8557                 proto_tree_add_item(tree, hf_smb_nt_ioctl_data, tvb, offset, len, TRUE);
8558                 offset += len;
8559
8560                 break;
8561         case NT_TRANS_SSD:
8562                 break;
8563         case NT_TRANS_NOTIFY:
8564                 break;
8565         case NT_TRANS_RENAME:
8566                 /* XXX not documented */
8567                 break;
8568         case NT_TRANS_QSD: {
8569                 /*
8570                  * XXX - this is probably a SECURITY_DESCRIPTOR structure,
8571                  * which may be documented in the Win32 documentation
8572                  * somewhere.
8573                  */
8574                 offset = dissect_nt_sec_desc(
8575                         tvb, offset, pinfo, tree, NULL, len, NULL);
8576                 break;
8577         }
8578         case NT_TRANS_GET_USER_QUOTA:
8579                 bcp=len;
8580                 offset = dissect_nt_user_quota(tvb, tree, offset, &bcp);
8581                 break;
8582         case NT_TRANS_SET_USER_QUOTA:
8583                 /* not decoded yet */
8584                 break;
8585         }
8586
8587         return offset;
8588 }
8589
8590 static int
8591 dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo,
8592                                 int offset, proto_tree *parent_tree,
8593                                 int len, nt_trans_data *ntd _U_, guint16 bc)
8594 {
8595         proto_item *item = NULL;
8596         proto_tree *tree = NULL;
8597         guint32 fn_len;
8598         const char *fn;
8599         smb_info_t *si;
8600         smb_nt_transact_info_t *nti;
8601         guint16 fid;
8602         int old_offset;
8603         guint32 neo;
8604         int padcnt;
8605
8606         si = (smb_info_t *)pinfo->private_data;
8607         if (si->sip != NULL)
8608                 nti = si->sip->extra_info;
8609         else
8610                 nti = NULL;
8611
8612         if(parent_tree){
8613                 if(nti != NULL){
8614                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8615                                 "%s Parameters",
8616                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8617                 } else {
8618                         /*
8619                          * We never saw the request to which this is a
8620                          * response.
8621                          */
8622                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8623                                 "Unknown NT Transaction Parameters (matching request not seen)");
8624                 }
8625                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_param);
8626         }
8627
8628         if (nti == NULL) {
8629                 offset += len;
8630                 return offset;
8631         }
8632         switch(nti->subcmd){
8633         case NT_TRANS_CREATE:
8634                 /* oplock level */
8635                 proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
8636                 offset += 1;
8637
8638                 /* reserved byte */
8639                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
8640                 offset += 1;
8641
8642                 /* fid */
8643                 fid = tvb_get_letohs(tvb, offset);
8644                 add_fid(tvb, pinfo, tree, offset, 2, fid);
8645                 offset += 2;
8646
8647                 /* create action */
8648                 proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
8649                 offset += 4;
8650
8651                 /* ea error offset */
8652                 proto_tree_add_item(tree, hf_smb_ea_error_offset, tvb, offset, 4, TRUE);
8653                 offset += 4;
8654
8655                 /* create time */
8656                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8657                         hf_smb_create_time);
8658
8659                 /* access time */
8660                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8661                         hf_smb_access_time);
8662
8663                 /* last write time */
8664                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8665                         hf_smb_last_write_time);
8666
8667                 /* last change time */
8668                 offset = dissect_smb_64bit_time(tvb, tree, offset,
8669                         hf_smb_change_time);
8670
8671                 /* Extended File Attributes */
8672                 offset = dissect_file_ext_attr(tvb, tree, offset);
8673
8674                 /* allocation size */
8675                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
8676                 offset += 8;
8677
8678                 /* end of file */
8679                 proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
8680                 offset += 8;
8681
8682                 /* File Type */
8683                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
8684                 offset += 2;
8685
8686                 /* device state */
8687                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
8688
8689                 /* is directory */
8690                 proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
8691                 offset += 1;
8692                 break;
8693         case NT_TRANS_IOCTL:
8694                 break;
8695         case NT_TRANS_SSD:
8696                 break;
8697         case NT_TRANS_NOTIFY:
8698                 while(len){
8699                         old_offset = offset;
8700
8701                         /* next entry offset */
8702                         neo = tvb_get_letohl(tvb, offset);
8703                         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
8704                         COUNT_BYTES(4);
8705                         len -= 4;
8706                         /* broken implementations */
8707                         if(len<0)break;
8708
8709                         /* action */
8710                         proto_tree_add_item(tree, hf_smb_nt_notify_action, tvb, offset, 4, TRUE);
8711                         COUNT_BYTES(4);
8712                         len -= 4;
8713                         /* broken implementations */
8714                         if(len<0)break;
8715
8716                         /* file name len */
8717                         fn_len = (guint32)tvb_get_letohl(tvb, offset);
8718                         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
8719                         COUNT_BYTES(4);
8720                         len -= 4;
8721                         /* broken implementations */
8722                         if(len<0)break;
8723
8724                         /* file name */
8725                         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, &bc);
8726                         if (fn == NULL)
8727                                 break;
8728                         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
8729                                 fn);
8730                         COUNT_BYTES(fn_len);
8731                         len -= fn_len;
8732                         /* broken implementations */
8733                         if(len<0)break;
8734
8735                         if (neo == 0)
8736                                 break;  /* no more structures */
8737
8738                         /* skip to next structure */
8739                         padcnt = (old_offset + neo) - offset;
8740                         if (padcnt < 0) {
8741                                 /*
8742                                  * XXX - this is bogus; flag it?
8743                                  */
8744                                 padcnt = 0;
8745                         }
8746                         if (padcnt != 0) {
8747                                 COUNT_BYTES(padcnt);
8748                                 len -= padcnt;
8749                                 /* broken implementations */
8750                                 if(len<0)break;
8751                         }
8752                 }
8753                 break;
8754         case NT_TRANS_RENAME:
8755                 /* XXX not documented */
8756                 break;
8757         case NT_TRANS_QSD:
8758                 /*
8759                  * This appears to be the size of the security
8760                  * descriptor; the calling sequence of
8761                  * "ZwQuerySecurityObject()" suggests that it would
8762                  * be.  The actual security descriptor wouldn't
8763                  * follow if the max data count in the request
8764                  * was smaller; this lets the client know how
8765                  * big a buffer it needs to provide.
8766                  */
8767                 proto_tree_add_item(tree, hf_smb_sec_desc_len, tvb, offset, 4, TRUE);
8768                 offset += 4;
8769                 break;
8770         case NT_TRANS_GET_USER_QUOTA:
8771                 proto_tree_add_text(tree, tvb, offset, 4, "Size of returned Quota data: %d",
8772                         tvb_get_letohl(tvb, offset));
8773                 offset += 4;
8774                 break;
8775         case NT_TRANS_SET_USER_QUOTA:
8776                 /* not decoded yet */
8777                 break;
8778         }
8779
8780         return offset;
8781 }
8782
8783 static int
8784 dissect_nt_trans_setup_response(tvbuff_t *tvb, packet_info *pinfo,
8785                                 int offset, proto_tree *parent_tree,
8786                                 int len, nt_trans_data *ntd _U_)
8787 {
8788         proto_item *item = NULL;
8789         proto_tree *tree = NULL;
8790         smb_info_t *si;
8791         smb_nt_transact_info_t *nti;
8792
8793         si = (smb_info_t *)pinfo->private_data;
8794         if (si->sip != NULL)
8795                 nti = si->sip->extra_info;
8796         else
8797                 nti = NULL;
8798
8799         if(parent_tree){
8800                 if(nti != NULL){
8801                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8802                                 "%s Setup",
8803                                 val_to_str(nti->subcmd, nt_cmd_vals, "Unknown NT Transaction (%u)"));
8804                 } else {
8805                         /*
8806                          * We never saw the request to which this is a
8807                          * response.
8808                          */
8809                         item = proto_tree_add_text(parent_tree, tvb, offset, len,
8810                                 "Unknown NT Transaction Setup (matching request not seen)");
8811                 }
8812                 tree = proto_item_add_subtree(item, ett_smb_nt_trans_setup);
8813         }
8814
8815         if (nti == NULL) {
8816                 offset += len;
8817                 return offset;
8818         }
8819         switch(nti->subcmd){
8820         case NT_TRANS_CREATE:
8821                 break;
8822         case NT_TRANS_IOCTL:
8823                 break;
8824         case NT_TRANS_SSD:
8825                 break;
8826         case NT_TRANS_NOTIFY:
8827                 break;
8828         case NT_TRANS_RENAME:
8829                 /* XXX not documented */
8830                 break;
8831         case NT_TRANS_QSD:
8832                 break;
8833         case NT_TRANS_GET_USER_QUOTA:
8834                 /* not decoded yet */
8835                 break;
8836         case NT_TRANS_SET_USER_QUOTA:
8837                 /* not decoded yet */
8838                 break;
8839         }
8840
8841         return offset;
8842 }
8843
8844 static int
8845 dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
8846 {
8847         guint8 wc, sc;
8848         guint32 pc=0, po=0, pd=0, dc=0, od=0, dd=0;
8849         guint32 td=0, tp=0;
8850         smb_info_t *si;
8851         smb_nt_transact_info_t *nti;
8852         static nt_trans_data ntd;
8853         guint16 bc;
8854         int padcnt;
8855         fragment_data *r_fd = NULL;
8856         tvbuff_t *pd_tvb=NULL;
8857         gboolean save_fragmented;
8858
8859         si = (smb_info_t *)pinfo->private_data;
8860         if (si->sip != NULL)
8861                 nti = si->sip->extra_info;
8862         else
8863                 nti = NULL;
8864
8865         /* primary request */
8866         if(nti != NULL){
8867                 proto_tree_add_uint(tree, hf_smb_nt_trans_subcmd, tvb, 0, 0, nti->subcmd);
8868                 if(check_col(pinfo->cinfo, COL_INFO)){
8869                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
8870                                 val_to_str(nti->subcmd, nt_cmd_vals, "<unknown (%u)>"));
8871                 }
8872         } else {
8873                 proto_tree_add_text(tree, tvb, offset, 0,
8874                         "Function: <unknown function - could not find matching request>");
8875                 if(check_col(pinfo->cinfo, COL_INFO)){
8876                         col_append_fstr(pinfo->cinfo, COL_INFO, ", <unknown>");
8877                 }
8878         }
8879
8880         WORD_COUNT;
8881
8882         /* 3 reserved bytes */
8883         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
8884         offset += 3;
8885
8886         /* total param count */
8887         tp = tvb_get_letohl(tvb, offset);
8888         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 4, tp);
8889         offset += 4;
8890
8891         /* total data count */
8892         td = tvb_get_letohl(tvb, offset);
8893         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 4, td);
8894         offset += 4;
8895
8896         /* param count */
8897         pc = tvb_get_letohl(tvb, offset);
8898         proto_tree_add_uint(tree, hf_smb_param_count32, tvb, offset, 4, pc);
8899         offset += 4;
8900
8901         /* param offset */
8902         po = tvb_get_letohl(tvb, offset);
8903         proto_tree_add_uint(tree, hf_smb_param_offset32, tvb, offset, 4, po);
8904         offset += 4;
8905
8906         /* param displacement */
8907         pd = tvb_get_letohl(tvb, offset);
8908         proto_tree_add_uint(tree, hf_smb_param_disp32, tvb, offset, 4, pd);
8909         offset += 4;
8910
8911         /* data count */
8912         dc = tvb_get_letohl(tvb, offset);
8913         proto_tree_add_uint(tree, hf_smb_data_count32, tvb, offset, 4, dc);
8914         offset += 4;
8915
8916         /* data offset */
8917         od = tvb_get_letohl(tvb, offset);
8918         proto_tree_add_uint(tree, hf_smb_data_offset32, tvb, offset, 4, od);
8919         offset += 4;
8920
8921         /* data displacement */
8922         dd = tvb_get_letohl(tvb, offset);
8923         proto_tree_add_uint(tree, hf_smb_data_disp32, tvb, offset, 4, dd);
8924         offset += 4;
8925
8926         /* setup count */
8927         sc = tvb_get_guint8(tvb, offset);
8928         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
8929         offset += 1;
8930
8931         /* setup data */
8932         if(sc){
8933                 dissect_nt_trans_setup_response(tvb, pinfo, offset, tree, sc*2, &ntd);
8934                 offset += sc*2;
8935         }
8936
8937         BYTE_COUNT;
8938
8939         /* reassembly of SMB NT Transaction data payload.
8940            In this section we do reassembly of both the data and parameters
8941            blocks of the SMB transaction command.
8942         */
8943         save_fragmented = pinfo->fragmented;
8944         /* do we need reassembly? */
8945         if( (td&&(td!=dc)) || (tp&&(tp!=pc)) ){
8946                 /* oh yeah, either data or parameter section needs
8947                    reassembly...
8948                 */
8949                 pinfo->fragmented = TRUE;
8950                 if(smb_trans_reassembly){
8951                         /* ...and we were told to do reassembly */
8952                         if(pc && ((unsigned int)tvb_length_remaining(tvb, po)>=pc) ){
8953                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8954                                                              po, pc, pd, td+tp);
8955
8956                         }
8957                         if((r_fd==NULL) && dc && ((unsigned int)tvb_length_remaining(tvb, od)>=dc) ){
8958                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
8959                                                              od, dc, dd+tp, td+tp);
8960                         }
8961                 }
8962         }
8963
8964         /* if we got a reassembled fd structure from the reassembly routine we
8965            must create pd_tvb from it
8966         */
8967         if(r_fd){
8968                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
8969                                              r_fd->datalen);
8970                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
8971                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
8972
8973                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
8974         }
8975
8976
8977         if(pd_tvb){
8978           /* we have reassembled data, grab param and data from there */
8979           dissect_nt_trans_param_response(pd_tvb, pinfo, 0, tree, tp,
8980                                           &ntd, (guint16) tvb_length(pd_tvb));
8981           dissect_nt_trans_data_response(pd_tvb, pinfo, tp, tree, td, &ntd);
8982         } else {
8983           /* we do not have reassembled data, just use what we have in the
8984              packet as well as we can */
8985           /* parameters */
8986           if(po>(guint32)offset){
8987             /* We have some initial padding bytes.
8988              */
8989             padcnt = po-offset;
8990             if (padcnt > bc)
8991               padcnt = bc;
8992             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
8993             COUNT_BYTES(padcnt);
8994           }
8995           if(pc){
8996             CHECK_BYTE_COUNT(pc);
8997             dissect_nt_trans_param_response(tvb, pinfo, offset, tree, pc, &ntd, bc);
8998             COUNT_BYTES(pc);
8999           }
9000
9001           /* data */
9002           if(od>(guint32)offset){
9003             /* We have some initial padding bytes.
9004              */
9005             padcnt = od-offset;
9006             if (padcnt > bc)
9007               padcnt = bc;
9008             proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
9009             COUNT_BYTES(padcnt);
9010           }
9011           if(dc){
9012             CHECK_BYTE_COUNT(dc);
9013             dissect_nt_trans_data_response(tvb, pinfo, offset, tree, dc, &ntd);
9014             COUNT_BYTES(dc);
9015           }
9016         }
9017         pinfo->fragmented = save_fragmented;
9018
9019         END_OF_SMB
9020
9021         return offset;
9022 }
9023
9024 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9025    NT Transaction command  ends here
9026    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9027
9028 static const value_string print_mode_vals[] = {
9029         {0,     "Text Mode"},
9030         {1,     "Graphics Mode"},
9031         {0, NULL}
9032 };
9033
9034 static int
9035 dissect_open_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9036 {
9037         smb_info_t *si = pinfo->private_data;
9038         int fn_len;
9039         const char *fn;
9040         guint8 wc;
9041         guint16 bc;
9042
9043         WORD_COUNT;
9044
9045         /* setup len */
9046         proto_tree_add_item(tree, hf_smb_setup_len, tvb, offset, 2, TRUE);
9047         offset += 2;
9048
9049         /* print mode */
9050         proto_tree_add_item(tree, hf_smb_print_mode, tvb, offset, 2, TRUE);
9051         offset += 2;
9052
9053         BYTE_COUNT;
9054
9055         /* buffer format */
9056         CHECK_BYTE_COUNT(1);
9057         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9058         COUNT_BYTES(1);
9059
9060         /* print identifier */
9061         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, FALSE, &bc);
9062         if (fn == NULL)
9063                 goto endofcommand;
9064         proto_tree_add_string(tree, hf_smb_print_identifier, tvb, offset, fn_len,
9065                 fn);
9066         COUNT_BYTES(fn_len);
9067
9068         END_OF_SMB
9069
9070         return offset;
9071 }
9072
9073
9074 static int
9075 dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9076 {
9077         int cnt;
9078         guint8 wc;
9079         guint16 bc, fid;
9080
9081         WORD_COUNT;
9082
9083         /* fid */
9084         fid = tvb_get_letohs(tvb, offset);
9085         add_fid(tvb, pinfo, tree, offset, 2, fid);
9086         offset += 2;
9087
9088         BYTE_COUNT;
9089
9090         /* buffer format */
9091         CHECK_BYTE_COUNT(1);
9092         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9093         COUNT_BYTES(1);
9094
9095         /* data len */
9096         CHECK_BYTE_COUNT(2);
9097         cnt = tvb_get_letohs(tvb, offset);
9098         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, cnt);
9099         COUNT_BYTES(2);
9100
9101         /* file data */
9102         offset = dissect_file_data(tvb, tree, offset, (guint16) cnt, (guint16) cnt);
9103
9104         END_OF_SMB
9105
9106         return offset;
9107 }
9108
9109
9110 static const value_string print_status_vals[] = {
9111         {1,     "Held or Stopped"},
9112         {2,     "Printing"},
9113         {3,     "Awaiting print"},
9114         {4,     "In intercept"},
9115         {5,     "File had error"},
9116         {6,     "Printer error"},
9117         {0, NULL}
9118 };
9119
9120 static int
9121 dissect_get_print_queue_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9122 {
9123         guint8 wc;
9124         guint16 bc;
9125
9126         WORD_COUNT;
9127
9128         /* max count */
9129         proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
9130         offset += 2;
9131
9132         /* start index */
9133         proto_tree_add_item(tree, hf_smb_start_index, tvb, offset, 2, TRUE);
9134         offset += 2;
9135
9136         BYTE_COUNT;
9137
9138         END_OF_SMB
9139
9140         return offset;
9141 }
9142
9143 static int
9144 dissect_print_queue_element(tvbuff_t *tvb, packet_info *pinfo,
9145     proto_tree *parent_tree, int offset, guint16 *bcp, gboolean *trunc)
9146 {
9147         proto_item *item = NULL;
9148         proto_tree *tree = NULL;
9149         smb_info_t *si = pinfo->private_data;
9150         int fn_len;
9151         const char *fn;
9152
9153         if(parent_tree){
9154                 item = proto_tree_add_text(parent_tree, tvb, offset, 28,
9155                         "Queue entry");
9156                 tree = proto_item_add_subtree(item, ett_smb_print_queue_entry);
9157         }
9158
9159         /* queued time */
9160         CHECK_BYTE_COUNT_SUBR(4);
9161         offset = dissect_smb_datetime(tvb, tree, offset,
9162                 hf_smb_print_queue_date,
9163                 hf_smb_print_queue_dos_date, hf_smb_print_queue_dos_time, FALSE);
9164         *bcp -= 4;
9165
9166         /* status */
9167         CHECK_BYTE_COUNT_SUBR(1);
9168         proto_tree_add_item(tree, hf_smb_print_status, tvb, offset, 1, TRUE);
9169         COUNT_BYTES_SUBR(1);
9170
9171         /* spool file number */
9172         CHECK_BYTE_COUNT_SUBR(2);
9173         proto_tree_add_item(tree, hf_smb_print_spool_file_number, tvb, offset, 2, TRUE);
9174         COUNT_BYTES_SUBR(2);
9175
9176         /* spool file size */
9177         CHECK_BYTE_COUNT_SUBR(4);
9178         proto_tree_add_item(tree, hf_smb_print_spool_file_size, tvb, offset, 4, TRUE);
9179         COUNT_BYTES_SUBR(4);
9180
9181         /* reserved byte */
9182         CHECK_BYTE_COUNT_SUBR(1);
9183         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9184         COUNT_BYTES_SUBR(1);
9185
9186         /* file name */
9187         fn_len = 16;
9188         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, TRUE, TRUE, bcp);
9189         CHECK_STRING_SUBR(fn);
9190         proto_tree_add_string(tree, hf_smb_print_spool_file_name, tvb, offset, 16,
9191                 fn);
9192         COUNT_BYTES_SUBR(fn_len);
9193
9194         *trunc = FALSE;
9195         return offset;
9196 }
9197
9198 static int
9199 dissect_get_print_queue_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9200 {
9201         guint16 cnt=0, len;
9202         guint8 wc;
9203         guint16 bc;
9204         gboolean trunc;
9205
9206         WORD_COUNT;
9207
9208         /* count */
9209         cnt = tvb_get_letohs(tvb, offset);
9210         proto_tree_add_uint(tree, hf_smb_count, tvb, offset, 2, cnt);
9211         offset += 2;
9212
9213         /* restart index */
9214         proto_tree_add_item(tree, hf_smb_restart_index, tvb, offset, 2, TRUE);
9215         offset += 2;
9216
9217         BYTE_COUNT;
9218
9219         /* buffer format */
9220         CHECK_BYTE_COUNT(1);
9221         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9222         COUNT_BYTES(1);
9223
9224         /* data len */
9225         CHECK_BYTE_COUNT(2);
9226         len = tvb_get_letohs(tvb, offset);
9227         proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, len);
9228         COUNT_BYTES(2);
9229
9230         /* queue elements */
9231         while(cnt--){
9232                 offset = dissect_print_queue_element(tvb, pinfo, tree, offset,
9233                     &bc, &trunc);
9234                 if (trunc)
9235                         goto endofcommand;
9236         }
9237
9238         END_OF_SMB
9239
9240         return offset;
9241 }
9242
9243
9244 static int
9245 dissect_send_single_block_message_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9246 {
9247         int name_len;
9248         guint16 bc;
9249         guint8 wc;
9250         guint16 message_len;
9251
9252         WORD_COUNT;
9253
9254         BYTE_COUNT;
9255
9256         /* buffer format */
9257         CHECK_BYTE_COUNT(1);
9258         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9259         COUNT_BYTES(1);
9260
9261         /* originator name */
9262         /* XXX - what if this runs past bc? */
9263         name_len = tvb_strsize(tvb, offset);
9264         CHECK_BYTE_COUNT(name_len);
9265         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9266             name_len, TRUE);
9267         COUNT_BYTES(name_len);
9268
9269         /* buffer format */
9270         CHECK_BYTE_COUNT(1);
9271         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9272         COUNT_BYTES(1);
9273
9274         /* destination name */
9275         /* XXX - what if this runs past bc? */
9276         name_len = tvb_strsize(tvb, offset);
9277         CHECK_BYTE_COUNT(name_len);
9278         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9279             name_len, TRUE);
9280         COUNT_BYTES(name_len);
9281
9282         /* buffer format */
9283         CHECK_BYTE_COUNT(1);
9284         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9285         COUNT_BYTES(1);
9286
9287         /* message len */
9288         CHECK_BYTE_COUNT(2);
9289         message_len = tvb_get_letohs(tvb, offset);
9290         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9291             message_len);
9292         COUNT_BYTES(2);
9293
9294         /* message */
9295         CHECK_BYTE_COUNT(message_len);
9296         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9297             TRUE);
9298         COUNT_BYTES(message_len);
9299
9300         END_OF_SMB
9301
9302         return offset;
9303 }
9304
9305 static int
9306 dissect_send_multi_block_message_start_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9307 {
9308         int name_len;
9309         guint16 bc;
9310         guint8 wc;
9311
9312         WORD_COUNT;
9313
9314         BYTE_COUNT;
9315
9316         /* buffer format */
9317         CHECK_BYTE_COUNT(1);
9318         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9319         COUNT_BYTES(1);
9320
9321         /* originator name */
9322         /* XXX - what if this runs past bc? */
9323         name_len = tvb_strsize(tvb, offset);
9324         CHECK_BYTE_COUNT(name_len);
9325         proto_tree_add_item(tree, hf_smb_originator_name, tvb, offset,
9326             name_len, TRUE);
9327         COUNT_BYTES(name_len);
9328
9329         /* buffer format */
9330         CHECK_BYTE_COUNT(1);
9331         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9332         COUNT_BYTES(1);
9333
9334         /* destination name */
9335         /* XXX - what if this runs past bc? */
9336         name_len = tvb_strsize(tvb, offset);
9337         CHECK_BYTE_COUNT(name_len);
9338         proto_tree_add_item(tree, hf_smb_destination_name, tvb, offset,
9339             name_len, TRUE);
9340         COUNT_BYTES(name_len);
9341
9342         END_OF_SMB
9343
9344         return offset;
9345 }
9346
9347 static int
9348 dissect_message_group_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9349 {
9350         guint16 bc;
9351         guint8 wc;
9352
9353         WORD_COUNT;
9354
9355         /* message group ID */
9356         proto_tree_add_item(tree, hf_smb_mgid, tvb, offset, 2, TRUE);
9357         offset += 2;
9358
9359         BYTE_COUNT;
9360
9361         END_OF_SMB
9362
9363         return offset;
9364 }
9365
9366 static int
9367 dissect_send_multi_block_message_text_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9368 {
9369         guint16 bc;
9370         guint8 wc;
9371         guint16 message_len;
9372
9373         WORD_COUNT;
9374
9375         BYTE_COUNT;
9376
9377         /* buffer format */
9378         CHECK_BYTE_COUNT(1);
9379         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9380         COUNT_BYTES(1);
9381
9382         /* message len */
9383         CHECK_BYTE_COUNT(2);
9384         message_len = tvb_get_letohs(tvb, offset);
9385         proto_tree_add_uint(tree, hf_smb_message_len, tvb, offset, 2,
9386             message_len);
9387         COUNT_BYTES(2);
9388
9389         /* message */
9390         CHECK_BYTE_COUNT(message_len);
9391         proto_tree_add_item(tree, hf_smb_message, tvb, offset, message_len,
9392             TRUE);
9393         COUNT_BYTES(message_len);
9394
9395         END_OF_SMB
9396
9397         return offset;
9398 }
9399
9400 static int
9401 dissect_forwarded_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9402 {
9403         int name_len;
9404         guint16 bc;
9405         guint8 wc;
9406
9407         WORD_COUNT;
9408
9409         BYTE_COUNT;
9410
9411         /* buffer format */
9412         CHECK_BYTE_COUNT(1);
9413         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9414         COUNT_BYTES(1);
9415
9416         /* forwarded name */
9417         /* XXX - what if this runs past bc? */
9418         name_len = tvb_strsize(tvb, offset);
9419         CHECK_BYTE_COUNT(name_len);
9420         proto_tree_add_item(tree, hf_smb_forwarded_name, tvb, offset,
9421             name_len, TRUE);
9422         COUNT_BYTES(name_len);
9423
9424         END_OF_SMB
9425
9426         return offset;
9427 }
9428
9429 static int
9430 dissect_get_machine_name_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9431 {
9432         int name_len;
9433         guint16 bc;
9434         guint8 wc;
9435
9436         WORD_COUNT;
9437
9438         BYTE_COUNT;
9439
9440         /* buffer format */
9441         CHECK_BYTE_COUNT(1);
9442         proto_tree_add_item(tree, hf_smb_buffer_format, tvb, offset, 1, TRUE);
9443         COUNT_BYTES(1);
9444
9445         /* machine name */
9446         /* XXX - what if this runs past bc? */
9447         name_len = tvb_strsize(tvb, offset);
9448         CHECK_BYTE_COUNT(name_len);
9449         proto_tree_add_item(tree, hf_smb_machine_name, tvb, offset,
9450             name_len, TRUE);
9451         COUNT_BYTES(name_len);
9452
9453         END_OF_SMB
9454
9455         return offset;
9456 }
9457
9458
9459 static int
9460 dissect_nt_create_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9461 {
9462         guint8  wc, cmd=0xff;
9463         guint16 andxoffset=0;
9464         guint16 bc;
9465         smb_info_t *si = pinfo->private_data;
9466         int fn_len;
9467         const char *fn;
9468
9469         WORD_COUNT;
9470
9471         /* next smb command */
9472         cmd = tvb_get_guint8(tvb, offset);
9473         if(cmd!=0xff){
9474                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9475         } else {
9476                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9477         }
9478         offset += 1;
9479
9480         /* reserved byte */
9481         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9482         offset += 1;
9483
9484         /* andxoffset */
9485         andxoffset = tvb_get_letohs(tvb, offset);
9486         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9487         offset += 2;
9488
9489         /* reserved byte */
9490         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9491         offset += 1;
9492
9493         /* file name len */
9494         fn_len = tvb_get_letohs(tvb, offset);
9495         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 2, fn_len);
9496         offset += 2;
9497
9498         /* Create flags */
9499         offset = dissect_nt_create_bits(tvb, tree, offset);
9500
9501         /* root directory fid */
9502         proto_tree_add_item(tree, hf_smb_root_dir_fid, tvb, offset, 4, TRUE);
9503         offset += 4;
9504
9505         /* nt access mask */
9506         offset = dissect_smb_access_mask(tvb, tree, offset);
9507
9508         /* allocation size */
9509         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9510         offset += 8;
9511
9512         /* Extended File Attributes */
9513         offset = dissect_file_ext_attr(tvb, tree, offset);
9514
9515         /* share access */
9516         offset = dissect_nt_share_access(tvb, tree, offset);
9517
9518         /* create disposition */
9519         proto_tree_add_item(tree, hf_smb_nt_create_disposition, tvb, offset, 4, TRUE);
9520         offset += 4;
9521
9522         /* create options */
9523         offset = dissect_nt_create_options(tvb, tree, offset);
9524
9525         /* impersonation level */
9526         proto_tree_add_item(tree, hf_smb_nt_impersonation_level, tvb, offset, 4, TRUE);
9527         offset += 4;
9528
9529         /* security flags */
9530         offset = dissect_nt_security_flags(tvb, tree, offset);
9531
9532         BYTE_COUNT;
9533
9534         /* file name */
9535         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
9536         if (fn == NULL)
9537                 goto endofcommand;
9538         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
9539                 fn);
9540         COUNT_BYTES(fn_len);
9541
9542         if (check_col(pinfo->cinfo, COL_INFO)) {
9543                 col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s", fn);
9544         }
9545
9546         END_OF_SMB
9547
9548         /* call AndXCommand (if there are any) */
9549         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9550
9551         return offset;
9552 }
9553
9554
9555 static int
9556 dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
9557 {
9558         guint8  wc, cmd=0xff;
9559         guint16 andxoffset=0;
9560         guint16 bc;
9561         guint16 fid;
9562
9563         WORD_COUNT;
9564
9565         /* next smb command */
9566         cmd = tvb_get_guint8(tvb, offset);
9567         if(cmd!=0xff){
9568                 proto_tree_add_uint_format(tree, hf_smb_cmd, tvb, offset, 1, cmd, "AndXCommand: %s (0x%02x)", decode_smb_name(cmd), cmd);
9569         } else {
9570                 proto_tree_add_text(tree, tvb, offset, 1, "AndXCommand: No further commands (0xff)");
9571         }
9572         offset += 1;
9573
9574         /* reserved byte */
9575         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
9576         offset += 1;
9577
9578         /* andxoffset */
9579         andxoffset = tvb_get_letohs(tvb, offset);
9580         proto_tree_add_uint(tree, hf_smb_andxoffset, tvb, offset, 2, andxoffset);
9581         offset += 2;
9582
9583         /* oplock level */
9584         proto_tree_add_item(tree, hf_smb_oplock_level, tvb, offset, 1, TRUE);
9585         offset += 1;
9586
9587         /* fid */
9588         fid = tvb_get_letohs(tvb, offset);
9589         add_fid(tvb, pinfo, tree, offset, 2, fid);
9590         offset += 2;
9591
9592         /* create action */
9593         /*XXX is this really the same as create disposition in the request? it looks so*/
9594         /* No, it is not. It is the same as the create action from an Open&X request ... RJS */
9595         proto_tree_add_item(tree, hf_smb_create_action, tvb, offset, 4, TRUE);
9596         offset += 4;
9597
9598         /* create time */
9599         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
9600
9601         /* access time */
9602         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
9603
9604         /* last write time */
9605         offset = dissect_smb_64bit_time(tvb, tree, offset,
9606                 hf_smb_last_write_time);
9607
9608         /* last change time */
9609         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
9610
9611         /* Extended File Attributes */
9612         offset = dissect_file_ext_attr(tvb, tree, offset);
9613
9614         /* allocation size */
9615         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
9616         offset += 8;
9617
9618         /* end of file */
9619         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
9620         offset += 8;
9621
9622         /* File Type */
9623         proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
9624         offset += 2;
9625
9626         /* IPC State */
9627         offset = dissect_ipc_state(tvb, tree, offset, FALSE);
9628
9629         /* is directory */
9630         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
9631         offset += 1;
9632
9633         BYTE_COUNT;
9634
9635         END_OF_SMB
9636
9637         /* call AndXCommand (if there are any) */
9638         dissect_smb_command(tvb, pinfo, andxoffset, smb_tree, cmd, FALSE);
9639
9640         return offset;
9641 }
9642
9643
9644 static int
9645 dissect_nt_cancel_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
9646 {
9647         guint8 wc;
9648         guint16 bc;
9649
9650         WORD_COUNT;
9651
9652         BYTE_COUNT;
9653
9654         END_OF_SMB
9655
9656         return offset;
9657 }
9658
9659 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9660    BEGIN Transaction/Transaction2 Primary and secondary requests
9661    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
9662
9663
9664 const value_string trans2_cmd_vals[] = {
9665         { 0x00,         "OPEN2" },
9666         { 0x01,         "FIND_FIRST2" },
9667         { 0x02,         "FIND_NEXT2" },
9668         { 0x03,         "QUERY_FS_INFO" },
9669         { 0x04,         "SET_FS_QUOTA" },
9670         { 0x05,         "QUERY_PATH_INFO" },
9671         { 0x06,         "SET_PATH_INFO" },
9672         { 0x07,         "QUERY_FILE_INFO" },
9673         { 0x08,         "SET_FILE_INFO" },
9674         { 0x09,         "FSCTL" },
9675         { 0x0A,         "IOCTL2" },
9676         { 0x0B,         "FIND_NOTIFY_FIRST" },
9677         { 0x0C,         "FIND_NOTIFY_NEXT" },
9678         { 0x0D,         "CREATE_DIRECTORY" },
9679         { 0x0E,         "SESSION_SETUP" },
9680         { 0x10,         "GET_DFS_REFERRAL" },
9681         { 0x11,         "REPORT_DFS_INCONSISTENCY" },
9682         { 0,    NULL }
9683 };
9684
9685 static const true_false_string tfs_tf_dtid = {
9686         "Also DISCONNECT TID",
9687         "Do NOT disconnect TID"
9688 };
9689 static const true_false_string tfs_tf_owt = {
9690         "One Way Transaction (NO RESPONSE)",
9691         "Two way transaction"
9692 };
9693
9694 static const true_false_string tfs_ff2_backup = {
9695         "Find WITH backup intent",
9696         "No backup intent"
9697 };
9698 static const true_false_string tfs_ff2_continue = {
9699         "CONTINUE search from previous position",
9700         "New search, do NOT continue from previous position"
9701 };
9702 static const true_false_string tfs_ff2_resume = {
9703         "Return RESUME keys",
9704         "Do NOT return resume keys"
9705 };
9706 static const true_false_string tfs_ff2_close_eos = {
9707         "CLOSE search if END OF SEARCH is reached",
9708         "Do NOT close search if end of search reached"
9709 };
9710 static const true_false_string tfs_ff2_close = {
9711         "CLOSE search after this request",
9712         "Do NOT close search after this request"
9713 };
9714
9715 /* used by
9716    TRANS2_FIND_FIRST2
9717 */
9718 static const value_string ff2_il_vals[] = {
9719         { 1,            "Info Standard"},
9720         { 2,            "Info Query EA Size"},
9721         { 3,            "Info Query EAs From List"},
9722         { 0x0101,       "Find File Directory Info"},
9723         { 0x0102,       "Find File Full Directory Info"},
9724         { 0x0103,       "Find File Names Info"},
9725         { 0x0104,       "Find File Both Directory Info"},
9726         { 0x0202,       "Find File UNIX"},
9727         {0, NULL}
9728 };
9729
9730 /* values used by :
9731         TRANS2_QUERY_PATH_INFORMATION
9732         TRANS2_QUERY_FILE_INFORMATION
9733 */
9734 static const value_string qpi_loi_vals[] = {
9735         { 1,            "Info Standard"},
9736         { 2,            "Info Query EA Size"},
9737         { 3,            "Info Query EAs From List"},
9738         { 4,            "Info Query All EAs"},
9739         { 6,            "Info Is Name Valid"},
9740         { 0x0101,       "Query File Basic Info"},
9741         { 0x0102,       "Query File Standard Info"},
9742         { 0x0103,       "Query File EA Info"},
9743         { 0x0104,       "Query File Name Info"},
9744         { 0x0107,       "Query File All Info"},
9745         { 0x0108,       "Query File Alt Name Info"},
9746         { 0x0109,       "Query File Stream Info"},
9747         { 0x010b,       "Query File Compression Info"},
9748         { 0x0200,       "Query File Unix Basic"},
9749         { 0x0201,       "Query File Unix Link"},
9750         { 1004,         "Query File Basic Info"},
9751         { 1005,         "Query File Standard Info"},
9752         { 1006,         "Query File Internal Info"},
9753         { 1007,         "Query File EA Info"},
9754         { 1009,         "Query File Name Info"},
9755         { 1010,         "Query File Rename Info"},
9756         { 1011,         "Query File Link Info"},
9757         { 1012,         "Query File Names Info"},
9758         { 1013,         "Query File Disposition Info"},
9759         { 1014,         "Query File Position Info"},
9760         { 1015,         "Query File Full EA Info"},
9761         { 1016,         "Query File Mode Info"},
9762         { 1017,         "Query File Alignment Info"},
9763         { 1018,         "Query File All Info"},
9764         { 1019,         "Query File Allocation Info"},
9765         { 1020,         "Query File End of File Info"},
9766         { 1021,         "Query File Alt Name Info"},
9767         { 1022,         "Query File Stream Info"},
9768         { 1023,         "Query File Pipe Info"},
9769         { 1024,         "Query File Pipe Local Info"},
9770         { 1025,         "Query File Pipe Remote Info"},
9771         { 1026,         "Query File Mailslot Query Info"},
9772         { 1027,         "Query File Mailslot Set Info"},
9773         { 1028,         "Query File Compression Info"},
9774         { 1029,         "Query File ObjectID Info"},
9775         { 1030,         "Query File Completion Info"},
9776         { 1031,         "Query File Move Cluster Info"},
9777         { 1032,         "Query File Quota Info"},
9778         { 1033,         "Query File Reparsepoint Info"},
9779         { 1034,         "Query File Network Open Info"},
9780         { 1035,         "Query File Attribute Tag Info"},
9781         { 1036,         "Query File Tracking Info"},
9782         { 1037,         "Query File Maximum Info"},
9783         {0, NULL}
9784 };
9785
9786 /* values used by :
9787         TRANS2_SET_PATH_INFORMATION
9788         TRANS2_SET_FILE_INFORMATION
9789         (the SNIA CIFS spec lists some only for TRANS2_SET_FILE_INFORMATION,
9790         but I'm assuming they apply to TRANS2_SET_PATH_INFORMATION as
9791         well; note that they're different from the QUERY_PATH_INFORMATION
9792         and QUERY_FILE_INFORMATION values!)
9793 */
9794 static const value_string spi_loi_vals[] = {
9795         { 1,            "Info Standard"},
9796         { 2,            "Info Query EA Size"},
9797         { 4,            "Info Query All EAs"},
9798         { 0x0101,       "Set File Basic Info"},
9799         { 0x0102,       "Set File Disposition Info"},
9800         { 0x0103,       "Set File Allocation Info"},
9801         { 0x0104,       "Set File End Of File Info"},
9802         { 0x0200,       "Set File Unix Basic"},
9803         { 0x0201,       "Set File Unix Link"},
9804         { 0x0202,       "Set File Unix HardLink"},
9805         { 1004,         "Set File Basic Info"},
9806         { 1010,         "Set Rename Information"},
9807         { 1013,         "Set Disposition Information"},
9808         { 1014,         "Set Position Information"},
9809         { 1016,         "Set Mode Information"},
9810         { 1019,         "Set Allocation Information"},
9811         { 1020,         "Set EOF Information"},
9812         { 1023,         "Set File Pipe Information"},
9813         { 1025,         "Set File Pipe Remote Information"},
9814         { 1029,         "Set Copy On Write Information"},
9815         { 1032,         "Set OLE Class ID Information"},
9816         { 1039,         "Set Inherit Context Index Information"},
9817         { 1040,         "Set OLE Information (?)"},
9818         {0, NULL}
9819 };
9820
9821 static const value_string qfsi_vals[] = {
9822         { 1,            "Info Allocation"},
9823         { 2,            "Info Volume"},
9824         { 0x0101,       "Query FS Label Info"},
9825         { 0x0102,       "Query FS Volume Info"},
9826         { 0x0103,       "Query FS Size Info"},
9827         { 0x0104,       "Query FS Device Info"},
9828         { 0x0105,       "Query FS Attribute Info"},
9829         { 0x0200,       "Unix Query FS Info"},
9830         { 0x0301,       "Mac Query FS Info"},
9831         { 1001,         "Query FS Label Info"},
9832         { 1002,         "Query FS Volume Info"},
9833         { 1003,         "Query FS Size Info"},
9834         { 1004,         "Query FS Device Info"},
9835         { 1005,         "Query FS Attribute Info"},
9836         { 1006,         "Query FS Quota Info"},
9837         { 1007,         "Query Full FS Size Info"},
9838         { 1008,         "Object ID Information"},
9839         {0, NULL}
9840 };
9841
9842 static const value_string nt_rename_vals[] = {
9843         { 0x0103,       "Create Hard Link"},
9844         {0, NULL}
9845 };
9846
9847
9848 static const value_string delete_pending_vals[] = {
9849         {0,     "Normal, no pending delete"},
9850         {1,     "This object has DELETE PENDING"},
9851         {0, NULL}
9852 };
9853
9854 static const value_string alignment_vals[] = {
9855         {0,     "Byte alignment"},
9856         {1,     "Word (16bit) alignment"},
9857         {3,     "Long (32bit) alignment"},
9858         {7,     "8 byte boundary alignment"},
9859         {0x0f,  "16 byte boundary alignment"},
9860         {0x1f,  "32 byte boundary alignment"},
9861         {0x3f,  "64 byte boundary alignment"},
9862         {0x7f,  "128 byte boundary alignment"},
9863         {0xff,  "256 byte boundary alignment"},
9864         {0x1ff, "512 byte boundary alignment"},
9865         {0, NULL}
9866 };
9867
9868 static const true_false_string tfs_marked_for_deletion = {
9869         "File is MARKED FOR DELETION",
9870         "File is NOT marked for deletion"
9871 };
9872
9873 static const true_false_string tfs_get_dfs_server_hold_storage = {
9874         "Referral SERVER HOLDS STORAGE for the file",
9875         "Referral server does NOT hold storage for the file"
9876 };
9877 static const true_false_string tfs_get_dfs_fielding = {
9878         "The server in referral is FIELDING CAPABLE",
9879         "The server in referrals is NOT fielding capable"
9880 };
9881
9882 static const true_false_string tfs_dfs_referral_flags_strip = {
9883         "STRIP off pathconsumed characters before submitting",
9884         "Do NOT strip off any characters"
9885 };
9886
9887 static const value_string dfs_referral_server_type_vals[] = {
9888         {0,     "Don't know"},
9889         {1,     "SMB Server"},
9890         {2,     "Netware Server"},
9891         {3,     "Domain Server"},
9892         {0, NULL}
9893 };
9894
9895
9896 static const true_false_string tfs_device_char_removable = {
9897         "This is a REMOVABLE device",
9898         "This is NOT a removable device"
9899 };
9900 static const true_false_string tfs_device_char_read_only = {
9901         "This is a READ-ONLY device",
9902         "This is NOT a read-only device"
9903 };
9904 static const true_false_string tfs_device_char_floppy = {
9905         "This is a FLOPPY DISK device",
9906         "This is NOT a floppy disk device"
9907 };
9908 static const true_false_string tfs_device_char_write_once = {
9909         "This is a WRITE-ONCE device",
9910         "This is NOT a write-once device"
9911 };
9912 static const true_false_string tfs_device_char_remote = {
9913         "This is a REMOTE device",
9914         "This is NOT a remote device"
9915 };
9916 static const true_false_string tfs_device_char_mounted = {
9917         "This device is MOUNTED",
9918         "This device is NOT mounted"
9919 };
9920 static const true_false_string tfs_device_char_virtual = {
9921         "This is a VIRTUAL device",
9922         "This is NOT a virtual device"
9923 };
9924
9925
9926 static const true_false_string tfs_fs_attr_css = {
9927         "This FS supports CASE SENSITIVE SEARCHes",
9928         "This FS does NOT support case sensitive searches"
9929 };
9930 static const true_false_string tfs_fs_attr_cpn = {
9931         "This FS supports CASE PRESERVED NAMES",
9932         "This FS does NOT support case preserved names"
9933 };
9934 static const true_false_string tfs_fs_attr_pacls = {
9935         "This FS supports PERSISTENT ACLs",
9936         "This FS does NOT support persistent acls"
9937 };
9938 static const true_false_string tfs_fs_attr_fc = {
9939         "This FS supports COMPRESSED FILES",
9940         "This FS does NOT support compressed files"
9941 };
9942 static const true_false_string tfs_fs_attr_vq = {
9943         "This FS supports VOLUME QUOTAS",
9944         "This FS does NOT support volume quotas"
9945 };
9946 static const true_false_string tfs_fs_attr_dim = {
9947         "This FS is on a MOUNTED DEVICE",
9948         "This FS is NOT on a mounted device"
9949 };
9950 static const true_false_string tfs_fs_attr_vic = {
9951         "This FS is on a COMPRESSED VOLUME",
9952         "This FS is NOT on a compressed volume"
9953 };
9954
9955 #define FF2_RESUME      0x0004
9956
9957 static int
9958 dissect_ff2_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
9959 {
9960         guint16 mask;
9961         proto_item *item = NULL;
9962         proto_tree *tree = NULL;
9963         smb_info_t *si;
9964         smb_transact2_info_t *t2i;
9965
9966         mask = tvb_get_letohs(tvb, offset);
9967
9968         si = (smb_info_t *)pinfo->private_data;
9969         if (si->sip != NULL) {
9970                 t2i = si->sip->extra_info;
9971                 if (t2i != NULL) {
9972                         if (!pinfo->fd->flags.visited)
9973                                 t2i->resume_keys = (mask & FF2_RESUME);
9974                 }
9975         }
9976
9977         if(parent_tree){
9978                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
9979                         "Flags: 0x%04x", mask);
9980                 tree = proto_item_add_subtree(item, ett_smb_find_first2_flags);
9981         }
9982
9983         proto_tree_add_boolean(tree, hf_smb_ff2_backup,
9984                 tvb, offset, 2, mask);
9985         proto_tree_add_boolean(tree, hf_smb_ff2_continue,
9986                 tvb, offset, 2, mask);
9987         proto_tree_add_boolean(tree, hf_smb_ff2_resume,
9988                 tvb, offset, 2, mask);
9989         proto_tree_add_boolean(tree, hf_smb_ff2_close_eos,
9990                 tvb, offset, 2, mask);
9991         proto_tree_add_boolean(tree, hf_smb_ff2_close,
9992                 tvb, offset, 2, mask);
9993
9994         offset += 2;
9995
9996         return offset;
9997 }
9998
9999 #if 0
10000 static int
10001 dissect_sfi_ioflag(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10002 {
10003         guint16 mask;
10004         proto_item *item = NULL;
10005         proto_tree *tree = NULL;
10006
10007         mask = tvb_get_letohs(tvb, offset);
10008
10009         if(parent_tree){
10010                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10011                         "IO Flag: 0x%04x", mask);
10012                 tree = proto_item_add_subtree(item, ett_smb_ioflag);
10013         }
10014
10015         proto_tree_add_boolean(tree, hf_smb_sfi_writetru,
10016                 tvb, offset, 2, mask);
10017         proto_tree_add_boolean(tree, hf_smb_sfi_caching,
10018                 tvb, offset, 2, mask);
10019
10020         offset += 2;
10021
10022         return offset;
10023 }
10024 #endif
10025
10026 static int
10027 dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
10028     proto_tree *parent_tree, int offset, int subcmd, guint16 bc)
10029 {
10030         proto_item *item = NULL;
10031         proto_tree *tree = NULL;
10032         smb_info_t *si;
10033         smb_transact2_info_t *t2i;
10034         int fn_len;
10035         const char *fn;
10036
10037         si = (smb_info_t *)pinfo->private_data;
10038         if (si->sip != NULL)
10039                 t2i = si->sip->extra_info;
10040         else
10041                 t2i = NULL;
10042
10043         if(parent_tree){
10044                 item = proto_tree_add_text(parent_tree, tvb, offset, bc,
10045                                 "%s Parameters",
10046                                 val_to_str(subcmd, trans2_cmd_vals,
10047                                            "Unknown (0x%02x)"));
10048                 tree = proto_item_add_subtree(item, ett_smb_transaction_params);
10049         }
10050
10051         switch(subcmd){
10052         case 0x00:      /*TRANS2_OPEN2*/
10053                 /* open flags */
10054                 CHECK_BYTE_COUNT_TRANS(2);
10055                 offset = dissect_open_flags(tvb, tree, offset, 0x000f);
10056                 bc -= 2;
10057
10058                 /* desired access */
10059                 CHECK_BYTE_COUNT_TRANS(2);
10060                 offset = dissect_access(tvb, tree, offset, "Desired");
10061                 bc -= 2;
10062
10063                 /* Search Attributes */
10064                 CHECK_BYTE_COUNT_TRANS(2);
10065                 offset = dissect_search_attributes(tvb, tree, offset);
10066                 bc -= 2;
10067
10068                 /* File Attributes */
10069                 CHECK_BYTE_COUNT_TRANS(2);
10070                 offset = dissect_file_attributes(tvb, tree, offset, 2);
10071                 bc -= 2;
10072
10073                 /* create time */
10074                 CHECK_BYTE_COUNT_TRANS(4);
10075                 offset = dissect_smb_datetime(tvb, tree, offset,
10076                         hf_smb_create_time,
10077                         hf_smb_create_dos_date, hf_smb_create_dos_time,
10078                         TRUE);
10079                 bc -= 4;
10080
10081                 /* open function */
10082                 CHECK_BYTE_COUNT_TRANS(2);
10083                 offset = dissect_open_function(tvb, tree, offset);
10084                 bc -= 2;
10085
10086                 /* allocation size */
10087                 CHECK_BYTE_COUNT_TRANS(4);
10088                 proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10089                 COUNT_BYTES_TRANS(4);
10090
10091                 /* 10 reserved bytes */
10092                 CHECK_BYTE_COUNT_TRANS(10);
10093                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 10, TRUE);
10094                 COUNT_BYTES_TRANS(10);
10095
10096                 /* file name */
10097                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10098                 CHECK_STRING_TRANS(fn);
10099                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10100                         fn);
10101                 COUNT_BYTES_TRANS(fn_len);
10102
10103                 if (check_col(pinfo->cinfo, COL_INFO)) {
10104                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10105                         fn);
10106                 }
10107                 break;
10108         case 0x01:      /*TRANS2_FIND_FIRST2*/
10109                 /* Search Attributes */
10110                 CHECK_BYTE_COUNT_TRANS(2);
10111                 offset = dissect_search_attributes(tvb, tree, offset);
10112                 bc -= 2;
10113
10114                 /* search count */
10115                 CHECK_BYTE_COUNT_TRANS(2);
10116                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10117                 COUNT_BYTES_TRANS(2);
10118
10119                 /* Find First2 flags */
10120                 CHECK_BYTE_COUNT_TRANS(2);
10121                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10122                 bc -= 2;
10123
10124                 /* Find First2 information level */
10125                 CHECK_BYTE_COUNT_TRANS(2);
10126                 si->info_level = tvb_get_letohs(tvb, offset);
10127                 if (!pinfo->fd->flags.visited)
10128                         t2i->info_level = si->info_level;
10129                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10130                 COUNT_BYTES_TRANS(2);
10131
10132                 /* storage type */
10133                 CHECK_BYTE_COUNT_TRANS(4);
10134                 proto_tree_add_item(tree, hf_smb_storage_type, tvb, offset, 4, TRUE);
10135                 COUNT_BYTES_TRANS(4);
10136
10137                 /* search pattern */
10138                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10139                 CHECK_STRING_TRANS(fn);
10140                 proto_tree_add_string(tree, hf_smb_search_pattern, tvb, offset, fn_len,
10141                         fn);
10142                 COUNT_BYTES_TRANS(fn_len);
10143
10144                 if (check_col(pinfo->cinfo, COL_INFO)) {
10145                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Pattern: %s",
10146                         fn);
10147                 }
10148
10149                 break;
10150         case 0x02:      /*TRANS2_FIND_NEXT2*/
10151                 /* sid */
10152                 CHECK_BYTE_COUNT_TRANS(2);
10153                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
10154                 COUNT_BYTES_TRANS(2);
10155
10156                 /* search count */
10157                 CHECK_BYTE_COUNT_TRANS(2);
10158                 proto_tree_add_item(tree, hf_smb_search_count, tvb, offset, 2, TRUE);
10159                 COUNT_BYTES_TRANS(2);
10160
10161                 /* Find First2 information level */
10162                 CHECK_BYTE_COUNT_TRANS(2);
10163                 si->info_level = tvb_get_letohs(tvb, offset);
10164                 if (!pinfo->fd->flags.visited)
10165                         t2i->info_level = si->info_level;
10166                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, offset, 2, si->info_level);
10167                 COUNT_BYTES_TRANS(2);
10168
10169                 /* resume key */
10170                 CHECK_BYTE_COUNT_TRANS(4);
10171                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
10172                 COUNT_BYTES_TRANS(4);
10173
10174                 /* Find First2 flags */
10175                 CHECK_BYTE_COUNT_TRANS(2);
10176                 offset = dissect_ff2_flags(tvb, pinfo, tree, offset);
10177                 bc -= 2;
10178
10179                 /* file name */
10180                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10181                 CHECK_STRING_TRANS(fn);
10182                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10183                         fn);
10184                 COUNT_BYTES_TRANS(fn_len);
10185
10186                 if (check_col(pinfo->cinfo, COL_INFO)) {
10187                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Continue: %s",
10188                         fn);
10189                 }
10190
10191                 break;
10192         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
10193                 /* level of interest */
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_qfsi_information_level, tvb, offset, 2, si->info_level);
10199                 COUNT_BYTES_TRANS(2);
10200
10201                 if (check_col(pinfo->cinfo, COL_INFO))
10202                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
10203                                         val_to_str(si->info_level, qfsi_vals, 
10204                                                    "Unknown (0x%02x)"));
10205
10206                 break;
10207         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
10208                 /* level of interest */
10209                 CHECK_BYTE_COUNT_TRANS(2);
10210                 si->info_level = tvb_get_letohs(tvb, offset);
10211                 if (!pinfo->fd->flags.visited)
10212                         t2i->info_level = si->info_level;
10213                 proto_tree_add_uint(tree, hf_smb_qpi_loi, tvb, offset, 2, si->info_level);
10214                 COUNT_BYTES_TRANS(2);
10215
10216                 if (check_col(pinfo->cinfo, COL_INFO)) {
10217                         col_append_fstr(
10218                                 pinfo->cinfo, COL_INFO, ", %s", 
10219                                 val_to_str(si->info_level, qpi_loi_vals, 
10220                                            "Unknown (%u)"));
10221                 }
10222
10223                 /* 4 reserved bytes */
10224                 CHECK_BYTE_COUNT_TRANS(4);
10225                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10226                 COUNT_BYTES_TRANS(4);
10227
10228                 /* file name */
10229                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10230                 CHECK_STRING_TRANS(fn);
10231                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10232                         fn);
10233                 COUNT_BYTES_TRANS(fn_len);
10234
10235                 if (check_col(pinfo->cinfo, COL_INFO)) {
10236                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10237                         fn);
10238                 }
10239
10240                 break;
10241         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
10242                 /* level of interest */
10243                 CHECK_BYTE_COUNT_TRANS(2);
10244                 si->info_level = tvb_get_letohs(tvb, offset);
10245                 if (!pinfo->fd->flags.visited)
10246                         t2i->info_level = si->info_level;
10247                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10248                 COUNT_BYTES_TRANS(2);
10249
10250                 /* 4 reserved bytes */
10251                 CHECK_BYTE_COUNT_TRANS(4);
10252                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10253                 COUNT_BYTES_TRANS(4);
10254
10255                 /* file name */
10256                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10257                 CHECK_STRING_TRANS(fn);
10258                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10259                         fn);
10260                 COUNT_BYTES_TRANS(fn_len);
10261
10262                 if (check_col(pinfo->cinfo, COL_INFO)) {
10263                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10264                         fn);
10265                 }
10266
10267                 break;
10268         case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
10269                 guint16 fid;
10270
10271                 /* fid */
10272                 CHECK_BYTE_COUNT_TRANS(2);
10273                 fid = tvb_get_letohs(tvb, offset);
10274                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10275                 COUNT_BYTES_TRANS(2);
10276
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                 break;
10293         }
10294         case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
10295                 guint16 fid;
10296
10297                 /* fid */
10298                 CHECK_BYTE_COUNT_TRANS(2);
10299                 fid = tvb_get_letohs(tvb, offset);
10300                 add_fid(tvb, pinfo, tree, offset, 2, fid);
10301                 COUNT_BYTES_TRANS(2);
10302
10303                 /* level of interest */
10304                 CHECK_BYTE_COUNT_TRANS(2);
10305                 si->info_level = tvb_get_letohs(tvb, offset);
10306                 if (!pinfo->fd->flags.visited)
10307                         t2i->info_level = si->info_level;
10308                 proto_tree_add_uint(tree, hf_smb_spi_loi, tvb, offset, 2, si->info_level);
10309                 COUNT_BYTES_TRANS(2);
10310
10311 #if 0
10312                 /*
10313                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10314                  * Extensions Version 3.0, Document Version 1.11,
10315                  * July 19, 1990" says this is I/O flags, but it's
10316                  * reserved in the SNIA spec, and some clients appear
10317                  * to leave junk in it.
10318                  *
10319                  * Is this some field used only if a particular
10320                  * dialect was negotiated, so that clients can feel
10321                  * safe not setting it if they haven't negotiated that
10322                  * dialect?  Or do the (non-OS/2) clients simply not care
10323                  * about that particular OS/2-oriented dialect?
10324                  */
10325
10326                 /* IO Flag */
10327                 CHECK_BYTE_COUNT_TRANS(2);
10328                 offset = dissect_sfi_ioflag(tvb, tree, offset);
10329                 bc -= 2;
10330 #else
10331                 /* 2 reserved bytes */
10332                 CHECK_BYTE_COUNT_TRANS(2);
10333                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
10334                 COUNT_BYTES_TRANS(2);
10335 #endif
10336
10337                 break;
10338         }
10339         case 0x09:      /*TRANS2_FSCTL*/
10340                 /* this call has no parameter block in the request */
10341
10342                 /*
10343                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10344                  * Extensions Version 3.0, Document Version 1.11,
10345                  * July 19, 1990" says this this contains a
10346                  * "File system specific parameter block".  (That means
10347                  * we may not be able to dissect it in any case.)
10348                  */
10349                 break;
10350         case 0x0a:      /*TRANS2_IOCTL2*/
10351                 /* this call has no parameter block in the request */
10352
10353                 /*
10354                  * XXX - "Microsoft Networks SMB File Sharing Protocol
10355                  * Extensions Version 3.0, Document Version 1.11,
10356                  * July 19, 1990" says this this contains a
10357                  * "Device/function specific parameter block".  (That
10358                  * means we may not be able to dissect it in any case.)
10359                  */
10360                 break;
10361         case 0x0b: {    /*TRANS2_FIND_NOTIFY_FIRST*/
10362                 /* Search Attributes */
10363                 CHECK_BYTE_COUNT_TRANS(2);
10364                 offset = dissect_search_attributes(tvb, tree, offset);
10365                 bc -= 2;
10366
10367                 /* Number of changes to wait for */
10368                 CHECK_BYTE_COUNT_TRANS(2);
10369                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10370                 COUNT_BYTES_TRANS(2);
10371
10372                 /* Find Notify information level */
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_fn_information_level, tvb, offset, 2, si->info_level);
10378                 COUNT_BYTES_TRANS(2);
10379
10380                 /* 4 reserved bytes */
10381                 CHECK_BYTE_COUNT_TRANS(4);
10382                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10383                 COUNT_BYTES_TRANS(4);
10384
10385                 /* file name */
10386                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10387                 CHECK_STRING_TRANS(fn);
10388                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10389                         fn);
10390                 COUNT_BYTES_TRANS(fn_len);
10391
10392                 if (check_col(pinfo->cinfo, COL_INFO)) {
10393                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Path: %s",
10394                         fn);
10395                 }
10396
10397                 break;
10398         }
10399         case 0x0c: {    /*TRANS2_FIND_NOTIFY_NEXT*/
10400                 /* Monitor handle */
10401                 CHECK_BYTE_COUNT_TRANS(2);
10402                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
10403                 COUNT_BYTES_TRANS(2);
10404
10405                 /* Number of changes to wait for */
10406                 CHECK_BYTE_COUNT_TRANS(2);
10407                 proto_tree_add_item(tree, hf_smb_change_count, tvb, offset, 2, TRUE);
10408                 COUNT_BYTES_TRANS(2);
10409
10410                 break;
10411         }
10412         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
10413                 /* 4 reserved bytes */
10414                 CHECK_BYTE_COUNT_TRANS(4);
10415                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 4, TRUE);
10416                 COUNT_BYTES_TRANS(4);
10417
10418                 /* dir name */
10419                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len,
10420                         FALSE, FALSE, &bc);
10421                 CHECK_STRING_TRANS(fn);
10422                 proto_tree_add_string(tree, hf_smb_dir_name, tvb, offset, fn_len,
10423                         fn);
10424                 COUNT_BYTES_TRANS(fn_len);
10425
10426                 if (check_col(pinfo->cinfo, COL_INFO)) {
10427                         col_append_fstr(pinfo->cinfo, COL_INFO, ", Dir: %s",
10428                         fn);
10429                 }
10430                 break;
10431         case 0x0e:      /*TRANS2_SESSION_SETUP*/
10432                 /* XXX unknown structure*/
10433                 break;
10434         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
10435                 /* referral level */
10436                 CHECK_BYTE_COUNT_TRANS(2);
10437                 proto_tree_add_item(tree, hf_smb_max_referral_level, tvb, offset, 2, TRUE);
10438                 COUNT_BYTES_TRANS(2);
10439
10440                 /* file name */
10441                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, &bc);
10442                 CHECK_STRING_TRANS(fn);
10443                 proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10444                         fn);
10445                 COUNT_BYTES_TRANS(fn_len);
10446
10447                 if (check_col(pinfo->cinfo, COL_INFO)) {
10448                         col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
10449                         fn);
10450                 }
10451
10452                 break;
10453         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
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, ", File: %s",
10463                         fn);
10464                 }
10465
10466                 break;
10467         }
10468
10469         /* ooops there were data we didnt know how to process */
10470         if(bc != 0){
10471                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, bc, TRUE);
10472                 offset += bc;
10473         }
10474
10475         return offset;
10476 }
10477
10478 /*
10479  * XXX - just use "dissect_connect_flags()" here?
10480  */
10481 static guint16
10482 dissect_transaction_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10483 {
10484         guint16 mask;
10485         proto_item *item = NULL;
10486         proto_tree *tree = NULL;
10487
10488         mask = tvb_get_letohs(tvb, offset);
10489
10490         if(parent_tree){
10491                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10492                         "Flags: 0x%04x", mask);
10493                 tree = proto_item_add_subtree(item, ett_smb_transaction_flags);
10494         }
10495
10496         proto_tree_add_boolean(tree, hf_smb_transaction_flags_owt,
10497                 tvb, offset, 2, mask);
10498         proto_tree_add_boolean(tree, hf_smb_transaction_flags_dtid,
10499                 tvb, offset, 2, mask);
10500
10501         return mask;
10502 }
10503
10504
10505 static int
10506 dissect_get_dfs_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10507 {
10508         guint16 mask;
10509         proto_item *item = NULL;
10510         proto_tree *tree = NULL;
10511
10512         mask = tvb_get_letohs(tvb, offset);
10513
10514         if(parent_tree){
10515                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10516                         "Flags: 0x%04x", mask);
10517                 tree = proto_item_add_subtree(item, ett_smb_get_dfs_flags);
10518         }
10519
10520         proto_tree_add_boolean(tree, hf_smb_get_dfs_server_hold_storage,
10521                 tvb, offset, 2, mask);
10522         proto_tree_add_boolean(tree, hf_smb_get_dfs_fielding,
10523                 tvb, offset, 2, mask);
10524
10525         offset += 2;
10526         return offset;
10527 }
10528
10529 static int
10530 dissect_dfs_referral_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
10531 {
10532         guint16 mask;
10533         proto_item *item = NULL;
10534         proto_tree *tree = NULL;
10535
10536         mask = tvb_get_letohs(tvb, offset);
10537
10538         if(parent_tree){
10539                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
10540                         "Flags: 0x%04x", mask);
10541                 tree = proto_item_add_subtree(item, ett_smb_dfs_referral_flags);
10542         }
10543
10544         proto_tree_add_boolean(tree, hf_smb_dfs_referral_flags_strip,
10545                 tvb, offset, 2, mask);
10546
10547         offset += 2;
10548
10549         return offset;
10550 }
10551
10552
10553 /* dfs inconsistency data  (4.4.2)
10554 */
10555 static int
10556 dissect_dfs_inconsistency_data(tvbuff_t *tvb, packet_info *pinfo,
10557     proto_tree *tree, int offset, guint16 *bcp)
10558 {
10559         smb_info_t *si = pinfo->private_data;
10560         int fn_len;
10561         const char *fn;
10562
10563         /*XXX shouldn this data hold version and size? unclear from doc*/
10564         /* referral version */
10565         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10566         proto_tree_add_item(tree, hf_smb_dfs_referral_version, tvb, offset, 2, TRUE);
10567         COUNT_BYTES_TRANS_SUBR(2);
10568
10569         /* referral size */
10570         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10571         proto_tree_add_item(tree, hf_smb_dfs_referral_size, tvb, offset, 2, TRUE);
10572         COUNT_BYTES_TRANS_SUBR(2);
10573
10574         /* referral server type */
10575         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10576         proto_tree_add_item(tree, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10577         COUNT_BYTES_TRANS_SUBR(2);
10578
10579         /* referral flags */
10580         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10581         offset = dissect_dfs_referral_flags(tvb, tree, offset);
10582         *bcp -= 2;
10583
10584         /* node name */
10585         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10586         CHECK_STRING_TRANS_SUBR(fn);
10587         proto_tree_add_string(tree, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10588                 fn);
10589         COUNT_BYTES_TRANS_SUBR(fn_len);
10590
10591         return offset;
10592 }
10593
10594 /* get dfs referral data  (4.4.1)
10595 */
10596 static int
10597 dissect_get_dfs_referral_data(tvbuff_t *tvb, packet_info *pinfo,
10598     proto_tree *tree, int offset, guint16 *bcp)
10599 {
10600         smb_info_t *si = pinfo->private_data;
10601         guint16 numref;
10602         guint16 refsize;
10603         guint16 pathoffset;
10604         guint16 altpathoffset;
10605         guint16 nodeoffset;
10606         int fn_len;
10607         int stroffset;
10608         int offsetoffset;
10609         guint16 save_bc;
10610         const char *fn;
10611         int unklen;
10612         int ucstring_end;
10613         int ucstring_len;
10614
10615         /* path consumed */
10616         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10617         proto_tree_add_item(tree, hf_smb_dfs_path_consumed, tvb, offset, 2, TRUE);
10618         COUNT_BYTES_TRANS_SUBR(2);
10619
10620         /* num referrals */
10621         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10622         numref = tvb_get_letohs(tvb, offset);
10623         proto_tree_add_uint(tree, hf_smb_dfs_num_referrals, tvb, offset, 2, numref);
10624         COUNT_BYTES_TRANS_SUBR(2);
10625
10626         /* get dfs flags */
10627         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10628         offset = dissect_get_dfs_flags(tvb, tree, offset);
10629         *bcp -= 2;
10630
10631         /* XXX - in at least one capture there appears to be 2 bytes
10632            of stuff after the Dfs flags, perhaps so that the header
10633            in front of the referral list is a multiple of 4 bytes long. */
10634         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10635         proto_tree_add_item(tree, hf_smb_padding, tvb, offset, 2, TRUE);
10636         COUNT_BYTES_TRANS_SUBR(2);
10637
10638         /* if there are any referrals */
10639         if(numref){
10640                 proto_item *ref_item = NULL;
10641                 proto_tree *ref_tree = NULL;
10642                 int old_offset=offset;
10643
10644                 if(tree){
10645                         ref_item = proto_tree_add_text(tree,
10646                                 tvb, offset, *bcp, "Referrals");
10647                         ref_tree = proto_item_add_subtree(ref_item,
10648                                 ett_smb_dfs_referrals);
10649                 }
10650                 ucstring_end = -1;
10651
10652                 while(numref--){
10653                         proto_item *ri = NULL;
10654                         proto_tree *rt = NULL;
10655                         int old_offset=offset;
10656                         guint16 version;
10657
10658                         if(tree){
10659                                 ri = proto_tree_add_text(ref_tree,
10660                                         tvb, offset, *bcp, "Referral");
10661                                 rt = proto_item_add_subtree(ri,
10662                                         ett_smb_dfs_referral);
10663                         }
10664
10665                         /* referral version */
10666                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10667                         version = tvb_get_letohs(tvb, offset);
10668                         proto_tree_add_uint(rt, hf_smb_dfs_referral_version,
10669                                 tvb, offset, 2, version);
10670                         COUNT_BYTES_TRANS_SUBR(2);
10671
10672                         /* referral size */
10673                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10674                         refsize = tvb_get_letohs(tvb, offset);
10675                         proto_tree_add_uint(rt, hf_smb_dfs_referral_size, tvb, offset, 2, refsize);
10676                         COUNT_BYTES_TRANS_SUBR(2);
10677
10678                         /* referral server type */
10679                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10680                         proto_tree_add_item(rt, hf_smb_dfs_referral_server_type, tvb, offset, 2, TRUE);
10681                         COUNT_BYTES_TRANS_SUBR(2);
10682
10683                         /* referral flags */
10684                         CHECK_BYTE_COUNT_TRANS_SUBR(2);
10685                         offset = dissect_dfs_referral_flags(tvb, rt, offset);
10686                         *bcp -= 2;
10687
10688                         switch(version){
10689
10690                         case 1:
10691                                 /* node name */
10692                                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10693                                 CHECK_STRING_TRANS_SUBR(fn);
10694                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, offset, fn_len,
10695                                         fn);
10696                                 COUNT_BYTES_TRANS_SUBR(fn_len);
10697                                 break;
10698
10699                         case 2:
10700                         case 3: /* XXX - like version 2, but not identical;
10701                                    seen in a capture, but the format isn't
10702                                    documented */
10703                                 /* proximity */
10704                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10705                                 proto_tree_add_item(rt, hf_smb_dfs_referral_proximity, tvb, offset, 2, TRUE);
10706                                 COUNT_BYTES_TRANS_SUBR(2);
10707
10708                                 /* ttl */
10709                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10710                                 proto_tree_add_item(rt, hf_smb_dfs_referral_ttl, tvb, offset, 2, TRUE);
10711                                 COUNT_BYTES_TRANS_SUBR(2);
10712
10713                                 /* path offset */
10714                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10715                                 pathoffset = tvb_get_letohs(tvb, offset);
10716                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_path_offset, tvb, offset, 2, pathoffset);
10717                                 COUNT_BYTES_TRANS_SUBR(2);
10718
10719                                 /* alt path offset */
10720                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10721                                 altpathoffset = tvb_get_letohs(tvb, offset);
10722                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_alt_path_offset, tvb, offset, 2, altpathoffset);
10723                                 COUNT_BYTES_TRANS_SUBR(2);
10724
10725                                 /* node offset */
10726                                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
10727                                 nodeoffset = tvb_get_letohs(tvb, offset);
10728                                 proto_tree_add_uint(rt, hf_smb_dfs_referral_node_offset, tvb, offset, 2, nodeoffset);
10729                                 COUNT_BYTES_TRANS_SUBR(2);
10730
10731                                 /* path */
10732                                 if (pathoffset != 0) {
10733                                         stroffset = old_offset + pathoffset;
10734                                         offsetoffset = stroffset - offset;
10735                                         if (offsetoffset > 0 &&
10736                                             *bcp > offsetoffset) {
10737                                                 save_bc = *bcp;
10738                                                 *bcp -= offsetoffset;
10739                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10740                                                 CHECK_STRING_TRANS_SUBR(fn);
10741                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_path, tvb, stroffset, fn_len,
10742                                                         fn);
10743                                                 stroffset += fn_len;
10744                                                 if (ucstring_end < stroffset)
10745                                                         ucstring_end = stroffset;
10746                                                 *bcp = save_bc;
10747                                         }
10748                                 }
10749
10750                                 /* alt path */
10751                                 if (altpathoffset != 0) {
10752                                         stroffset = old_offset + altpathoffset;
10753                                         offsetoffset = stroffset - offset;
10754                                         if (offsetoffset > 0 &&
10755                                             *bcp > offsetoffset) {
10756                                                 save_bc = *bcp;
10757                                                 *bcp -= offsetoffset;
10758                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10759                                                 CHECK_STRING_TRANS_SUBR(fn);
10760                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_alt_path, tvb, stroffset, fn_len,
10761                                                         fn);
10762                                                 stroffset += fn_len;
10763                                                 if (ucstring_end < stroffset)
10764                                                         ucstring_end = stroffset;
10765                                                 *bcp = save_bc;
10766                                         }
10767                                 }
10768
10769                                 /* node */
10770                                 if (nodeoffset != 0) {
10771                                         stroffset = old_offset + nodeoffset;
10772                                         offsetoffset = stroffset - offset;
10773                                         if (offsetoffset > 0 &&
10774                                             *bcp > offsetoffset) {
10775                                                 save_bc = *bcp;
10776                                                 *bcp -= offsetoffset;
10777                                                 fn = get_unicode_or_ascii_string(tvb, &stroffset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10778                                                 CHECK_STRING_TRANS_SUBR(fn);
10779                                                 proto_tree_add_string(rt, hf_smb_dfs_referral_node, tvb, stroffset, fn_len,
10780                                                         fn);
10781                                                 stroffset += fn_len;
10782                                                 if (ucstring_end < stroffset)
10783                                                         ucstring_end = stroffset;
10784                                                 *bcp = save_bc;
10785                                         }
10786                                 }
10787                                 break;
10788                         }
10789
10790                         /*
10791                          * Show anything beyond the length of the referral
10792                          * as unknown data.
10793                          */
10794                         unklen = (old_offset + refsize) - offset;
10795                         if (unklen < 0) {
10796                                 /*
10797                                  * XXX - the length is bogus.
10798                                  */
10799                                 unklen = 0;
10800                         }
10801                         if (unklen != 0) {
10802                                 CHECK_BYTE_COUNT_TRANS_SUBR(unklen);
10803                                 proto_tree_add_item(rt, hf_smb_unknown, tvb,
10804                                     offset, unklen, TRUE);
10805                                 COUNT_BYTES_TRANS_SUBR(unklen);
10806                         }
10807
10808                         proto_item_set_len(ri, offset-old_offset);
10809                 }
10810
10811                 /*
10812                  * Treat the offset past the end of the last Unicode
10813                  * string after the referrals (if any) as the last
10814                  * offset.
10815                  */
10816                 if (ucstring_end > offset) {
10817                         ucstring_len = ucstring_end - offset;
10818                         if (*bcp < ucstring_len)
10819                                 ucstring_len = *bcp;
10820                         offset += ucstring_len;
10821                         *bcp -= ucstring_len;
10822                 }
10823                 proto_item_set_len(ref_item, offset-old_offset);
10824         }
10825
10826         return offset;
10827 }
10828
10829
10830 /* this dissects the SMB_INFO_STANDARD and SMB_INFO_QUERY_EA_SIZE
10831    as described in 4.2.16.1
10832 */
10833 static int
10834 dissect_4_2_16_1(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10835     int offset, guint16 *bcp, gboolean *trunc)
10836 {
10837         /* create time */
10838         CHECK_BYTE_COUNT_SUBR(4);
10839         offset = dissect_smb_datetime(tvb, tree, offset,
10840                 hf_smb_create_time, hf_smb_create_dos_date, hf_smb_create_dos_time,
10841                 FALSE);
10842         *bcp -= 4;
10843
10844         /* access time */
10845         CHECK_BYTE_COUNT_SUBR(4);
10846         offset = dissect_smb_datetime(tvb, tree, offset,
10847                 hf_smb_access_time, hf_smb_access_dos_date, hf_smb_access_dos_time,
10848                 FALSE);
10849         *bcp -= 4;
10850
10851         /* last write time */
10852         CHECK_BYTE_COUNT_SUBR(4);
10853         offset = dissect_smb_datetime(tvb, tree, offset,
10854                 hf_smb_last_write_time, hf_smb_last_write_dos_date, hf_smb_last_write_dos_time,
10855                 FALSE);
10856         *bcp -= 4;
10857
10858         /* data size */
10859         CHECK_BYTE_COUNT_SUBR(4);
10860         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
10861         COUNT_BYTES_SUBR(4);
10862
10863         /* allocation size */
10864         CHECK_BYTE_COUNT_SUBR(4);
10865         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
10866         COUNT_BYTES_SUBR(4);
10867
10868         /* File Attributes */
10869         CHECK_BYTE_COUNT_SUBR(2);
10870         offset = dissect_file_attributes(tvb, tree, offset, 2);
10871         *bcp -= 2;
10872
10873         /* ea length */
10874         CHECK_BYTE_COUNT_SUBR(4);
10875         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10876         COUNT_BYTES_SUBR(4);
10877
10878         *trunc = FALSE;
10879         return offset;
10880 }
10881
10882 /* this dissects the SMB_INFO_QUERY_EAS_FROM_LIST and SMB_INFO_QUERY_ALL_EAS
10883    as described in 4.2.16.2
10884 */
10885 static int
10886 dissect_4_2_16_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10887     int offset, guint16 *bcp, gboolean *trunc)
10888 {
10889         guint8 name_len;
10890         guint16 data_len;
10891         /* EA size */
10892
10893         CHECK_BYTE_COUNT_SUBR(4);
10894         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
10895         COUNT_BYTES_SUBR(4);
10896
10897         while (*bcp > 0) {
10898                 proto_item *item;
10899                 proto_tree *subtree;
10900                 int start_offset = offset;
10901                 guint8 *name;
10902
10903                 item = proto_tree_add_text(
10904                         tree, tvb, offset, 0, "Extended Attribute");
10905                 subtree = proto_item_add_subtree(item, ett_smb_ea);
10906
10907                 /* EA flags */
10908                 
10909                 CHECK_BYTE_COUNT_SUBR(1);
10910                 proto_tree_add_item(
10911                         subtree, hf_smb_ea_flags, tvb, offset, 1, TRUE);
10912                 COUNT_BYTES_SUBR(1);
10913
10914                 /* EA name length */
10915                 
10916                 name_len = tvb_get_guint8(tvb, offset);
10917
10918                 CHECK_BYTE_COUNT_SUBR(1);
10919                 proto_tree_add_item(
10920                         subtree, hf_smb_ea_name_length, tvb, offset, 1, TRUE);
10921                 COUNT_BYTES_SUBR(1);
10922
10923                 /* EA data length */
10924
10925                 data_len = tvb_get_letohs(tvb, offset);
10926                 
10927                 CHECK_BYTE_COUNT_SUBR(2);
10928                 proto_tree_add_item(
10929                         subtree, hf_smb_ea_data_length, tvb, offset, 2, TRUE);
10930                 COUNT_BYTES_SUBR(2);
10931
10932                 /* EA name */
10933
10934                 name = tvb_get_string(tvb, offset, name_len);
10935                 proto_item_append_text(item, ": %s", name);
10936                 g_free(name);
10937
10938                 CHECK_BYTE_COUNT_SUBR(name_len + 1);
10939                 proto_tree_add_item(
10940                         subtree, hf_smb_ea_name, tvb, offset, name_len + 1, 
10941                         TRUE);
10942                 COUNT_BYTES_SUBR(name_len + 1);
10943
10944                 /* EA data */
10945                 
10946                 CHECK_BYTE_COUNT_SUBR(data_len);
10947                 proto_tree_add_item(
10948                         subtree, hf_smb_ea_data, tvb, offset, data_len, TRUE);
10949                 COUNT_BYTES_SUBR(data_len);
10950
10951                 proto_item_set_len(item, offset - start_offset);
10952         }
10953
10954         *trunc = FALSE;
10955         return offset;
10956 }
10957
10958 /* this dissects the SMB_INFO_IS_NAME_VALID
10959    as described in 4.2.16.3
10960 */
10961 static int
10962 dissect_4_2_16_3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
10963     int offset, guint16 *bcp, gboolean *trunc)
10964 {
10965         smb_info_t *si = pinfo->private_data;
10966         int fn_len;
10967         const char *fn;
10968
10969         /* file name */
10970         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
10971         CHECK_STRING_SUBR(fn);
10972         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
10973                 fn);
10974         COUNT_BYTES_SUBR(fn_len);
10975
10976         *trunc = FALSE;
10977         return offset;
10978 }
10979
10980 /* this dissects the SMB_QUERY_FILE_BASIC_INFO
10981    as described in 4.2.16.4
10982 */
10983 static int
10984 dissect_4_2_16_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
10985     int offset, guint16 *bcp, gboolean *trunc)
10986 {
10987         /* create time */
10988         CHECK_BYTE_COUNT_SUBR(8);
10989         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
10990         *bcp -= 8;
10991
10992         /* access time */
10993         CHECK_BYTE_COUNT_SUBR(8);
10994         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
10995         *bcp -= 8;
10996
10997         /* last write time */
10998         CHECK_BYTE_COUNT_SUBR(8);
10999         offset = dissect_smb_64bit_time(tvb, tree, offset,
11000                 hf_smb_last_write_time);
11001         *bcp -= 8;
11002
11003         /* last change time */
11004         CHECK_BYTE_COUNT_SUBR(8);
11005         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
11006         *bcp -= 8;
11007
11008         /* File Attributes */
11009         CHECK_BYTE_COUNT_SUBR(4);
11010         offset = dissect_file_attributes(tvb, tree, offset, 4);
11011         *bcp -= 4;
11012
11013         *trunc = FALSE;
11014         return offset;
11015 }
11016
11017 /* this dissects the SMB_QUERY_FILE_STANDARD_INFO
11018    as described in 4.2.16.5
11019 */
11020 static int
11021 dissect_4_2_16_5(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11022     int offset, guint16 *bcp, gboolean *trunc)
11023 {
11024         /* allocation size */
11025         CHECK_BYTE_COUNT_SUBR(8);
11026         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11027         COUNT_BYTES_SUBR(8);
11028
11029         /* end of file */
11030         CHECK_BYTE_COUNT_SUBR(8);
11031         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11032         COUNT_BYTES_SUBR(8);
11033
11034         /* number of links */
11035         CHECK_BYTE_COUNT_SUBR(4);
11036         proto_tree_add_item(tree, hf_smb_number_of_links, tvb, offset, 4, TRUE);
11037         COUNT_BYTES_SUBR(4);
11038
11039         /* delete pending */
11040         CHECK_BYTE_COUNT_SUBR(1);
11041         proto_tree_add_item(tree, hf_smb_delete_pending, tvb, offset, 1, TRUE);
11042         COUNT_BYTES_SUBR(1);
11043
11044         /* is directory */
11045         CHECK_BYTE_COUNT_SUBR(1);
11046         proto_tree_add_item(tree, hf_smb_is_directory, tvb, offset, 1, TRUE);
11047         COUNT_BYTES_SUBR(1);
11048
11049         *trunc = FALSE;
11050         return offset;
11051 }
11052
11053 /* this dissects the SMB_QUERY_FILE_EA_INFO
11054    as described in 4.2.16.6
11055 */
11056 static int
11057 dissect_4_2_16_6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11058     int offset, guint16 *bcp, gboolean *trunc)
11059 {
11060         /* ea length */
11061         CHECK_BYTE_COUNT_SUBR(4);
11062         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
11063         COUNT_BYTES_SUBR(4);
11064
11065         *trunc = FALSE;
11066         return offset;
11067 }
11068
11069 /* this dissects the SMB_QUERY_FILE_NAME_INFO
11070    as described in 4.2.16.7
11071    this is the same as SMB_QUERY_FILE_ALT_NAME_INFO
11072    as described in 4.2.16.9
11073 */
11074 static int
11075 dissect_4_2_16_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11076     int offset, guint16 *bcp, gboolean *trunc)
11077 {
11078         smb_info_t *si = pinfo->private_data;
11079         int fn_len;
11080         const char *fn;
11081
11082         /* file name len */
11083         CHECK_BYTE_COUNT_SUBR(4);
11084         proto_tree_add_item(tree, hf_smb_file_name_len, tvb, offset, 4, TRUE);
11085         COUNT_BYTES_SUBR(4);
11086
11087         /* file name */
11088         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
11089         CHECK_STRING_SUBR(fn);
11090         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
11091                 fn);
11092         COUNT_BYTES_SUBR(fn_len);
11093
11094         *trunc = FALSE;
11095         return offset;
11096 }
11097
11098 /* this dissects the SMB_QUERY_FILE_ALL_INFO
11099    as described in 4.2.16.8
11100 */
11101 static int
11102 dissect_4_2_16_8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
11103     int offset, guint16 *bcp, gboolean *trunc)
11104 {
11105
11106         offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp, trunc);
11107         if (*trunc) {
11108                 return offset;
11109         }
11110         offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp, trunc);
11111         if (*trunc) {
11112                 return offset;
11113         }
11114
11115         /* index number */
11116         CHECK_BYTE_COUNT_SUBR(8);
11117         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11118         COUNT_BYTES_SUBR(8);
11119
11120         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11121         if (*trunc)
11122                 return offset;
11123
11124         /* access flags */
11125         CHECK_BYTE_COUNT_SUBR(4);
11126         offset = dissect_smb_access_mask(tvb, tree, offset);
11127         COUNT_BYTES_SUBR(4);
11128
11129         /* index number */
11130         CHECK_BYTE_COUNT_SUBR(8);
11131         proto_tree_add_item(tree, hf_smb_index_number, tvb, offset, 8, TRUE);
11132         COUNT_BYTES_SUBR(8);
11133
11134         /* current offset */
11135         CHECK_BYTE_COUNT_SUBR(8);
11136         proto_tree_add_item(tree, hf_smb_current_offset, tvb, offset, 8, TRUE);
11137         COUNT_BYTES_SUBR(8);
11138
11139         /* mode */
11140         CHECK_BYTE_COUNT_SUBR(4);
11141         offset = dissect_nt_create_options(tvb, tree, offset);
11142         *bcp -= 4;
11143
11144         /* alignment */
11145         CHECK_BYTE_COUNT_SUBR(4);
11146         proto_tree_add_item(tree, hf_smb_t2_alignment, tvb, offset, 4, TRUE);
11147         COUNT_BYTES_SUBR(4);
11148
11149         offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp, trunc);
11150
11151         return offset;
11152 }
11153
11154 /* this dissects the SMB_QUERY_FILE_STREAM_INFO
11155    as described in 4.2.16.10
11156 */
11157 static int
11158 dissect_4_2_16_10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
11159     int offset, guint16 *bcp, gboolean *trunc)
11160 {
11161         proto_item *item;
11162         proto_tree *tree;
11163         int old_offset;
11164         guint32 neo;
11165         smb_info_t *si = pinfo->private_data;
11166         int fn_len;
11167         const char *fn;
11168         int padcnt;
11169
11170         for (;;) {
11171                 old_offset = offset;
11172
11173                 /* next entry offset */
11174                 CHECK_BYTE_COUNT_SUBR(4);
11175                 if(parent_tree){
11176                         item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "Stream Info");
11177                         tree = proto_item_add_subtree(item, ett_smb_ff2_data);
11178                 } else {
11179                         item = NULL;
11180                         tree = NULL;
11181                 }
11182
11183                 neo = tvb_get_letohl(tvb, offset);
11184                 proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
11185                 COUNT_BYTES_SUBR(4);
11186
11187                 /* stream name len */
11188                 CHECK_BYTE_COUNT_SUBR(4);
11189                 fn_len = tvb_get_letohl(tvb, offset);
11190                 proto_tree_add_uint(tree, hf_smb_t2_stream_name_length, tvb, offset, 4, fn_len);
11191                 COUNT_BYTES_SUBR(4);
11192
11193                 /* stream size */
11194                 CHECK_BYTE_COUNT_SUBR(8);
11195                 proto_tree_add_item(tree, hf_smb_t2_stream_size, tvb, offset, 8, TRUE);
11196                 COUNT_BYTES_SUBR(8);
11197
11198                 /* allocation size */
11199                 CHECK_BYTE_COUNT_SUBR(8);
11200                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11201                 COUNT_BYTES_SUBR(8);
11202
11203                 /* stream name */
11204                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11205                 CHECK_STRING_SUBR(fn);
11206                 proto_tree_add_string(tree, hf_smb_t2_stream_name, tvb, offset, fn_len,
11207                         fn);
11208                 COUNT_BYTES_SUBR(fn_len);
11209
11210                 proto_item_append_text(item, ": %s", fn);
11211                 proto_item_set_len(item, offset-old_offset);
11212
11213                 if (neo == 0)
11214                         break;  /* no more structures */
11215
11216                 /* skip to next structure */
11217                 padcnt = (old_offset + neo) - offset;
11218                 if (padcnt < 0) {
11219                         /*
11220                          * XXX - this is bogus; flag it?
11221                          */
11222                         padcnt = 0;
11223                 }
11224                 if (padcnt != 0) {
11225                         CHECK_BYTE_COUNT_SUBR(padcnt);
11226                         COUNT_BYTES_SUBR(padcnt);
11227                 }
11228         }
11229
11230         *trunc = FALSE;
11231         return offset;
11232 }
11233
11234 /* this dissects the SMB_QUERY_FILE_COMPRESSION_INFO
11235    as described in 4.2.16.11
11236 */
11237 static int
11238 dissect_4_2_16_11(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11239     int offset, guint16 *bcp, gboolean *trunc)
11240 {
11241         /* compressed file size */
11242         CHECK_BYTE_COUNT_SUBR(8);
11243         proto_tree_add_item(tree, hf_smb_t2_compressed_file_size, tvb, offset, 8, TRUE);
11244         COUNT_BYTES_SUBR(8);
11245
11246         /* compression format */
11247         CHECK_BYTE_COUNT_SUBR(2);
11248         proto_tree_add_item(tree, hf_smb_t2_compressed_format, tvb, offset, 2, TRUE);
11249         COUNT_BYTES_SUBR(2);
11250
11251         /* compression unit shift */
11252         CHECK_BYTE_COUNT_SUBR(1);
11253         proto_tree_add_item(tree, hf_smb_t2_compressed_unit_shift,tvb, offset, 1, TRUE);
11254         COUNT_BYTES_SUBR(1);
11255
11256         /* compression chunk shift */
11257         CHECK_BYTE_COUNT_SUBR(1);
11258         proto_tree_add_item(tree, hf_smb_t2_compressed_chunk_shift, tvb, offset, 1, TRUE);
11259         COUNT_BYTES_SUBR(1);
11260
11261         /* compression cluster shift */
11262         CHECK_BYTE_COUNT_SUBR(1);
11263         proto_tree_add_item(tree, hf_smb_t2_compressed_cluster_shift, tvb, offset, 1, TRUE);
11264         COUNT_BYTES_SUBR(1);
11265
11266         /* 3 reserved bytes */
11267         CHECK_BYTE_COUNT_SUBR(3);
11268         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 3, TRUE);
11269         COUNT_BYTES_SUBR(3);
11270
11271         *trunc = FALSE;
11272         return offset;
11273 }
11274
11275 /* 4.2.16.12 - SMB_QUERY_FILE_UNIX_BASIC */
11276
11277 static const value_string unix_file_type_vals[] = {
11278         { 0, "File" },
11279         { 1, "Directory" },
11280         { 2, "Symbolic link" },
11281         { 3, "Character device" },
11282         { 4, "Block device" },
11283         { 5, "FIFO" },
11284         { 6, "Socket" },
11285         { 0, NULL }
11286 };
11287
11288 static int
11289 dissect_4_2_16_12(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11290                   int offset, guint16 *bcp, gboolean *trunc)
11291 {
11292         /* End of file (file size) */
11293         CHECK_BYTE_COUNT_SUBR(8);
11294         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
11295         COUNT_BYTES_SUBR(8);
11296
11297         /* Number of bytes */
11298         CHECK_BYTE_COUNT_SUBR(8);
11299         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
11300         COUNT_BYTES_SUBR(8);
11301
11302         /* Last status change */
11303         CHECK_BYTE_COUNT_SUBR(8);
11304         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
11305         *bcp -= 8;              /* dissect_smb_64bit_time() increments offset */
11306
11307         /* Last access time */
11308         CHECK_BYTE_COUNT_SUBR(8);
11309         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
11310         *bcp -= 8;
11311
11312         /* Last modification time */
11313         CHECK_BYTE_COUNT_SUBR(8);
11314         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
11315         *bcp -= 8;
11316
11317         /* File owner uid */
11318         CHECK_BYTE_COUNT_SUBR(8);
11319         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
11320         COUNT_BYTES_SUBR(8);
11321
11322         /* File group gid */
11323         CHECK_BYTE_COUNT_SUBR(8);
11324         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
11325         COUNT_BYTES_SUBR(8);
11326
11327         /* File type */
11328         CHECK_BYTE_COUNT_SUBR(4);
11329         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
11330         COUNT_BYTES_SUBR(4);
11331
11332         /* Major device number */
11333         CHECK_BYTE_COUNT_SUBR(8);
11334         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
11335         COUNT_BYTES_SUBR(8);
11336
11337         /* Minor device number */
11338         CHECK_BYTE_COUNT_SUBR(8);
11339         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
11340         COUNT_BYTES_SUBR(8);
11341
11342         /* Unique id */
11343         CHECK_BYTE_COUNT_SUBR(8);
11344         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
11345         COUNT_BYTES_SUBR(8);
11346
11347         /* Permissions */
11348         CHECK_BYTE_COUNT_SUBR(8);
11349         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
11350         COUNT_BYTES_SUBR(8);
11351
11352         /* Nlinks */
11353         CHECK_BYTE_COUNT_SUBR(8);
11354         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
11355         COUNT_BYTES_SUBR(8);
11356
11357         /* Sometimes there is one extra byte in the data field which I
11358            guess could be padding, but we are only using 4 or 8 byte
11359            data types so this is a bit confusing. -tpot */
11360
11361         *trunc = FALSE;
11362         return offset;
11363 }
11364
11365 /* 4.2.16.13 - SMB_QUERY_FILE_UNIX_LINK */
11366
11367 static int
11368 dissect_4_2_16_13(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11369                   int offset, guint16 *bcp, gboolean *trunc)
11370 {
11371         smb_info_t *si = pinfo->private_data;
11372         const char *fn;
11373         int fn_len;
11374
11375         /* Link destination */
11376
11377         fn = get_unicode_or_ascii_string(
11378                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11379
11380         CHECK_STRING_SUBR(fn);
11381         proto_tree_add_string(
11382                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
11383         COUNT_BYTES_SUBR(fn_len);
11384
11385         *trunc = FALSE;
11386         return offset;
11387 }
11388
11389 /* this dissects the SMB_SET_FILE_DISPOSITION_INFO
11390    as described in 4.2.19.2
11391 */
11392 static int
11393 dissect_4_2_19_2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11394     int offset, guint16 *bcp, gboolean *trunc)
11395 {
11396         /* marked for deletion? */
11397         CHECK_BYTE_COUNT_SUBR(1);
11398         proto_tree_add_item(tree, hf_smb_t2_marked_for_deletion, tvb, offset, 1, TRUE);
11399         COUNT_BYTES_SUBR(1);
11400
11401         *trunc = FALSE;
11402         return offset;
11403 }
11404
11405 /* this dissects the SMB_SET_FILE_ALLOCATION_INFO
11406    as described in 4.2.19.3
11407 */
11408 static int
11409 dissect_4_2_19_3(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11410     int offset, guint16 *bcp, gboolean *trunc)
11411 {
11412         /* file allocation size */
11413         CHECK_BYTE_COUNT_SUBR(8);
11414         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
11415         COUNT_BYTES_SUBR(8);
11416
11417         *trunc = FALSE;
11418         return offset;
11419 }
11420
11421 /* this dissects the SMB_SET_FILE_END_OF_FILE_INFO
11422    as described in 4.2.19.4
11423 */
11424 static int
11425 dissect_4_2_19_4(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11426     int offset, guint16 *bcp, gboolean *trunc)
11427 {
11428         /* file end of file offset */
11429         CHECK_BYTE_COUNT_SUBR(8);
11430         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
11431         COUNT_BYTES_SUBR(8);
11432
11433         *trunc = FALSE;
11434         return offset;
11435 }
11436
11437 /* Set File Rename Info */
11438
11439 static const true_false_string tfs_smb_replace = {
11440         "Remove target file if it exists",
11441         "Do NOT remove target file if it exists",
11442 };
11443
11444 static int
11445 dissect_rename_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
11446                     int offset, guint16 *bcp, gboolean *trunc)
11447 {
11448         smb_info_t *si = pinfo->private_data;
11449         const char *fn;
11450         guint32 target_name_len;
11451         int fn_len;
11452
11453         /* Replace flag */
11454         CHECK_BYTE_COUNT_SUBR(4);
11455         proto_tree_add_item(tree, hf_smb_replace, tvb, offset, 4, TRUE);
11456         COUNT_BYTES_SUBR(4);
11457
11458         /* Root directory handle */
11459         CHECK_BYTE_COUNT_SUBR(4);
11460         proto_tree_add_item(tree, hf_smb_root_dir_handle, tvb, offset, 4, TRUE);
11461         COUNT_BYTES_SUBR(4);
11462
11463         /* Target name length */
11464         CHECK_BYTE_COUNT_SUBR(4);
11465         target_name_len = tvb_get_letohl(tvb, offset);
11466         proto_tree_add_uint(tree, hf_smb_target_name_len, tvb, offset, 4, target_name_len);
11467         COUNT_BYTES_SUBR(4);
11468
11469         /* Target name */
11470         fn_len = target_name_len;
11471         fn = get_unicode_or_ascii_string(
11472                 tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
11473
11474         CHECK_STRING_SUBR(fn);
11475         proto_tree_add_string(
11476                 tree, hf_smb_target_name, tvb, offset, fn_len, fn);
11477         COUNT_BYTES_SUBR(fn_len);
11478
11479         *trunc = FALSE;
11480         return offset;
11481 }
11482
11483 /*dissect the data block for TRANS2_QUERY_PATH_INFORMATION and
11484   TRANS2_QUERY_FILE_INFORMATION*/
11485 static int
11486 dissect_qpi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11487     int offset, guint16 *bcp)
11488 {
11489         smb_info_t *si;
11490         gboolean trunc;
11491
11492         if(!*bcp){
11493                 return offset;
11494         }
11495
11496         si = (smb_info_t *)pinfo->private_data;
11497         switch(si->info_level){
11498         case 1:         /*Info Standard*/
11499                 
11500         case 2:         /*Info Query EA Size*/
11501                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11502                     &trunc);
11503                 break;
11504         case 3:         /*Info Query EAs From List*/
11505         case 4:         /*Info Query All EAs*/
11506                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11507                     &trunc);
11508                 break;
11509         case 6:         /*Info Is Name Valid*/
11510                 offset = dissect_4_2_16_3(tvb, pinfo, tree, offset, bcp,
11511                     &trunc);
11512                 break;
11513         case 0x0101:    /*Query File Basic Info*/
11514         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11515                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11516                     &trunc);
11517                 break;
11518         case 0x0102:    /*Query File Standard Info*/
11519         case 1005:      /* SMB_FILE_STANDARD_INFORMATION */
11520                 offset = dissect_4_2_16_5(tvb, pinfo, tree, offset, bcp,
11521                     &trunc);
11522                 break;
11523         case 0x0103:    /*Query File EA Info*/
11524         case 1007:      /* SMB_FILE_EA_INFORMATION */
11525                 offset = dissect_4_2_16_6(tvb, pinfo, tree, offset, bcp,
11526                     &trunc);
11527                 break;
11528         case 0x0104:    /*Query File Name Info*/
11529         case 1009:      /* SMB_FILE_NAME_INFORMATION */
11530                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11531                     &trunc);
11532                 break;
11533         case 0x0107:    /*Query File All Info*/
11534         case 1018:      /* SMB_FILE_ALL_INFORMATION */
11535                 offset = dissect_4_2_16_8(tvb, pinfo, tree, offset, bcp,
11536                     &trunc);
11537                 break;
11538         case 0x0108:    /*Query File Alt File Info*/
11539         case 1021:      /* SMB_FILE_ALTERNATE_NAME_INFORMATION */
11540                 offset = dissect_4_2_16_7(tvb, pinfo, tree, offset, bcp,
11541                     &trunc);
11542                 break;
11543         case 1022:      /* SMB_FILE_STREAM_INFORMATION */
11544                 ((smb_info_t *)(pinfo->private_data))->unicode = TRUE;
11545         case 0x0109:    /*Query File Stream Info*/
11546                 offset = dissect_4_2_16_10(tvb, pinfo, tree, offset, bcp,
11547                     &trunc);
11548                 break;
11549         case 0x010b:    /*Query File Compression Info*/
11550         case 1028:      /* SMB_FILE_COMPRESSION_INFORMATION */
11551                 offset = dissect_4_2_16_11(tvb, pinfo, tree, offset, bcp,
11552                     &trunc);
11553                 break;
11554         case 0x0200:    /* Query File Unix Basic*/
11555                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp, 
11556                                            &trunc);
11557                 break;
11558         case 0x0201:    /* Query File Unix Link*/
11559                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp, 
11560                                            &trunc);
11561                 break;
11562         case 0x0202:    /* Query File Unix HardLink*/
11563                 /* XXX add this from the SNIA doc */
11564                 break;
11565         }
11566
11567         return offset;
11568 }
11569
11570 /*dissect the data block for TRANS2_SET_PATH_INFORMATION and
11571   TRANS2_SET_FILE_INFORMATION*/
11572 static int
11573 dissect_spi_loi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
11574     int offset, guint16 *bcp)
11575 {
11576         smb_info_t *si;
11577         gboolean trunc;
11578
11579         if(!*bcp){
11580                 return offset;
11581         }
11582
11583         si = (smb_info_t *)pinfo->private_data;
11584         switch(si->info_level){
11585         case 1:         /*Info Standard*/
11586                 
11587         case 2:         /*Info Query EA Size*/
11588                 offset = dissect_4_2_16_1(tvb, pinfo, tree, offset, bcp,
11589                     &trunc);
11590                 break;
11591         case 4:         /*Info Query All EAs*/
11592                 offset = dissect_4_2_16_2(tvb, pinfo, tree, offset, bcp,
11593                     &trunc);
11594                 break;
11595         case 0x0101:    /*Set File Basic Info*/
11596         case 1004:      /* SMB_FILE_BASIC_INFORMATION */
11597                 offset = dissect_4_2_16_4(tvb, pinfo, tree, offset, bcp,
11598                     &trunc);
11599                 break;
11600         case 0x0102:    /*Set File Disposition Info*/
11601                 offset = dissect_4_2_19_2(tvb, pinfo, tree, offset, bcp,
11602                     &trunc);
11603                 break;
11604         case 0x0103:    /*Set File Allocation Info*/
11605                 offset = dissect_4_2_19_3(tvb, pinfo, tree, offset, bcp,
11606                     &trunc);
11607                 break;
11608         case 0x0104:    /*Set End Of File Info*/
11609                 offset = dissect_4_2_19_4(tvb, pinfo, tree, offset, bcp,
11610                     &trunc);
11611                 break;
11612         case 0x0200:    /*Set File Unix Basic.  Same as query. */
11613                 offset = dissect_4_2_16_12(tvb, pinfo, tree, offset, bcp,
11614                     &trunc);
11615                 break;
11616         case 0x0201:    /*Set File Unix Link.  Same as query. */
11617                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11618                     &trunc);
11619                 break;
11620         case 0x0203:    /*Set File Unix HardLink.  Same as link query. */
11621                 offset = dissect_4_2_16_13(tvb, pinfo, tree, offset, bcp,
11622                     &trunc);
11623                 break;
11624         case 1010:      /* Set File Rename */
11625                 offset = dissect_rename_info(tvb, pinfo, tree, offset, bcp,
11626                     &trunc);
11627                 break;
11628         case 1013:
11629         case 1014:
11630         case 1016:
11631         case 1019:
11632         case 1020:
11633         case 1023:
11634         case 1025:
11635         case 1029:
11636         case 1032:
11637         case 1039:
11638         case 1040:
11639                 /* XXX: TODO, extra levels discovered by tridge */
11640                 break;
11641         }
11642
11643         return offset;
11644 }
11645
11646
11647 static const true_false_string tfs_quota_flags_deny_disk = {
11648         "DENY DISK SPACE for users exceeding quota limit",
11649         "Do NOT deny disk space for users exceeding quota limit"
11650 };
11651 static const true_false_string tfs_quota_flags_log_limit = {
11652         "LOG EVENT when a user exceeds their QUOTA LIMIT",
11653         "Do NOT log event when a user exceeds their quota limit"
11654 };
11655 static const true_false_string tfs_quota_flags_log_warning = {
11656         "LOG EVENT when a user exceeds their WARNING LEVEL",
11657         "Do NOT log event when a user exceeds their warning level"
11658 };
11659 static const true_false_string tfs_quota_flags_enabled = {
11660         "Quotas are ENABLED of this fs",
11661         "Quotas are NOT enabled on this fs"
11662 };
11663 static void
11664 dissect_quota_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
11665 {
11666         guint8 mask;
11667         proto_item *item = NULL;
11668         proto_tree *tree = NULL;
11669
11670         mask = tvb_get_guint8(tvb, offset);
11671
11672         if(parent_tree){
11673                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
11674                         "Quota Flags: 0x%02x %s", mask,
11675                         mask?"Enabled":"Disabled");
11676                 tree = proto_item_add_subtree(item, ett_smb_quotaflags);
11677         }
11678
11679         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
11680                 tvb, offset, 1, mask);
11681         proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
11682                 tvb, offset, 1, mask);
11683         proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
11684                 tvb, offset, 1, mask);
11685
11686         if(mask && (!(mask&0x01))){
11687                 proto_tree_add_boolean_hidden(tree, hf_smb_quota_flags_enabled,
11688                         tvb, offset, 1, 0x01);
11689         } else {
11690                 proto_tree_add_boolean(tree, hf_smb_quota_flags_enabled,
11691                         tvb, offset, 1, mask);
11692         }
11693
11694 }
11695
11696 static int
11697 dissect_nt_quota(tvbuff_t *tvb, proto_tree *tree, int offset, guint16 *bcp)
11698 {
11699         /* first 24 bytes are unknown */
11700         CHECK_BYTE_COUNT_TRANS_SUBR(24);
11701         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11702                     offset, 24, TRUE);
11703         COUNT_BYTES_TRANS_SUBR(24);
11704
11705         /* number of bytes for quota warning */
11706         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11707         proto_tree_add_item(tree, hf_smb_soft_quota_limit, tvb, offset, 8, TRUE);
11708         COUNT_BYTES_TRANS_SUBR(8);
11709
11710         /* number of bytes for quota limit */
11711         CHECK_BYTE_COUNT_TRANS_SUBR(8);
11712         proto_tree_add_item(tree, hf_smb_hard_quota_limit, tvb, offset, 8, TRUE);
11713         COUNT_BYTES_TRANS_SUBR(8);
11714
11715         /* one byte of quota flags */
11716         CHECK_BYTE_COUNT_TRANS_SUBR(1);
11717         dissect_quota_flags(tvb, tree, offset);
11718         COUNT_BYTES_TRANS_SUBR(1);
11719
11720         /* these 7 bytes are unknown */
11721         CHECK_BYTE_COUNT_TRANS_SUBR(7);
11722         proto_tree_add_item(tree, hf_smb_unknown, tvb,
11723                     offset, 7, TRUE);
11724         COUNT_BYTES_TRANS_SUBR(7);
11725
11726         return offset;
11727 }
11728
11729 static int
11730 dissect_transaction2_request_data(tvbuff_t *tvb, packet_info *pinfo,
11731     proto_tree *parent_tree, int offset, int subcmd, guint16 dc)
11732 {
11733         proto_item *item = NULL;
11734         proto_tree *tree = NULL;
11735         smb_info_t *si;
11736
11737         si = (smb_info_t *)pinfo->private_data;
11738
11739         if(parent_tree){
11740                 item = proto_tree_add_text(parent_tree, tvb, offset, dc,
11741                                 "%s Data",
11742                                 val_to_str(subcmd, trans2_cmd_vals,
11743                                                 "Unknown (0x%02x)"));
11744                 tree = proto_item_add_subtree(item, ett_smb_transaction_data);
11745         }
11746
11747         switch(subcmd){
11748         case 0x00:      /*TRANS2_OPEN2*/
11749                 /* XXX dont know how to decode FEAList */
11750                 break;
11751         case 0x01:      /*TRANS2_FIND_FIRST2*/
11752                 /* XXX dont know how to decode FEAList */
11753                 break;
11754         case 0x02:      /*TRANS2_FIND_NEXT2*/
11755                 /* XXX dont know how to decode FEAList */
11756                 break;
11757         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
11758                 /* no data field in this request */
11759                 break;
11760         case 0x04:      /* TRANS2_SET_QUOTA */
11761                 offset = dissect_nt_quota(tvb, tree, offset, &dc);
11762                 break;
11763         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
11764                 /* no data field in this request */
11765                 /*
11766                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11767                  * Extensions Version 3.0, Document Version 1.11,
11768                  * July 19, 1990" says there may be "Additional
11769                  * FileInfoLevel dependent information" here.
11770                  *
11771                  * Was that just a cut-and-pasteo?
11772                  * TRANS2_SET_PATH_INFORMATION *does* have that information
11773                  * here.
11774                  */
11775                 break;
11776         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
11777                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11778                 break;
11779         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
11780                 /* no data field in this request */
11781                 /*
11782                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11783                  * Extensions Version 3.0, Document Version 1.11,
11784                  * July 19, 1990" says there may be "Additional
11785                  * FileInfoLevel dependent information" here.
11786                  *
11787                  * Was that just a cut-and-pasteo?
11788                  * TRANS2_SET_FILE_INFORMATION *does* have that information
11789                  * here.
11790                  */
11791                 break;
11792         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
11793                 offset = dissect_spi_loi_vals(tvb, pinfo, tree, offset, &dc);
11794                 break;
11795         case 0x09:      /*TRANS2_FSCTL*/
11796                 /*XXX dont know how to decode this yet */
11797
11798                 /*
11799                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11800                  * Extensions Version 3.0, Document Version 1.11,
11801                  * July 19, 1990" says this this contains a
11802                  * "File system specific data block".  (That means we
11803                  * may not be able to dissect it in any case.)
11804                  */
11805                 break;
11806         case 0x0a:      /*TRANS2_IOCTL2*/
11807                 /*XXX dont know how to decode this yet */
11808
11809                 /*
11810                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11811                  * Extensions Version 3.0, Document Version 1.11,
11812                  * July 19, 1990" says this this contains a
11813                  * "Device/function specific data block".  (That
11814                  * means we may not be able to dissect it in any case.)
11815                  */
11816                 break;
11817         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
11818                 /*XXX dont know how to decode this yet */
11819
11820                 /*
11821                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11822                  * Extensions Version 3.0, Document Version 1.11,
11823                  * July 19, 1990" says this this contains "additional
11824                  * level dependent match data".
11825                  */
11826                 break;
11827         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
11828                 /*XXX dont know how to decode this yet */
11829
11830                 /*
11831                  * XXX - "Microsoft Networks SMB File Sharing Protocol
11832                  * Extensions Version 3.0, Document Version 1.11,
11833                  * July 19, 1990" says this this contains "additional
11834                  * level dependent monitor information".
11835                  */
11836                 break;
11837         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
11838                 /* XXX optional FEAList, unknown what FEAList looks like*/
11839                 break;
11840         case 0x0e:      /*TRANS2_SESSION_SETUP*/
11841                 /*XXX dont know how to decode this yet */
11842                 break;
11843         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
11844                 /* no data field in this request */
11845                 break;
11846         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
11847                 offset = dissect_dfs_inconsistency_data(tvb, pinfo, tree, offset, &dc);
11848                 break;
11849         }
11850
11851         /* ooops there were data we didnt know how to process */
11852         if(dc != 0){
11853                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
11854                 offset += dc;
11855         }
11856
11857         return offset;
11858 }
11859
11860
11861 static void
11862 dissect_trans_data(tvbuff_t *s_tvb, tvbuff_t *p_tvb, tvbuff_t *d_tvb,
11863     proto_tree *tree)
11864 {
11865         int i;
11866         int offset;
11867         guint length;
11868
11869         /*
11870          * Show the setup words.
11871          */
11872         if (s_tvb != NULL) {
11873                 length = tvb_reported_length(s_tvb);
11874                 for (i = 0, offset = 0; length >= 2;
11875                     i++, offset += 2, length -= 2) {
11876                         /*
11877                          * XXX - add a setup word filterable field?
11878                          */
11879                         proto_tree_add_text(tree, s_tvb, offset, 2,
11880                             "Setup Word %d: 0x%04x", i,
11881                             tvb_get_letohs(s_tvb, offset));
11882                 }
11883         }
11884
11885         /*
11886          * Show the parameters, if any.
11887          */
11888         if (p_tvb != NULL) {
11889                 length = tvb_reported_length(p_tvb);
11890                 if (length != 0) {
11891                         proto_tree_add_text(tree, p_tvb, 0, length,
11892                             "Parameters: %s",
11893                             tvb_bytes_to_str(p_tvb, 0, length));
11894                 }
11895         }
11896
11897         /*
11898          * Show the data, if any.
11899          */
11900         if (d_tvb != NULL) {
11901                 length = tvb_reported_length(d_tvb);
11902                 if (length != 0) {
11903                         proto_tree_add_text(tree, d_tvb, 0, length,
11904                             "Data: %s", tvb_bytes_to_str(d_tvb, 0, length));
11905                 }
11906         }
11907 }
11908
11909 /* This routine handles the following 4 calls
11910    Transaction  0x25
11911    Transaction Secondary 0x26
11912    Transaction2 0x32
11913    Transaction2 Secondary 0x33
11914 */
11915 static int
11916 dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
11917 {
11918         guint8 wc, sc=0;
11919         int so=offset;
11920         int sl=0;
11921         int spo=offset;
11922         int spc=0;
11923         guint16 od=0, tf, po=0, pc=0, dc=0, pd, dd=0;
11924         int subcmd = -1;
11925         guint32 to;
11926         int an_len;
11927         const char *an = NULL;
11928         smb_info_t *si;
11929         smb_transact2_info_t *t2i;
11930         smb_transact_info_t *tri;
11931         guint16 bc;
11932         int padcnt;
11933         gboolean dissected_trans;
11934
11935         si = (smb_info_t *)pinfo->private_data;
11936
11937         WORD_COUNT;
11938
11939         if(wc==8){
11940                 /*secondary client request*/
11941
11942                 /* total param count, only a 16bit integer here*/
11943                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11944                 offset += 2;
11945
11946                 /* total data count , only 16bit integer here*/
11947                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11948                 offset += 2;
11949
11950                 /* param count */
11951                 pc = tvb_get_letohs(tvb, offset);
11952                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
11953                 offset += 2;
11954
11955                 /* param offset */
11956                 po = tvb_get_letohs(tvb, offset);
11957                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
11958                 offset += 2;
11959
11960                 /* param disp */
11961                 pd = tvb_get_letohs(tvb, offset);
11962                 proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
11963                 offset += 2;
11964
11965                 /* data count */
11966                 dc = tvb_get_letohs(tvb, offset);
11967                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
11968                 offset += 2;
11969
11970                 /* data offset */
11971                 od = tvb_get_letohs(tvb, offset);
11972                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
11973                 offset += 2;
11974
11975                 /* data disp */
11976                 dd = tvb_get_letohs(tvb, offset);
11977                 proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
11978                 offset += 2;
11979
11980                 if(si->cmd==SMB_COM_TRANSACTION2){
11981                         guint16 fid;
11982
11983                         /* fid */
11984                         fid = tvb_get_letohs(tvb, offset);
11985                         add_fid(tvb, pinfo, tree, offset, 2, fid);
11986
11987                         offset += 2;
11988                 }
11989
11990                 /* There are no setup words. */
11991                 so = offset;
11992                 sc = 0;
11993                 sl = 0;
11994         } else {
11995                 /* it is not a secondary request */
11996
11997                 /* total param count , only a 16 bit integer here*/
11998                 proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
11999                 offset += 2;
12000
12001                 /* total data count , only 16bit integer here*/
12002                 proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12003                 offset += 2;
12004
12005                 /* max param count , only 16bit integer here*/
12006                 proto_tree_add_uint(tree, hf_smb_max_param_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12007                 offset += 2;
12008
12009                 /* max data count, only 16bit integer here*/
12010                 proto_tree_add_uint(tree, hf_smb_max_data_count, tvb, offset, 2, tvb_get_letohs(tvb, offset));
12011                 offset += 2;
12012
12013                 /* max setup count, only 16bit integer here*/
12014                 proto_tree_add_uint(tree, hf_smb_max_setup_count, tvb, offset, 1, tvb_get_guint8(tvb, offset));
12015                 offset += 1;
12016
12017                 /* reserved byte */
12018                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12019                 offset += 1;
12020
12021                 /* transaction flags */
12022                 tf = dissect_transaction_flags(tvb, tree, offset);
12023                 offset += 2;
12024
12025                 /* timeout */
12026                 to = tvb_get_letohl(tvb, offset);
12027                 if (to == 0)
12028                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Return immediately (0)");
12029                 else if (to == 0xffffffff)
12030                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: Wait indefinitely (-1)");
12031                 else
12032                         proto_tree_add_uint_format(tree, hf_smb_timeout, tvb, offset, 4, to, "Timeout: %s", time_msecs_to_str(to));
12033                 offset += 4;
12034
12035                 /* 2 reserved bytes */
12036                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
12037                 offset += 2;
12038
12039                 /* param count */
12040                 pc = tvb_get_letohs(tvb, offset);
12041                 proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
12042                 offset += 2;
12043
12044                 /* param offset */
12045                 po = tvb_get_letohs(tvb, offset);
12046                 proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
12047                 offset += 2;
12048
12049                 /* param displacement is zero here */
12050                 pd = 0;
12051
12052                 /* data count */
12053                 dc = tvb_get_letohs(tvb, offset);
12054                 proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
12055                 offset += 2;
12056
12057                 /* data offset */
12058                 od = tvb_get_letohs(tvb, offset);
12059                 proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
12060                 offset += 2;
12061
12062                 /* data displacement is zero here */
12063                 dd = 0;
12064
12065                 /* setup count */
12066                 sc = tvb_get_guint8(tvb, offset);
12067                 proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
12068                 offset += 1;
12069
12070                 /* reserved byte */
12071                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12072                 offset += 1;
12073
12074                 /* this is where the setup bytes, if any start */
12075                 so = offset;
12076                 sl = sc*2;
12077
12078                 /* if there were any setup bytes, decode them */
12079                 if(sc){
12080                         switch(si->cmd){
12081
12082                         case SMB_COM_TRANSACTION2:
12083                                 /* TRANSACTION2 only has one setup word and
12084                                    that is the subcommand code.
12085
12086                                    XXX - except for TRANS2_FSCTL
12087                                    and TRANS2_IOCTL. */
12088                                 subcmd = tvb_get_letohs(tvb, offset);
12089                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd,
12090                                     tvb, offset, 2, subcmd);
12091                                 if (check_col(pinfo->cinfo, COL_INFO)) {
12092                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
12093                                             val_to_str(subcmd, trans2_cmd_vals,
12094                                                 "Unknown (0x%02x)"));
12095                                 }
12096                                 if (!si->unidir) {
12097                                         if(!pinfo->fd->flags.visited){
12098                                                 /*
12099                                                  * Allocate a new
12100                                                  * smb_transact2_info_t
12101                                                  * structure.
12102                                                  */
12103                                                 t2i = g_mem_chunk_alloc(smb_transact2_info_chunk);
12104                                                 t2i->subcmd = subcmd;
12105                                                 t2i->info_level = -1;
12106                                                 t2i->resume_keys = FALSE;
12107                                                 si->sip->extra_info = t2i;
12108                                         }
12109                                 }
12110
12111                                 /*
12112                                  * XXX - process TRANS2_FSCTL and
12113                                  * TRANS2_IOCTL setup words here.
12114                                  */
12115                                 break;
12116
12117                         case SMB_COM_TRANSACTION:
12118                                 /* TRANSACTION setup words processed below */
12119                                 break;
12120                         }
12121
12122                         offset += sl;
12123                 }
12124         }
12125
12126         BYTE_COUNT;
12127
12128         if(wc!=8){
12129                 /* primary request */
12130                 /* name is NULL if transaction2 */
12131                 if(si->cmd == SMB_COM_TRANSACTION){
12132                         /* Transaction Name */
12133                         an = get_unicode_or_ascii_string(tvb, &offset,
12134                                 si->unicode, &an_len, FALSE, FALSE, &bc);
12135                         if (an == NULL)
12136                                 goto endofcommand;
12137                         proto_tree_add_string(tree, hf_smb_trans_name, tvb,
12138                                 offset, an_len, an);
12139                         COUNT_BYTES(an_len);
12140                 }
12141         }
12142
12143         /*
12144          * The pipe or mailslot arguments for Transaction start with
12145          * the first setup word (or where the first setup word would
12146          * be if there were any setup words), and run to the current
12147          * offset (which could mean that there aren't any).
12148          */
12149         spo = so;
12150         spc = offset - spo;
12151
12152         /* parameters */
12153         if(po>offset){
12154                 /* We have some initial padding bytes.
12155                 */
12156                 padcnt = po-offset;
12157                 if (padcnt > bc)
12158                         padcnt = bc;
12159                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12160                 COUNT_BYTES(padcnt);
12161         }
12162         if(pc){
12163                 CHECK_BYTE_COUNT(pc);
12164                 switch(si->cmd) {
12165
12166                 case SMB_COM_TRANSACTION2:
12167                         /* TRANSACTION2 parameters*/
12168                         offset = dissect_transaction2_request_parameters(tvb,
12169                             pinfo, tree, offset, subcmd, pc);
12170                         bc -= pc;
12171                         break;
12172
12173                 case SMB_COM_TRANSACTION:
12174                         /* TRANSACTION parameters processed below */
12175                         COUNT_BYTES(pc);
12176                         break;
12177                 }
12178         }
12179
12180         /* data */
12181         if(od>offset){
12182                 /* We have some initial padding bytes.
12183                 */
12184                 padcnt = od-offset;
12185                 if (padcnt > bc)
12186                         padcnt = bc;
12187                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
12188                 COUNT_BYTES(padcnt);
12189         }
12190         if(dc){
12191                 CHECK_BYTE_COUNT(dc);
12192                 switch(si->cmd){
12193
12194                 case SMB_COM_TRANSACTION2:
12195                         /* TRANSACTION2 data*/
12196                         offset = dissect_transaction2_request_data(tvb, pinfo,
12197                             tree, offset, subcmd, dc);
12198                         bc -= dc;
12199                         break;
12200
12201                 case SMB_COM_TRANSACTION:
12202                         /* TRANSACTION data processed below */
12203                         COUNT_BYTES(dc);
12204                         break;
12205                 }
12206         }
12207
12208         /*TRANSACTION request parameters */
12209         if(si->cmd==SMB_COM_TRANSACTION){
12210                 /*XXX replace this block with a function and use that one
12211                      for both requests/responses*/
12212                 if(dd==0){
12213                         tvbuff_t *p_tvb, *d_tvb, *s_tvb;
12214                         tvbuff_t *sp_tvb, *pd_tvb;
12215
12216                         if(pc>0){
12217                                 if(pc>tvb_length_remaining(tvb, po)){
12218                                         p_tvb = tvb_new_subset(tvb, po, tvb_length_remaining(tvb, po), pc);
12219                                 } else {
12220                                         p_tvb = tvb_new_subset(tvb, po, pc, pc);
12221                                 }
12222                         } else {
12223                                 p_tvb = NULL;
12224                         }
12225                         if(dc>0){
12226                                 if(dc>tvb_length_remaining(tvb, od)){
12227                                         d_tvb = tvb_new_subset(tvb, od, tvb_length_remaining(tvb, od), dc);
12228                                 } else {
12229                                         d_tvb = tvb_new_subset(tvb, od, dc, dc);
12230                                 }
12231                         } else {
12232                                 d_tvb = NULL;
12233                         }
12234                         if(sl){
12235                                 if(sl>tvb_length_remaining(tvb, so)){
12236                                         s_tvb = tvb_new_subset(tvb, so, tvb_length_remaining(tvb, so), sl);
12237                                 } else {
12238                                         s_tvb = tvb_new_subset(tvb, so, sl, sl);
12239                                 }
12240                         } else {
12241                                 s_tvb = NULL;
12242                         }
12243
12244                         if (!si->unidir) {
12245                                 if(!pinfo->fd->flags.visited){
12246                                         /*
12247                                          * Allocate a new smb_transact_info_t
12248                                          * structure.
12249                                          */
12250                                         tri = g_mem_chunk_alloc(smb_transact_info_chunk);
12251                                         tri->subcmd = -1;
12252                                         tri->trans_subcmd = -1;
12253                                         tri->function = -1;
12254                                         tri->fid = -1;
12255                                         tri->lanman_cmd = 0;
12256                                         tri->param_descrip = NULL;
12257                                         tri->data_descrip = NULL;
12258                                         tri->aux_data_descrip = NULL;
12259                                         tri->info_level = -1;
12260                                         si->sip->extra_info = tri;
12261                                 } else {
12262                                         /*
12263                                          * We already filled the structure
12264                                          * in; don't bother doing so again.
12265                                          */
12266                                         tri = NULL;
12267                                 }
12268                         } else {
12269                                 /*
12270                                  * This is a unidirectional message, for
12271                                  * which there will be no reply; don't
12272                                  * bother allocating an "smb_transact_info_t"
12273                                  * structure for it.
12274                                  */
12275                                 tri = NULL;
12276                         }
12277                         dissected_trans = FALSE;
12278                         if(strncmp("\\PIPE\\", an, 6) == 0){
12279                                 if (tri != NULL)
12280                                         tri->subcmd=TRANSACTION_PIPE;
12281
12282                                 /*
12283                                  * A tvbuff containing the setup words and
12284                                  * the pipe path.
12285                                  */
12286                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12287
12288                                 /*
12289                                  * A tvbuff containing the parameters and the
12290                                  * data.
12291                                  */
12292                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
12293
12294                                 dissected_trans = dissect_pipe_smb(sp_tvb,
12295                                     s_tvb, pd_tvb, p_tvb, d_tvb, an+6, pinfo,
12296                                     top_tree);
12297
12298                                 /* In case we did not see the TreeConnect call,
12299                                    store this TID here as well as a IPC TID 
12300                                    so we know that future Read/Writes to this 
12301                                    TID is (probably) DCERPC.
12302                                 */
12303                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)){
12304                                         g_hash_table_remove(si->ct->tid_service, (void *)si->tid);
12305                                 }
12306                                 g_hash_table_insert(si->ct->tid_service, (void *)si->tid, (void *)TID_IPC);
12307                         } else if(strncmp("\\MAILSLOT\\", an, 10) == 0){
12308                                 if (tri != NULL)
12309                                         tri->subcmd=TRANSACTION_MAILSLOT;
12310
12311                                 /*
12312                                  * A tvbuff containing the setup words and
12313                                  * the mailslot path.
12314                                  */
12315                                 sp_tvb = tvb_new_subset(tvb, spo, spc, spc);
12316                                 dissected_trans = dissect_mailslot_smb(sp_tvb,
12317                                     s_tvb, d_tvb, an+10, pinfo, top_tree);
12318                         }
12319                         if (!dissected_trans)
12320                                 dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
12321                 } else {
12322                         if(check_col(pinfo->cinfo, COL_INFO)){
12323                                 col_append_str(pinfo->cinfo, COL_INFO,
12324                                         "[transact continuation]");
12325                         }
12326                 }
12327         }
12328
12329         END_OF_SMB
12330
12331         return offset;
12332 }
12333
12334
12335
12336 static int
12337 dissect_4_3_4_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12338     int offset, guint16 *bcp, gboolean *trunc)
12339 {
12340         int fn_len;
12341         const char *fn;
12342         int old_offset = offset;
12343         proto_item *item = NULL;
12344         proto_tree *tree = NULL;
12345         smb_info_t *si;
12346         smb_transact2_info_t *t2i;
12347         gboolean resume_keys = FALSE;
12348
12349         si = (smb_info_t *)pinfo->private_data;
12350         if (si->sip != NULL) {
12351                 t2i = si->sip->extra_info;
12352                 if (t2i != NULL)
12353                         resume_keys = t2i->resume_keys;
12354         }
12355
12356         if(parent_tree){
12357                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12358                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12359                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12360         }
12361
12362         if (resume_keys) {
12363                 /* resume key */
12364                 CHECK_BYTE_COUNT_SUBR(4);
12365                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12366                 COUNT_BYTES_SUBR(4);
12367         }
12368
12369         /* create time */
12370         CHECK_BYTE_COUNT_SUBR(4);
12371         offset = dissect_smb_datetime(tvb, tree, offset,
12372                 hf_smb_create_time,
12373                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12374         *bcp -= 4;
12375
12376         /* access time */
12377         CHECK_BYTE_COUNT_SUBR(4);
12378         offset = dissect_smb_datetime(tvb, tree, offset,
12379                 hf_smb_access_time,
12380                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12381         *bcp -= 4;
12382
12383         /* last write time */
12384         CHECK_BYTE_COUNT_SUBR(4);
12385         offset = dissect_smb_datetime(tvb, tree, offset,
12386                 hf_smb_last_write_time,
12387                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12388         *bcp -= 4;
12389
12390         /* data size */
12391         CHECK_BYTE_COUNT_SUBR(4);
12392         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12393         COUNT_BYTES_SUBR(4);
12394
12395         /* allocation size */
12396         CHECK_BYTE_COUNT_SUBR(4);
12397         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12398         COUNT_BYTES_SUBR(4);
12399
12400         /* File Attributes */
12401         CHECK_BYTE_COUNT_SUBR(2);
12402         offset = dissect_file_attributes(tvb, tree, offset, 2);
12403         *bcp -= 2;
12404
12405         /* file name len */
12406         CHECK_BYTE_COUNT_SUBR(1);
12407         fn_len = tvb_get_guint8(tvb, offset);
12408         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12409         COUNT_BYTES_SUBR(1);
12410         if (si->unicode)
12411                 fn_len += 2;    /* include terminating '\0' */
12412         else
12413                 fn_len++;       /* include terminating '\0' */
12414
12415         /* file name */
12416         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12417         CHECK_STRING_SUBR(fn);
12418         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12419                 fn);
12420         COUNT_BYTES_SUBR(fn_len);
12421
12422         if (check_col(pinfo->cinfo, COL_INFO)) {
12423                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12424                 fn);
12425         }
12426
12427         proto_item_append_text(item, " File: %s", fn);
12428         proto_item_set_len(item, offset-old_offset);
12429
12430         *trunc = FALSE;
12431         return offset;
12432 }
12433
12434 static int
12435 dissect_4_3_4_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12436     int offset, guint16 *bcp, gboolean *trunc)
12437 {
12438         int fn_len;
12439         const char *fn;
12440         int old_offset = offset;
12441         proto_item *item = NULL;
12442         proto_tree *tree = NULL;
12443         smb_info_t *si;
12444         smb_transact2_info_t *t2i;
12445         gboolean resume_keys = FALSE;
12446
12447         si = (smb_info_t *)pinfo->private_data;
12448         if (si->sip != NULL) {
12449                 t2i = si->sip->extra_info;
12450                 if (t2i != NULL)
12451                         resume_keys = t2i->resume_keys;
12452         }
12453
12454         if(parent_tree){
12455                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12456                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12457                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12458         }
12459
12460         if (resume_keys) {
12461                 /* resume key */
12462                 CHECK_BYTE_COUNT_SUBR(4);
12463                 proto_tree_add_item(tree, hf_smb_resume, tvb, offset, 4, TRUE);
12464                 COUNT_BYTES_SUBR(4);
12465         }
12466
12467         /* create time */
12468         CHECK_BYTE_COUNT_SUBR(4);
12469         offset = dissect_smb_datetime(tvb, tree, offset,
12470                 hf_smb_create_time,
12471                 hf_smb_create_dos_date, hf_smb_create_dos_time, FALSE);
12472         *bcp -= 4;
12473
12474         /* access time */
12475         CHECK_BYTE_COUNT_SUBR(4);
12476         offset = dissect_smb_datetime(tvb, tree, offset,
12477                 hf_smb_access_time,
12478                 hf_smb_access_dos_date, hf_smb_access_dos_time, FALSE);
12479         *bcp -= 4;
12480
12481         /* last write time */
12482         CHECK_BYTE_COUNT_SUBR(4);
12483         offset = dissect_smb_datetime(tvb, tree, offset,
12484                 hf_smb_last_write_time,
12485                 hf_smb_last_write_dos_date, hf_smb_last_write_dos_time, FALSE);
12486         *bcp -= 4;
12487
12488         /* data size */
12489         CHECK_BYTE_COUNT_SUBR(4);
12490         proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
12491         COUNT_BYTES_SUBR(4);
12492
12493         /* allocation size */
12494         CHECK_BYTE_COUNT_SUBR(4);
12495         proto_tree_add_item(tree, hf_smb_alloc_size, tvb, offset, 4, TRUE);
12496         COUNT_BYTES_SUBR(4);
12497
12498         /* File Attributes */
12499         CHECK_BYTE_COUNT_SUBR(2);
12500         offset = dissect_file_attributes(tvb, tree, offset, 2);
12501         *bcp -= 2;
12502
12503         /* ea length */
12504         CHECK_BYTE_COUNT_SUBR(4);
12505         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12506         COUNT_BYTES_SUBR(4);
12507
12508         /* file name len */
12509         CHECK_BYTE_COUNT_SUBR(1);
12510         fn_len = tvb_get_guint8(tvb, offset);
12511         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 1, fn_len);
12512         COUNT_BYTES_SUBR(1);
12513         if (si->unicode)
12514                 fn_len += 2;    /* include terminating '\0' */
12515         else
12516                 fn_len++;       /* include terminating '\0' */
12517
12518         /* file name */
12519         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12520         CHECK_STRING_SUBR(fn);
12521         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12522                 fn);
12523         COUNT_BYTES_SUBR(fn_len);
12524
12525         if (check_col(pinfo->cinfo, COL_INFO)) {
12526                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12527                 fn);
12528         }
12529
12530         proto_item_append_text(item, " File: %s", fn);
12531         proto_item_set_len(item, offset-old_offset);
12532
12533         *trunc = FALSE;
12534         return offset;
12535 }
12536
12537 static int
12538 dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12539     int offset, guint16 *bcp, gboolean *trunc)
12540 {
12541         int fn_len;
12542         const char *fn;
12543         int old_offset = offset;
12544         proto_item *item = NULL;
12545         proto_tree *tree = NULL;
12546         smb_info_t *si;
12547         guint32 neo;
12548         int padcnt;
12549
12550         si = (smb_info_t *)pinfo->private_data;
12551
12552         if(parent_tree){
12553                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12554                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12555                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12556         }
12557
12558         /*
12559          * We assume that the presence of a next entry offset implies the
12560          * absence of a resume key, as appears to be the case for 4.3.4.6.
12561          */
12562
12563         /* next entry offset */
12564         CHECK_BYTE_COUNT_SUBR(4);
12565         neo = tvb_get_letohl(tvb, offset);
12566         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12567         COUNT_BYTES_SUBR(4);
12568
12569         /* file index */
12570         CHECK_BYTE_COUNT_SUBR(4);
12571         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12572         COUNT_BYTES_SUBR(4);
12573
12574         /* create time */
12575         CHECK_BYTE_COUNT_SUBR(8);
12576         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12577         *bcp -= 8;
12578
12579         /* access time */
12580         CHECK_BYTE_COUNT_SUBR(8);
12581         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12582         *bcp -= 8;
12583
12584         /* last write time */
12585         CHECK_BYTE_COUNT_SUBR(8);
12586         offset = dissect_smb_64bit_time(tvb, tree, offset,
12587                 hf_smb_last_write_time);
12588         *bcp -= 8;
12589
12590         /* last change time */
12591         CHECK_BYTE_COUNT_SUBR(8);
12592         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12593         *bcp -= 8;
12594
12595         /* end of file */
12596         CHECK_BYTE_COUNT_SUBR(8);
12597         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12598         COUNT_BYTES_SUBR(8);
12599
12600         /* allocation size */
12601         CHECK_BYTE_COUNT_SUBR(8);
12602         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12603         COUNT_BYTES_SUBR(8);
12604
12605         /* Extended File Attributes */
12606         CHECK_BYTE_COUNT_SUBR(4);
12607         offset = dissect_file_ext_attr(tvb, tree, offset);
12608         *bcp -= 4;
12609
12610         /* file name len */
12611         CHECK_BYTE_COUNT_SUBR(4);
12612         fn_len = tvb_get_letohl(tvb, offset);
12613         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12614         COUNT_BYTES_SUBR(4);
12615
12616         /* file name */
12617         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12618         CHECK_STRING_SUBR(fn);
12619         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12620                 fn);
12621         COUNT_BYTES_SUBR(fn_len);
12622
12623         if (check_col(pinfo->cinfo, COL_INFO)) {
12624                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12625                 fn);
12626         }
12627
12628         /* skip to next structure */
12629         if(neo){
12630                 padcnt = (old_offset + neo) - offset;
12631                 if (padcnt < 0) {
12632                         /*
12633                          * XXX - this is bogus; flag it?
12634                          */
12635                         padcnt = 0;
12636                 }
12637                 if (padcnt != 0) {
12638                         CHECK_BYTE_COUNT_SUBR(padcnt);
12639                         COUNT_BYTES_SUBR(padcnt);
12640                 }
12641         }
12642
12643         proto_item_append_text(item, " File: %s", fn);
12644         proto_item_set_len(item, offset-old_offset);
12645
12646         *trunc = FALSE;
12647         return offset;
12648 }
12649
12650 static int
12651 dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12652     int offset, guint16 *bcp, gboolean *trunc)
12653 {
12654         int fn_len;
12655         const char *fn;
12656         int old_offset = offset;
12657         proto_item *item = NULL;
12658         proto_tree *tree = NULL;
12659         smb_info_t *si;
12660         guint32 neo;
12661         int padcnt;
12662
12663         si = (smb_info_t *)pinfo->private_data;
12664
12665         if(parent_tree){
12666                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12667                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12668                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12669         }
12670
12671         /*
12672          * We assume that the presence of a next entry offset implies the
12673          * absence of a resume key, as appears to be the case for 4.3.4.6.
12674          */
12675
12676         /* next entry offset */
12677         CHECK_BYTE_COUNT_SUBR(4);
12678         neo = tvb_get_letohl(tvb, offset);
12679         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12680         COUNT_BYTES_SUBR(4);
12681
12682         /* file index */
12683         CHECK_BYTE_COUNT_SUBR(4);
12684         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12685         COUNT_BYTES_SUBR(4);
12686
12687         /* create time */
12688         CHECK_BYTE_COUNT_SUBR(8);
12689         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12690         *bcp -= 8;
12691
12692         /* access time */
12693         CHECK_BYTE_COUNT_SUBR(8);
12694         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12695         *bcp -= 8;
12696
12697         /* last write time */
12698         CHECK_BYTE_COUNT_SUBR(8);
12699         offset = dissect_smb_64bit_time(tvb, tree, offset,
12700                 hf_smb_last_write_time);
12701         *bcp -= 8;
12702
12703         /* last change time */
12704         CHECK_BYTE_COUNT_SUBR(8);
12705         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12706         *bcp -= 8;
12707
12708         /* end of file */
12709         CHECK_BYTE_COUNT_SUBR(8);
12710         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12711         COUNT_BYTES_SUBR(8);
12712
12713         /* allocation size */
12714         CHECK_BYTE_COUNT_SUBR(8);
12715         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12716         COUNT_BYTES_SUBR(8);
12717
12718         /* Extended File Attributes */
12719         CHECK_BYTE_COUNT_SUBR(4);
12720         offset = dissect_file_ext_attr(tvb, tree, offset);
12721         *bcp -= 4;
12722
12723         /* file name len */
12724         CHECK_BYTE_COUNT_SUBR(4);
12725         fn_len = tvb_get_letohl(tvb, offset);
12726         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12727         COUNT_BYTES_SUBR(4);
12728
12729         /* ea length */
12730         CHECK_BYTE_COUNT_SUBR(4);
12731         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12732         COUNT_BYTES_SUBR(4);
12733
12734         /* file name */
12735         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12736         CHECK_STRING_SUBR(fn);
12737         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12738                 fn);
12739         COUNT_BYTES_SUBR(fn_len);
12740
12741         if (check_col(pinfo->cinfo, COL_INFO)) {
12742                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12743                 fn);
12744         }
12745
12746         /* skip to next structure */
12747         if(neo){
12748                 padcnt = (old_offset + neo) - offset;
12749                 if (padcnt < 0) {
12750                         /*
12751                          * XXX - this is bogus; flag it?
12752                          */
12753                         padcnt = 0;
12754                 }
12755                 if (padcnt != 0) {
12756                         CHECK_BYTE_COUNT_SUBR(padcnt);
12757                         COUNT_BYTES_SUBR(padcnt);
12758                 }
12759         }
12760
12761         proto_item_append_text(item, " File: %s", fn);
12762         proto_item_set_len(item, offset-old_offset);
12763
12764         *trunc = FALSE;
12765         return offset;
12766 }
12767
12768 static int
12769 dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12770     int offset, guint16 *bcp, gboolean *trunc)
12771 {
12772         int fn_len, sfn_len;
12773         const char *fn, *sfn;
12774         int old_offset = offset;
12775         proto_item *item = NULL;
12776         proto_tree *tree = NULL;
12777         smb_info_t *si;
12778         guint32 neo;
12779         int padcnt;
12780
12781         si = (smb_info_t *)pinfo->private_data;
12782
12783         if(parent_tree){
12784                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12785                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12786                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12787         }
12788
12789         /*
12790          * XXX - I have not seen any of these that contain a resume
12791          * key, even though some of the requests had the "return resume
12792          * key" flag set.
12793          */
12794
12795         /* next entry offset */
12796         CHECK_BYTE_COUNT_SUBR(4);
12797         neo = tvb_get_letohl(tvb, offset);
12798         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12799         COUNT_BYTES_SUBR(4);
12800
12801         /* file index */
12802         CHECK_BYTE_COUNT_SUBR(4);
12803         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12804         COUNT_BYTES_SUBR(4);
12805
12806         /* create time */
12807         CHECK_BYTE_COUNT_SUBR(8);
12808         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
12809         *bcp -= 8;
12810
12811         /* access time */
12812         CHECK_BYTE_COUNT_SUBR(8);
12813         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_access_time);
12814         *bcp -= 8;
12815
12816         /* last write time */
12817         CHECK_BYTE_COUNT_SUBR(8);
12818         offset = dissect_smb_64bit_time(tvb, tree, offset,
12819                 hf_smb_last_write_time);
12820         *bcp -= 8;
12821
12822         /* last change time */
12823         CHECK_BYTE_COUNT_SUBR(8);
12824         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_change_time);
12825         *bcp -= 8;
12826
12827         /* end of file */
12828         CHECK_BYTE_COUNT_SUBR(8);
12829         proto_tree_add_item(tree, hf_smb_end_of_file, tvb, offset, 8, TRUE);
12830         COUNT_BYTES_SUBR(8);
12831
12832         /* allocation size */
12833         CHECK_BYTE_COUNT_SUBR(8);
12834         proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
12835         COUNT_BYTES_SUBR(8);
12836
12837         /* Extended File Attributes */
12838         CHECK_BYTE_COUNT_SUBR(4);
12839         offset = dissect_file_ext_attr(tvb, tree, offset);
12840         *bcp -= 4;
12841
12842         /* file name len */
12843         CHECK_BYTE_COUNT_SUBR(4);
12844         fn_len = tvb_get_letohl(tvb, offset);
12845         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12846         COUNT_BYTES_SUBR(4);
12847
12848         /*
12849          * EA length.
12850          *
12851          * XXX - in one captures, this has the topmost bit set, and the
12852          * rest of the bits have the value 7.  Is the topmost bit being
12853          * set some indication that the value *isn't* the length of
12854          * the EAs?
12855          */
12856         CHECK_BYTE_COUNT_SUBR(4);
12857         proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
12858         COUNT_BYTES_SUBR(4);
12859
12860         /* short file name len */
12861         CHECK_BYTE_COUNT_SUBR(1);
12862         sfn_len = tvb_get_guint8(tvb, offset);
12863         proto_tree_add_uint(tree, hf_smb_short_file_name_len, tvb, offset, 1, sfn_len);
12864         COUNT_BYTES_SUBR(1);
12865
12866         /* reserved byte */
12867         CHECK_BYTE_COUNT_SUBR(1);
12868         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
12869         COUNT_BYTES_SUBR(1);
12870
12871         /* short file name - it's not always in Unicode */
12872         sfn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &sfn_len, FALSE, TRUE, bcp);
12873         CHECK_STRING_SUBR(sfn);
12874         proto_tree_add_string(tree, hf_smb_short_file_name, tvb, offset, 24,
12875                 sfn);
12876         COUNT_BYTES_SUBR(24);
12877
12878         /* file name */
12879         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12880         CHECK_STRING_SUBR(fn);
12881         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12882                 fn);
12883         COUNT_BYTES_SUBR(fn_len);
12884
12885         if (check_col(pinfo->cinfo, COL_INFO)) {
12886                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12887                 fn);
12888         }
12889
12890         /* skip to next structure */
12891         if(neo){
12892                 padcnt = (old_offset + neo) - offset;
12893                 if (padcnt < 0) {
12894                         /*
12895                          * XXX - this is bogus; flag it?
12896                          */
12897                         padcnt = 0;
12898                 }
12899                 if (padcnt != 0) {
12900                         CHECK_BYTE_COUNT_SUBR(padcnt);
12901                         COUNT_BYTES_SUBR(padcnt);
12902                 }
12903         }
12904
12905         proto_item_append_text(item, " File: %s", fn);
12906         proto_item_set_len(item, offset-old_offset);
12907
12908         *trunc = FALSE;
12909         return offset;
12910 }
12911
12912 static int
12913 dissect_4_3_4_7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
12914     int offset, guint16 *bcp, gboolean *trunc)
12915 {
12916         int fn_len;
12917         const char *fn;
12918         int old_offset = offset;
12919         proto_item *item = NULL;
12920         proto_tree *tree = NULL;
12921         smb_info_t *si;
12922         guint32 neo;
12923         int padcnt;
12924
12925         si = (smb_info_t *)pinfo->private_data;
12926
12927         if(parent_tree){
12928                 item = proto_tree_add_text(parent_tree, tvb, offset, *bcp, "%s",
12929                     val_to_str(si->info_level, ff2_il_vals, "Unknown (0x%02x)"));
12930                 tree = proto_item_add_subtree(item, ett_smb_ff2_data);
12931         }
12932
12933         /*
12934          * We assume that the presence of a next entry offset implies the
12935          * absence of a resume key, as appears to be the case for 4.3.4.6.
12936          */
12937
12938         /* next entry offset */
12939         CHECK_BYTE_COUNT_SUBR(4);
12940         neo = tvb_get_letohl(tvb, offset);
12941         proto_tree_add_uint(tree, hf_smb_next_entry_offset, tvb, offset, 4, neo);
12942         COUNT_BYTES_SUBR(4);
12943
12944         /* file index */
12945         CHECK_BYTE_COUNT_SUBR(4);
12946         proto_tree_add_item(tree, hf_smb_file_index, tvb, offset, 4, TRUE);
12947         COUNT_BYTES_SUBR(4);
12948
12949         /* file name len */
12950         CHECK_BYTE_COUNT_SUBR(4);
12951         fn_len = tvb_get_letohl(tvb, offset);
12952         proto_tree_add_uint(tree, hf_smb_file_name_len, tvb, offset, 4, fn_len);
12953         COUNT_BYTES_SUBR(4);
12954
12955         /* file name */
12956         fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
12957         CHECK_STRING_SUBR(fn);
12958         proto_tree_add_string(tree, hf_smb_file_name, tvb, offset, fn_len,
12959                 fn);
12960         COUNT_BYTES_SUBR(fn_len);
12961
12962         if (check_col(pinfo->cinfo, COL_INFO)) {
12963                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
12964                 fn);
12965         }
12966
12967         /* skip to next structure */
12968         if(neo){
12969                 padcnt = (old_offset + neo) - offset;
12970                 if (padcnt < 0) {
12971                         /*
12972                          * XXX - this is bogus; flag it?
12973                          */
12974                         padcnt = 0;
12975                 }
12976                 if (padcnt != 0) {
12977                         CHECK_BYTE_COUNT_SUBR(padcnt);
12978                         COUNT_BYTES_SUBR(padcnt);
12979                 }
12980         }
12981
12982         proto_item_append_text(item, " File: %s", fn);
12983         proto_item_set_len(item, offset-old_offset);
12984
12985         *trunc = FALSE;
12986         return offset;
12987 }
12988
12989 /* 4.3.4.8 - SMB_FIND_FILE_UNIX */
12990
12991 static int
12992 dissect_4_3_4_8(tvbuff_t *tvb _U_, packet_info *pinfo _U_,
12993                 proto_tree *tree, int offset, guint16 *bcp,
12994                 gboolean *trunc)
12995 {
12996         smb_info_t *si = pinfo->private_data;
12997         const char *fn;
12998         int fn_len;
12999
13000         /* NextEntryOffset */
13001         CHECK_BYTE_COUNT_SUBR(4);
13002         proto_tree_add_item(tree, hf_smb_unix_find_file_nextoffset, tvb, offset, 4, TRUE);
13003         COUNT_BYTES_SUBR(4);
13004         
13005         /* ResumeKey */
13006         CHECK_BYTE_COUNT_SUBR(4);
13007         proto_tree_add_item(tree, hf_smb_unix_find_file_resumekey, tvb, offset, 4, TRUE);
13008         COUNT_BYTES_SUBR(4);
13009
13010         /* End of file (file size) */
13011         CHECK_BYTE_COUNT_SUBR(8);
13012         proto_tree_add_item(tree, hf_smb_unix_file_size, tvb, offset, 8, TRUE);
13013         COUNT_BYTES_SUBR(8);
13014
13015         /* Number of bytes */
13016         CHECK_BYTE_COUNT_SUBR(8);
13017         proto_tree_add_item(tree, hf_smb_unix_file_num_bytes, tvb, offset, 8, TRUE);
13018         COUNT_BYTES_SUBR(8);
13019
13020         /* Last status change */
13021         CHECK_BYTE_COUNT_SUBR(8);
13022         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_status);
13023         *bcp -= 8;
13024
13025         /* Last access time */
13026         CHECK_BYTE_COUNT_SUBR(8);
13027         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_access);
13028         *bcp -= 8;
13029
13030         /* Last modification time */
13031         CHECK_BYTE_COUNT_SUBR(8);
13032         offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_unix_file_last_change);
13033         *bcp -= 8;
13034
13035         /* File owner uid */
13036         CHECK_BYTE_COUNT_SUBR(8);
13037         proto_tree_add_item(tree, hf_smb_unix_file_uid, tvb, offset, 8, TRUE);
13038         COUNT_BYTES_SUBR(8);
13039
13040         /* File group gid */
13041         CHECK_BYTE_COUNT_SUBR(8);
13042         proto_tree_add_item(tree, hf_smb_unix_file_gid, tvb, offset, 8, TRUE);
13043         COUNT_BYTES_SUBR(8);
13044
13045         /* File type */
13046         CHECK_BYTE_COUNT_SUBR(4);
13047         proto_tree_add_item(tree, hf_smb_unix_file_type, tvb, offset, 4, TRUE);
13048         COUNT_BYTES_SUBR(4);
13049
13050         /* Major device number */
13051         CHECK_BYTE_COUNT_SUBR(8);
13052         proto_tree_add_item(tree, hf_smb_unix_file_dev_major, tvb, offset, 8, TRUE);
13053         COUNT_BYTES_SUBR(8);
13054
13055         /* Minor device number */
13056         CHECK_BYTE_COUNT_SUBR(8);
13057         proto_tree_add_item(tree, hf_smb_unix_file_dev_minor, tvb, offset, 8, TRUE);
13058         COUNT_BYTES_SUBR(8);
13059
13060         /* Unique id */
13061         CHECK_BYTE_COUNT_SUBR(8);
13062         proto_tree_add_item(tree, hf_smb_unix_file_unique_id, tvb, offset, 8, TRUE);
13063         COUNT_BYTES_SUBR(8);
13064
13065         /* Permissions */
13066         CHECK_BYTE_COUNT_SUBR(8);
13067         proto_tree_add_item(tree, hf_smb_unix_file_permissions, tvb, offset, 8, TRUE);
13068         COUNT_BYTES_SUBR(8);
13069
13070         /* Nlinks */
13071         CHECK_BYTE_COUNT_SUBR(8);
13072         proto_tree_add_item(tree, hf_smb_unix_file_nlinks, tvb, offset, 8, TRUE);
13073         COUNT_BYTES_SUBR(8);
13074
13075         /* Name */
13076
13077         fn = get_unicode_or_ascii_string(
13078                 tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13079
13080         CHECK_STRING_SUBR(fn);
13081         proto_tree_add_string(
13082                 tree, hf_smb_unix_file_link_dest, tvb, offset, fn_len, fn);
13083         COUNT_BYTES_SUBR(fn_len);
13084
13085         /* Pad to 4 bytes */
13086
13087         if (offset % 4)
13088                 offset += 4 - (offset % 4);
13089
13090         *trunc = FALSE;
13091         return offset;
13092 }
13093
13094 /*dissect the data block for TRANS2_FIND_FIRST2*/
13095 static int
13096 dissect_ff2_response_data(tvbuff_t * tvb, packet_info * pinfo,
13097     proto_tree * tree, int offset, guint16 *bcp, gboolean *trunc)
13098 {
13099         smb_info_t *si;
13100
13101         if(!*bcp){
13102                 return offset;
13103         }
13104
13105         si = (smb_info_t *)pinfo->private_data;
13106         switch(si->info_level){
13107         case 1:         /*Info Standard*/
13108                 offset = dissect_4_3_4_1(tvb, pinfo, tree, offset, bcp,
13109                     trunc);
13110                 break;
13111         case 2:         /*Info Query EA Size*/
13112                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13113                     trunc);
13114                 break;
13115         case 3:         /*Info Query EAs From List same as
13116                                 InfoQueryEASize*/
13117                 offset = dissect_4_3_4_2(tvb, pinfo, tree, offset, bcp,
13118                     trunc);
13119                 break;
13120         case 0x0101:    /*Find File Directory Info*/
13121                 offset = dissect_4_3_4_4(tvb, pinfo, tree, offset, bcp,
13122                     trunc);
13123                 break;
13124         case 0x0102:    /*Find File Full Directory Info*/
13125                 offset = dissect_4_3_4_5(tvb, pinfo, tree, offset, bcp,
13126                     trunc);
13127                 break;
13128         case 0x0103:    /*Find File Names Info*/
13129                 offset = dissect_4_3_4_7(tvb, pinfo, tree, offset, bcp,
13130                     trunc);
13131                 break;
13132         case 0x0104:    /*Find File Both Directory Info*/
13133                 offset = dissect_4_3_4_6(tvb, pinfo, tree, offset, bcp,
13134                     trunc);
13135                 break;
13136         case 0x0202:    /*Find File UNIX*/
13137                 offset = dissect_4_3_4_8(tvb, pinfo, tree, offset, bcp,
13138                     trunc);
13139                 break;
13140         default:        /* unknown info level */
13141                 *trunc = FALSE;
13142                 break;
13143         }
13144         return offset;
13145 }
13146
13147
13148 static int
13149 dissect_fs_attributes(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13150 {
13151         guint32 mask;
13152         proto_item *item = NULL;
13153         proto_tree *tree = NULL;
13154
13155         mask = tvb_get_letohl(tvb, offset);
13156
13157         if(parent_tree){
13158                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13159                         "FS Attributes: 0x%08x", mask);
13160                 tree = proto_item_add_subtree(item, ett_smb_fs_attributes);
13161         }
13162
13163         proto_tree_add_boolean(tree, hf_smb_fs_attr_css,
13164                 tvb, offset, 4, mask);
13165         proto_tree_add_boolean(tree, hf_smb_fs_attr_cpn,
13166                 tvb, offset, 4, mask);
13167         proto_tree_add_boolean(tree, hf_smb_fs_attr_pacls,
13168                 tvb, offset, 4, mask);
13169         proto_tree_add_boolean(tree, hf_smb_fs_attr_fc,
13170                 tvb, offset, 4, mask);
13171         proto_tree_add_boolean(tree, hf_smb_fs_attr_vq,
13172                 tvb, offset, 4, mask);
13173         proto_tree_add_boolean(tree, hf_smb_fs_attr_dim,
13174                 tvb, offset, 4, mask);
13175         proto_tree_add_boolean(tree, hf_smb_fs_attr_vic,
13176                 tvb, offset, 4, mask);
13177
13178         offset += 4;
13179         return offset;
13180 }
13181
13182
13183 static int
13184 dissect_device_characteristics(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
13185 {
13186         guint32 mask;
13187         proto_item *item = NULL;
13188         proto_tree *tree = NULL;
13189
13190         mask = tvb_get_letohl(tvb, offset);
13191
13192         if(parent_tree){
13193                 item = proto_tree_add_text(parent_tree, tvb, offset, 4,
13194                         "Device Characteristics: 0x%08x", mask);
13195                 tree = proto_item_add_subtree(item, ett_smb_device_characteristics);
13196         }
13197
13198         proto_tree_add_boolean(tree, hf_smb_device_char_removable,
13199                 tvb, offset, 4, mask);
13200         proto_tree_add_boolean(tree, hf_smb_device_char_read_only,
13201                 tvb, offset, 4, mask);
13202         proto_tree_add_boolean(tree, hf_smb_device_char_floppy,
13203                 tvb, offset, 4, mask);
13204         proto_tree_add_boolean(tree, hf_smb_device_char_write_once,
13205                 tvb, offset, 4, mask);
13206         proto_tree_add_boolean(tree, hf_smb_device_char_remote,
13207                 tvb, offset, 4, mask);
13208         proto_tree_add_boolean(tree, hf_smb_device_char_mounted,
13209                 tvb, offset, 4, mask);
13210         proto_tree_add_boolean(tree, hf_smb_device_char_virtual,
13211                 tvb, offset, 4, mask);
13212
13213         offset += 4;
13214         return offset;
13215 }
13216
13217 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
13218
13219 static const true_false_string tfs_smb_mac_access_ctrl = {
13220   "Macintosh Access Control Supported",
13221   "Macintosh Access Control Not Supported"
13222 };
13223
13224 static const true_false_string tfs_smb_mac_getset_comments = {
13225   "Macintosh Get & Set Comments Supported",
13226   "Macintosh Get & Set Comments Not Supported"
13227 };
13228
13229 static const true_false_string tfs_smb_mac_desktopdb_calls = {
13230   "Macintosh Get & Set Desktop Database Info Supported",
13231   "Macintosh Get & Set Desktop Database Info Supported"
13232 };
13233
13234 static const true_false_string tfs_smb_mac_unique_ids = {
13235   "Macintosh Unique IDs Supported",
13236   "Macintosh Unique IDs Not Supported"
13237 };
13238
13239 static const true_false_string tfs_smb_mac_streams = {
13240   "Macintosh and Streams Extensions Not Supported",
13241   "Macintosh and Streams Extensions Supported"
13242 };
13243
13244 static int
13245 dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
13246     int offset, guint16 *bcp)
13247 {
13248         smb_info_t *si;
13249         int fn_len, vll, fnl;
13250         const char *fn;
13251         guint support = 0;
13252         proto_item *item = NULL;
13253         proto_tree *ti = NULL;
13254
13255         if(!*bcp){
13256                 return offset;
13257         }
13258
13259         si = (smb_info_t *)pinfo->private_data;
13260         switch(si->info_level){
13261         case 1:         /* SMB_INFO_ALLOCATION */
13262                 /* filesystem id */
13263                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13264                 proto_tree_add_item(tree, hf_smb_fs_id, tvb, offset, 4, TRUE);
13265                 COUNT_BYTES_TRANS_SUBR(4);
13266
13267                 /* sectors per unit */
13268                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13269                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13270                 COUNT_BYTES_TRANS_SUBR(4);
13271
13272                 /* units */
13273                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13274                 proto_tree_add_item(tree, hf_smb_fs_units, tvb, offset, 4, TRUE);
13275                 COUNT_BYTES_TRANS_SUBR(4);
13276
13277                 /* avail units */
13278                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13279                 proto_tree_add_item(tree, hf_smb_avail_units, tvb, offset, 4, TRUE);
13280                 COUNT_BYTES_TRANS_SUBR(4);
13281
13282                 /* bytes per sector, only 16bit integer here */
13283                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13284                 proto_tree_add_uint(tree, hf_smb_fs_sector, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13285                 COUNT_BYTES_TRANS_SUBR(2);
13286
13287                 break;
13288         case 2:         /* SMB_INFO_VOLUME */
13289                 /* volume serial number */
13290                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13291                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13292                 COUNT_BYTES_TRANS_SUBR(4);
13293
13294                 /* volume label length, only one byte here */
13295                 CHECK_BYTE_COUNT_TRANS_SUBR(1);
13296                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 1, tvb_get_guint8(tvb, offset));
13297                 COUNT_BYTES_TRANS_SUBR(1);
13298
13299                 /* label */
13300                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, FALSE, bcp);
13301                 CHECK_STRING_TRANS_SUBR(fn);
13302                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13303                         fn);
13304                 COUNT_BYTES_TRANS_SUBR(fn_len);
13305
13306                 break;
13307         case 0x0101:    /* SMB_QUERY_FS_LABEL_INFO */
13308         case 1002:      /* SMB_FS_LABEL_INFORMATION */
13309                 /* volume label length */
13310                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13311                 vll = tvb_get_letohl(tvb, offset);
13312                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13313                 COUNT_BYTES_TRANS_SUBR(4);
13314
13315                 /* label */
13316                 fn_len = vll;
13317                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13318                 CHECK_STRING_TRANS_SUBR(fn);
13319                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13320                         fn);
13321                 COUNT_BYTES_TRANS_SUBR(fn_len);
13322
13323                 break;
13324         case 0x0102:    /* SMB_QUERY_FS_VOLUME_INFO */
13325         case 1001:      /* SMB_FS_VOLUME_INFORMATION */
13326                 /* create time */
13327                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13328                 offset = dissect_smb_64bit_time(tvb, tree, offset,
13329                         hf_smb_create_time);
13330                 *bcp -= 8;
13331
13332                 /* volume serial number */
13333                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13334                 proto_tree_add_item(tree, hf_smb_volume_serial_num, tvb, offset, 4, TRUE);
13335                 COUNT_BYTES_TRANS_SUBR(4);
13336
13337                 /* volume label length */
13338                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13339                 vll = tvb_get_letohl(tvb, offset);
13340                 proto_tree_add_uint(tree, hf_smb_volume_label_len, tvb, offset, 4, vll);
13341                 COUNT_BYTES_TRANS_SUBR(4);
13342
13343                 /* 2 reserved bytes */
13344                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13345                 proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
13346                 COUNT_BYTES_TRANS_SUBR(2);
13347
13348                 /* label */
13349                 fn_len = vll;
13350                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13351                 CHECK_STRING_TRANS_SUBR(fn);
13352                 proto_tree_add_string(tree, hf_smb_volume_label, tvb, offset, fn_len,
13353                         fn);
13354                 COUNT_BYTES_TRANS_SUBR(fn_len);
13355
13356                 break;
13357         case 0x0103:    /* SMB_QUERY_FS_SIZE_INFO */
13358         case 1003:      /* SMB_FS_SIZE_INFORMATION */
13359                 /* allocation size */
13360                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13361                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13362                 COUNT_BYTES_TRANS_SUBR(8);
13363
13364                 /* free allocation units */
13365                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13366                 proto_tree_add_item(tree, hf_smb_free_alloc_units64, tvb, offset, 8, TRUE);
13367                 COUNT_BYTES_TRANS_SUBR(8);
13368
13369                 /* sectors per unit */
13370                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13371                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13372                 COUNT_BYTES_TRANS_SUBR(4);
13373
13374                 /* bytes per sector */
13375                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13376                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13377                 COUNT_BYTES_TRANS_SUBR(4);
13378
13379                 break;
13380         case 0x0104:    /* SMB_QUERY_FS_DEVICE_INFO */
13381         case 1004:      /* SMB_FS_DEVICE_INFORMATION */
13382                 /* device type */
13383                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13384                 proto_tree_add_item(tree, hf_smb_device_type, tvb, offset, 4, TRUE);
13385                 COUNT_BYTES_TRANS_SUBR(4);
13386
13387                 /* device characteristics */
13388                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13389                 offset = dissect_device_characteristics(tvb, tree, offset);
13390                 *bcp -= 4;
13391
13392                 break;
13393         case 0x0105:    /* SMB_QUERY_FS_ATTRIBUTE_INFO */
13394         case 1005:      /* SMB_FS_ATTRIBUTE_INFORMATION */
13395                 /* FS attributes */
13396                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13397                 offset = dissect_fs_attributes(tvb, tree, offset);
13398                 *bcp -= 4;
13399
13400                 /* max name len */
13401                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13402                 proto_tree_add_item(tree, hf_smb_max_name_len, tvb, offset, 4, TRUE);
13403                 COUNT_BYTES_TRANS_SUBR(4);
13404
13405                 /* fs name length */
13406                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13407                 fnl = tvb_get_letohl(tvb, offset);
13408                 proto_tree_add_uint(tree, hf_smb_fs_name_len, tvb, offset, 4, fnl);
13409                 COUNT_BYTES_TRANS_SUBR(4);
13410
13411                 /* label */
13412                 fn_len = fnl;
13413                 fn = get_unicode_or_ascii_string(tvb, &offset, si->unicode, &fn_len, FALSE, TRUE, bcp);
13414                 CHECK_STRING_TRANS_SUBR(fn);
13415                 proto_tree_add_string(tree, hf_smb_fs_name, tvb, offset, fn_len,
13416                         fn);
13417                 COUNT_BYTES_TRANS_SUBR(fn_len);
13418
13419                 break;
13420         case 0x200: {   /* SMB_QUERY_CIFS_UNIX_INFO */
13421                 proto_item *item = NULL;
13422                 proto_tree *subtree = NULL;
13423                 guint32 caps_lo, caps_hi;
13424
13425                 /* MajorVersionNumber */
13426                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13427                 proto_tree_add_item(tree, hf_smb_unix_major_version, tvb, offset, 2, TRUE);
13428                 COUNT_BYTES_TRANS_SUBR(2);
13429
13430                 /* MinorVersionNumber */
13431                 CHECK_BYTE_COUNT_TRANS_SUBR(2);
13432                 proto_tree_add_item(tree, hf_smb_unix_minor_version, tvb, offset, 2, TRUE);
13433                 COUNT_BYTES_TRANS_SUBR(2);
13434
13435                 /* Capability */
13436
13437                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13438
13439                 caps_lo = tvb_get_letohl(tvb, offset);
13440                 caps_hi = tvb_get_letohl(tvb, offset + 4);
13441
13442                 if (tree) {
13443                         item = proto_tree_add_text(
13444                                 tree, tvb, offset, 8, "Capabilities: 0x%08x%08x", 
13445                                 caps_hi, caps_lo);
13446                         subtree = proto_item_add_subtree(
13447                                 item, ett_smb_unix_capabilities);
13448                 }
13449
13450                 proto_tree_add_boolean(
13451                         subtree, hf_smb_unix_capability_fcntl, tvb, offset, 8, 
13452                         caps_lo);
13453
13454                 proto_tree_add_boolean(
13455                         subtree, hf_smb_unix_capability_posix_acl, tvb, offset, 8, 
13456                         caps_lo);
13457
13458                 COUNT_BYTES_TRANS_SUBR(8);
13459
13460                 break;
13461         }
13462         case 0x301:     /* MAC_QUERY_FS_INFO */
13463                 /* Create time */
13464                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13465                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_create_time);
13466                 *bcp -= 8;
13467                 /* Modify Time */
13468                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13469                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_modify_time);
13470                 *bcp -= 8;
13471                 /* Backup Time */
13472                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13473                 offset = dissect_smb_64bit_time(tvb, tree, offset, hf_smb_backup_time);
13474                 *bcp -= 8;
13475                 /* Allocation blocks */
13476                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13477                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_count, tvb,
13478                                     offset,
13479                                     4, TRUE);
13480                 COUNT_BYTES_TRANS_SUBR(4);
13481                 /* Allocation Block Size */
13482                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13483                 proto_tree_add_item(tree, hf_smb_mac_alloc_block_size, tvb,
13484                                     offset, 4, TRUE);
13485                 COUNT_BYTES_TRANS_SUBR(4);
13486                 /* Free Block Count */
13487                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13488                 proto_tree_add_item(tree, hf_smb_mac_free_block_count, tvb,
13489                                     offset, 4, TRUE);
13490                 COUNT_BYTES_TRANS_SUBR(4);
13491                 /* Finder Info ... */
13492                 CHECK_BYTE_COUNT_TRANS_SUBR(32);
13493                 proto_tree_add_bytes_format(tree, hf_smb_mac_fndrinfo, tvb,
13494                                             offset, 32,
13495                                             tvb_get_ptr(tvb, offset,32),
13496                                             "Finder Info: %s",
13497                                             tvb_format_text(tvb, offset, 32));
13498                 COUNT_BYTES_TRANS_SUBR(32);
13499                 /* Number Files */
13500                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13501                 proto_tree_add_item(tree, hf_smb_mac_root_file_count, tvb,
13502                                     offset, 4, TRUE);
13503                 COUNT_BYTES_TRANS_SUBR(4);
13504                 /* Number of Root Directories */
13505                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13506                 proto_tree_add_item(tree, hf_smb_mac_root_dir_count, tvb,
13507                                     offset, 4, TRUE);
13508                 COUNT_BYTES_TRANS_SUBR(4);
13509                 /* Number of files */
13510                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13511                 proto_tree_add_item(tree, hf_smb_mac_file_count, tvb,
13512                                     offset, 4, TRUE);
13513                 COUNT_BYTES_TRANS_SUBR(4);
13514                 /* Dir Count */
13515                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13516                 proto_tree_add_item(tree, hf_smb_mac_dir_count, tvb,
13517                                     offset, 4, TRUE);
13518                 COUNT_BYTES_TRANS_SUBR(4);
13519                 /* Mac Support Flags */
13520                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13521                 support = tvb_get_ntohl(tvb, offset);
13522                 item = proto_tree_add_text(tree, tvb, offset, 4,
13523                                            "Mac Support Flags: 0x%08x", support);
13524                 ti = proto_item_add_subtree(item, ett_smb_mac_support_flags);
13525                 proto_tree_add_boolean(ti, hf_smb_mac_sup_access_ctrl,
13526                                        tvb, offset, 4, support);
13527                 proto_tree_add_boolean(ti, hf_smb_mac_sup_getset_comments,
13528                                        tvb, offset, 4, support);
13529                 proto_tree_add_boolean(ti, hf_smb_mac_sup_desktopdb_calls,
13530                                        tvb, offset, 4, support);
13531                 proto_tree_add_boolean(ti, hf_smb_mac_sup_unique_ids,
13532                                        tvb, offset, 4, support);
13533                 proto_tree_add_boolean(ti, hf_smb_mac_sup_streams,
13534                                        tvb, offset, 4, support);
13535                 COUNT_BYTES_TRANS_SUBR(4);
13536                 break;
13537         case 1006:      /* QUERY_FS_QUOTA_INFO */
13538                 offset = dissect_nt_quota(tvb, tree, offset, bcp);
13539                 break;
13540         case 1007:      /* SMB_FS_FULL_SIZE_INFORMATION */
13541                 /* allocation size */
13542                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13543                 proto_tree_add_item(tree, hf_smb_alloc_size64, tvb, offset, 8, TRUE);
13544                 COUNT_BYTES_TRANS_SUBR(8);
13545
13546                 /* caller free allocation units */
13547                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13548                 proto_tree_add_item(tree, hf_smb_caller_free_alloc_units64, tvb, offset, 8, TRUE);
13549                 COUNT_BYTES_TRANS_SUBR(8);
13550
13551                 /* actual free allocation units */
13552                 CHECK_BYTE_COUNT_TRANS_SUBR(8);
13553                 proto_tree_add_item(tree, hf_smb_actual_free_alloc_units64, tvb, offset, 8, TRUE);
13554                 COUNT_BYTES_TRANS_SUBR(8);
13555
13556                 /* sectors per unit */
13557                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13558                 proto_tree_add_item(tree, hf_smb_sector_unit, tvb, offset, 4, TRUE);
13559                 COUNT_BYTES_TRANS_SUBR(4);
13560
13561                 /* bytes per sector */
13562                 CHECK_BYTE_COUNT_TRANS_SUBR(4);
13563                 proto_tree_add_item(tree, hf_smb_fs_sector, tvb, offset, 4, TRUE);
13564                 COUNT_BYTES_TRANS_SUBR(4);
13565                 break;
13566         case 1008: /* Query Object ID is GUID plus unknown data */ {
13567                 e_uuid_t fs_id;
13568                 char uuid_str[DCERPC_UUID_STR_LEN]; 
13569                 int uuid_str_len;
13570                 guint8 drep = 0x10;
13571                 
13572                 CHECK_BYTE_COUNT_TRANS_SUBR(16);
13573
13574                 dcerpc_tvb_get_uuid (tvb, offset, &drep, &fs_id);
13575
13576                 uuid_str_len = snprintf(
13577                         uuid_str, DCERPC_UUID_STR_LEN, 
13578                         "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
13579                         fs_id.Data1, fs_id.Data2, fs_id.Data3,
13580                         fs_id.Data4[0], fs_id.Data4[1],
13581                         fs_id.Data4[2], fs_id.Data4[3],
13582                         fs_id.Data4[4], fs_id.Data4[5],
13583                         fs_id.Data4[6], fs_id.Data4[7]);
13584
13585                 proto_tree_add_string_format(
13586                         tree, hf_smb_fs_guid, tvb,
13587                         offset, 16, uuid_str, "GUID: %s", uuid_str);
13588
13589                 COUNT_BYTES_TRANS_SUBR(16);
13590                 break;
13591             }
13592         }
13593
13594         return offset;
13595 }
13596
13597 static int
13598 dissect_transaction2_response_data(tvbuff_t *tvb, packet_info *pinfo,
13599     proto_tree *parent_tree)
13600 {
13601         proto_item *item = NULL;
13602         proto_tree *tree = NULL;
13603         smb_info_t *si;
13604         smb_transact2_info_t *t2i;
13605         int count;
13606         gboolean trunc;
13607         int offset = 0;
13608         guint16 dc;
13609
13610         dc = tvb_reported_length(tvb);
13611
13612         si = (smb_info_t *)pinfo->private_data;
13613         if (si->sip != NULL)
13614                 t2i = si->sip->extra_info;
13615         else
13616                 t2i = NULL;
13617
13618         if(parent_tree){
13619                 if (t2i != NULL && t2i->subcmd != -1) {
13620                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13621                                 "%s Data",
13622                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13623                                         "Unknown (0x%02x)"));
13624                         tree = proto_item_add_subtree(item, ett_smb_transaction_data);
13625                 } else {
13626                         item = proto_tree_add_text(parent_tree, tvb, offset, dc,
13627                                 "Unknown Transaction2 Data");
13628                 }
13629         }
13630
13631         if (t2i == NULL) {
13632                 offset += dc;
13633                 return offset;
13634         }
13635         switch(t2i->subcmd){
13636         case 0x00:      /*TRANS2_OPEN2*/
13637                 /* XXX not implemented yet. See SNIA doc */
13638                 break;
13639         case 0x01:      /*TRANS2_FIND_FIRST2*/
13640                 /* returned data */
13641                 count = si->info_count;
13642
13643                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13644                         col_append_fstr(pinfo->cinfo, COL_INFO,
13645                         ", Files:");
13646                 }
13647
13648                 while(count--){
13649                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13650                                 offset, &dc, &trunc);
13651                         if (trunc)
13652                                 break;
13653                 }
13654                 break;
13655         case 0x02:      /*TRANS2_FIND_NEXT2*/
13656                 /* returned data */
13657                 count = si->info_count;
13658
13659                 if (count && check_col(pinfo->cinfo, COL_INFO)) {
13660                         col_append_fstr(pinfo->cinfo, COL_INFO,
13661                         ", Files:");
13662                 }
13663
13664                 while(count--){
13665                         offset = dissect_ff2_response_data(tvb, pinfo, tree,
13666                                 offset, &dc, &trunc);
13667                         if (trunc)
13668                                 break;
13669                 }
13670                 break;
13671         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13672                 offset = dissect_qfsi_vals(tvb, pinfo, tree, offset, &dc);
13673                 break;
13674         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13675                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13676                 break;
13677         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13678                 /* no data in this response */
13679                 break;
13680         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13681                 /* identical to QUERY_PATH_INFO */
13682                 offset = dissect_qpi_loi_vals(tvb, pinfo, tree, offset, &dc);
13683                 break;
13684         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13685                 /* no data in this response */
13686                 break;
13687         case 0x09:      /*TRANS2_FSCTL*/
13688                 /* XXX dont know how to dissect this one (yet)*/
13689
13690                 /*
13691                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13692                  * Extensions Version 3.0, Document Version 1.11,
13693                  * July 19, 1990" says this this contains a
13694                  * "File system specific return data block".
13695                  * (That means we may not be able to dissect it in any
13696                  * case.)
13697                  */
13698                 break;
13699         case 0x0a:      /*TRANS2_IOCTL2*/
13700                 /* XXX dont know how to dissect this one (yet)*/
13701
13702                 /*
13703                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13704                  * Extensions Version 3.0, Document Version 1.11,
13705                  * July 19, 1990" says this this contains a
13706                  * "Device/function specific return data block".
13707                  * (That means we may not be able to dissect it in any
13708                  * case.)
13709                  */
13710                 break;
13711         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13712                 /* XXX dont know how to dissect this one (yet)*/
13713
13714                 /*
13715                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13716                  * Extensions Version 3.0, Document Version 1.11,
13717                  * July 19, 1990" says this this contains "the level
13718                  * dependent information about the changes which
13719                  * occurred".
13720                  */
13721                 break;
13722         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13723                 /* XXX dont know how to dissect this one (yet)*/
13724
13725                 /*
13726                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13727                  * Extensions Version 3.0, Document Version 1.11,
13728                  * July 19, 1990" says this this contains "the level
13729                  * dependent information about the changes which
13730                  * occurred".
13731                  */
13732                 break;
13733         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13734                 /* no data in this response */
13735                 break;
13736         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13737                 /* XXX dont know how to dissect this one (yet)*/
13738                 break;
13739         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
13740                 offset = dissect_get_dfs_referral_data(tvb, pinfo, tree, offset, &dc);
13741                 break;
13742         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
13743                 /* the SNIA spec appears to say the response has no data */
13744                 break;
13745         case -1:
13746                 /*
13747                  * We don't know what the matching request was; don't
13748                  * bother putting anything else into the tree for the data.
13749                  */
13750                 offset += dc;
13751                 dc = 0;
13752                 break;
13753         }
13754
13755         /* ooops there were data we didnt know how to process */
13756         if(dc != 0){
13757                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, dc, TRUE);
13758                 offset += dc;
13759         }
13760
13761         return offset;
13762 }
13763
13764
13765 static void
13766 dissect_transaction2_response_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
13767 {
13768         proto_item *item = NULL;
13769         proto_tree *tree = NULL;
13770         smb_info_t *si;
13771         smb_transact2_info_t *t2i;
13772         guint16 fid;
13773         int lno;
13774         int offset = 0;
13775         int pc;
13776
13777         pc = tvb_reported_length(tvb);
13778
13779         si = (smb_info_t *)pinfo->private_data;
13780         if (si->sip != NULL)
13781                 t2i = si->sip->extra_info;
13782         else
13783                 t2i = NULL;
13784
13785         if(parent_tree){
13786                 if (t2i != NULL && t2i->subcmd != -1) {
13787                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13788                                 "%s Parameters",
13789                                 val_to_str(t2i->subcmd, trans2_cmd_vals,
13790                                                 "Unknown (0x%02x)"));
13791                         tree = proto_item_add_subtree(item, ett_smb_transaction_params);
13792                 } else {
13793                         item = proto_tree_add_text(parent_tree, tvb, offset, pc,
13794                                 "Unknown Transaction2 Parameters");
13795                 }
13796         }
13797
13798         if (t2i == NULL) {
13799                 offset += pc;
13800                 return;
13801         }
13802         switch(t2i->subcmd){
13803         case 0x00:      /*TRANS2_OPEN2*/
13804                 /* fid */
13805                 fid = tvb_get_letohs(tvb, offset);
13806                 add_fid(tvb, pinfo, tree, offset, 2, fid);
13807                 offset += 2;
13808
13809                 /*
13810                  * XXX - Microsoft Networks SMB File Sharing Protocol
13811                  * Extensions Version 3.0, Document Version 1.11,
13812                  * July 19, 1990 says that the file attributes, create
13813                  * time (which it says is the last modification time),
13814                  * data size, granted access, file type, and IPC state
13815                  * are returned only if bit 0 is set in the open flags,
13816                  * and that the EA length is returned only if bit 3
13817                  * is set in the open flags.  Does that mean that,
13818                  * at least in that SMB dialect, those fields are not
13819                  * present in the reply parameters if the bits in
13820                  * question aren't set?
13821                  */
13822
13823                 /* File Attributes */
13824                 offset = dissect_file_attributes(tvb, tree, offset, 2);
13825
13826                 /* create time */
13827                 offset = dissect_smb_datetime(tvb, tree, offset,
13828                         hf_smb_create_time,
13829                         hf_smb_create_dos_date, hf_smb_create_dos_time, TRUE);
13830
13831                 /* data size */
13832                 proto_tree_add_item(tree, hf_smb_data_size, tvb, offset, 4, TRUE);
13833                 offset += 4;
13834
13835                 /* granted access */
13836                 offset = dissect_access(tvb, tree, offset, "Granted");
13837
13838                 /* File Type */
13839                 proto_tree_add_item(tree, hf_smb_file_type, tvb, offset, 2, TRUE);
13840                 offset += 2;
13841
13842                 /* IPC State */
13843                 offset = dissect_ipc_state(tvb, tree, offset, FALSE);
13844
13845                 /* open_action */
13846                 offset = dissect_open_action(tvb, tree, offset);
13847
13848                 /* server unique file ID */
13849                 proto_tree_add_item(tree, hf_smb_file_id, tvb, offset, 4, TRUE);
13850                 offset += 4;
13851
13852                 /* ea error offset, only a 16 bit integer here */
13853                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13854                 offset += 2;
13855
13856                 /* ea length */
13857                 proto_tree_add_item(tree, hf_smb_ea_list_length, tvb, offset, 4, TRUE);
13858                 offset += 4;
13859
13860                 break;
13861         case 0x01:      /*TRANS2_FIND_FIRST2*/
13862                 /* Find First2 information level */
13863                 proto_tree_add_uint(tree, hf_smb_ff2_information_level, tvb, 0, 0, si->info_level);
13864
13865                 /* sid */
13866                 proto_tree_add_item(tree, hf_smb_search_id, tvb, offset, 2, TRUE);
13867                 offset += 2;
13868
13869                 /* search count */
13870                 si->info_count = tvb_get_letohs(tvb, offset);
13871                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13872                 offset += 2;
13873
13874                 /* end of search */
13875                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13876                 offset += 2;
13877
13878                 /* ea error offset, only a 16 bit integer here */
13879                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13880                 offset += 2;
13881
13882                 /* last name offset */
13883                 lno = tvb_get_letohs(tvb, offset);
13884                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13885                 offset += 2;
13886
13887                 break;
13888         case 0x02:      /*TRANS2_FIND_NEXT2*/
13889                 /* search count */
13890                 si->info_count = tvb_get_letohs(tvb, offset);
13891                 proto_tree_add_uint(tree, hf_smb_search_count, tvb, offset, 2, si->info_count);
13892                 offset += 2;
13893
13894                 /* end of search */
13895                 proto_tree_add_item(tree, hf_smb_end_of_search, tvb, offset, 2, TRUE);
13896                 offset += 2;
13897
13898                 /* ea_error_offset, only a 16 bit integer here*/
13899                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13900                 offset += 2;
13901
13902                 /* last name offset */
13903                 lno = tvb_get_letohs(tvb, offset);
13904                 proto_tree_add_uint(tree, hf_smb_last_name_offset, tvb, offset, 2, lno);
13905                 offset += 2;
13906
13907                 break;
13908         case 0x03:      /*TRANS2_QUERY_FS_INFORMATION*/
13909                 /* no parameter block here */
13910                 break;
13911         case 0x05:      /*TRANS2_QUERY_PATH_INFORMATION*/
13912                 /* ea_error_offset, only a 16 bit integer here*/
13913                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13914                 offset += 2;
13915
13916                 break;
13917         case 0x06:      /*TRANS2_SET_PATH_INFORMATION*/
13918                 /* ea_error_offset, only a 16 bit integer here*/
13919                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13920                 offset += 2;
13921
13922                 break;
13923         case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
13924                 /* ea_error_offset, only a 16 bit integer here*/
13925                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13926                 offset += 2;
13927
13928                 break;
13929         case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
13930                 /* ea_error_offset, only a 16 bit integer here*/
13931                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13932                 offset += 2;
13933
13934                 break;
13935         case 0x09:      /*TRANS2_FSCTL*/
13936                 /* XXX dont know how to dissect this one (yet)*/
13937
13938                 /*
13939                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13940                  * Extensions Version 3.0, Document Version 1.11,
13941                  * July 19, 1990" says this this contains a
13942                  * "File system specific return parameter block".
13943                  * (That means we may not be able to dissect it in any
13944                  * case.)
13945                  */
13946                 break;
13947         case 0x0a:      /*TRANS2_IOCTL2*/
13948                 /* XXX dont know how to dissect this one (yet)*/
13949
13950                 /*
13951                  * XXX - "Microsoft Networks SMB File Sharing Protocol
13952                  * Extensions Version 3.0, Document Version 1.11,
13953                  * July 19, 1990" says this this contains a
13954                  * "Device/function specific return parameter block".
13955                  * (That means we may not be able to dissect it in any
13956                  * case.)
13957                  */
13958                 break;
13959         case 0x0b:      /*TRANS2_FIND_NOTIFY_FIRST*/
13960                 /* Find Notify information level */
13961                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13962
13963                 /* Monitor handle */
13964                 proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
13965                 offset += 2;
13966
13967                 /* Change count */
13968                 si->info_count = tvb_get_letohs(tvb, offset);
13969                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13970                 offset += 2;
13971
13972                 /* ea_error_offset, only a 16 bit integer here*/
13973                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13974                 offset += 2;
13975
13976                 break;
13977         case 0x0c:      /*TRANS2_FIND_NOTIFY_NEXT*/
13978                 /* Find Notify information level */
13979                 proto_tree_add_uint(tree, hf_smb_fn_information_level, tvb, 0, 0, si->info_level);
13980
13981                 /* Change count */
13982                 si->info_count = tvb_get_letohs(tvb, offset);
13983                 proto_tree_add_uint(tree, hf_smb_change_count, tvb, offset, 2, si->info_count);
13984                 offset += 2;
13985
13986                 /* ea_error_offset, only a 16 bit integer here*/
13987                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13988                 offset += 2;
13989
13990                 break;
13991         case 0x0d:      /*TRANS2_CREATE_DIRECTORY*/
13992                 /* ea error offset, only a 16 bit integer here */
13993                 proto_tree_add_uint(tree, hf_smb_ea_error_offset, tvb, offset, 2, tvb_get_letohs(tvb, offset));
13994                 offset += 2;
13995
13996                 break;
13997         case 0x0e:      /*TRANS2_SESSION_SETUP*/
13998                 /* XXX dont know how to dissect this one (yet)*/
13999                 break;
14000         case 0x10:      /*TRANS2_GET_DFS_REFERRAL*/
14001                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14002                 break;
14003         case 0x11:      /*TRANS2_REPORT_DFS_INCONSISTENCY*/
14004                 /* XXX dont know how to dissect this one (yet) see SNIA doc*/
14005                 break;
14006         case -1:
14007                 /*
14008                  * We don't know what the matching request was; don't
14009                  * bother putting anything else into the tree for the data.
14010                  */
14011                 offset += pc;
14012                 break;
14013         }
14014
14015         /* ooops there were data we didnt know how to process */
14016         if(offset<pc){
14017                 proto_tree_add_item(tree, hf_smb_unknown, tvb, offset, pc-offset, TRUE);
14018                 offset += pc-offset;
14019         }
14020 }
14021
14022
14023 static int
14024 dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14025 {
14026         guint8 sc, wc;
14027         guint16 od=0, po=0, pc=0, pd=0, dc=0, dd=0, td=0, tp=0;
14028         smb_info_t *si;
14029         smb_transact2_info_t *t2i = NULL;
14030         guint16 bc;
14031         int padcnt;
14032         gboolean dissected_trans;
14033         fragment_data *r_fd = NULL;
14034         tvbuff_t *pd_tvb=NULL, *d_tvb=NULL, *p_tvb=NULL;
14035         tvbuff_t *s_tvb=NULL, *sp_tvb=NULL;
14036         gboolean save_fragmented;
14037
14038         si = (smb_info_t *)pinfo->private_data;
14039
14040         switch(si->cmd){
14041         case SMB_COM_TRANSACTION2:
14042                 /* transaction2 */
14043                 if (si->sip != NULL) {
14044                         t2i = si->sip->extra_info;
14045                 } else
14046                         t2i = NULL;
14047                 if (t2i == NULL) {
14048                         /*
14049                          * We didn't see the matching request, so we don't
14050                          * know what type of transaction this is.
14051                          */
14052                         proto_tree_add_text(tree, tvb, 0, 0,
14053                                 "Subcommand: <UNKNOWN> since request packet wasn't seen");
14054                         if (check_col(pinfo->cinfo, COL_INFO)) {
14055                                 col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14056                         }
14057                 } else {
14058                         si->info_level = t2i->info_level;
14059                         if (t2i->subcmd == -1) {
14060                                 /*
14061                                  * We didn't manage to extract the subcommand
14062                                  * from the matching request (perhaps because
14063                                  * the frame was short), so we don't know what
14064                                  * type of transaction this is.
14065                                  */
14066                                 proto_tree_add_text(tree, tvb, 0, 0,
14067                                         "Subcommand: <UNKNOWN> since transaction code wasn't found in request packet");
14068                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14069                                         col_append_fstr(pinfo->cinfo, COL_INFO, "<unknown>");
14070                                 }
14071                         } else {
14072                                 proto_tree_add_uint(tree, hf_smb_trans2_subcmd, tvb, 0, 0, t2i->subcmd);
14073                                 if (check_col(pinfo->cinfo, COL_INFO)) {
14074                                         col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
14075                                                 val_to_str(t2i->subcmd,
14076                                                         trans2_cmd_vals,
14077                                                         "<unknown (0x%02x)>"));
14078                                 }
14079                         }
14080                 }
14081                 break;
14082         }
14083
14084         WORD_COUNT;
14085
14086         /* total param count, only a 16bit integer here */
14087         tp = tvb_get_letohs(tvb, offset);
14088         proto_tree_add_uint(tree, hf_smb_total_param_count, tvb, offset, 2, tp);
14089         offset += 2;
14090
14091         /* total data count, only a 16 bit integer here */
14092         td = tvb_get_letohs(tvb, offset);
14093         proto_tree_add_uint(tree, hf_smb_total_data_count, tvb, offset, 2, td);
14094         offset += 2;
14095
14096         /* 2 reserved bytes */
14097         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 2, TRUE);
14098         offset += 2;
14099
14100         /* param count */
14101         pc = tvb_get_letohs(tvb, offset);
14102         proto_tree_add_uint(tree, hf_smb_param_count16, tvb, offset, 2, pc);
14103         offset += 2;
14104
14105         /* param offset */
14106         po = tvb_get_letohs(tvb, offset);
14107         proto_tree_add_uint(tree, hf_smb_param_offset16, tvb, offset, 2, po);
14108         offset += 2;
14109
14110         /* param disp */
14111         pd = tvb_get_letohs(tvb, offset);
14112         proto_tree_add_uint(tree, hf_smb_param_disp16, tvb, offset, 2, pd);
14113         offset += 2;
14114
14115         /* data count */
14116         dc = tvb_get_letohs(tvb, offset);
14117         proto_tree_add_uint(tree, hf_smb_data_count16, tvb, offset, 2, dc);
14118         offset += 2;
14119
14120         /* data offset */
14121         od = tvb_get_letohs(tvb, offset);
14122         proto_tree_add_uint(tree, hf_smb_data_offset16, tvb, offset, 2, od);
14123         offset += 2;
14124
14125         /* data disp */
14126         dd = tvb_get_letohs(tvb, offset);
14127         proto_tree_add_uint(tree, hf_smb_data_disp16, tvb, offset, 2, dd);
14128         offset += 2;
14129
14130         /* setup count */
14131         sc = tvb_get_guint8(tvb, offset);
14132         proto_tree_add_uint(tree, hf_smb_setup_count, tvb, offset, 1, sc);
14133         offset += 1;
14134
14135         /* reserved byte */
14136         proto_tree_add_item(tree, hf_smb_reserved, tvb, offset, 1, TRUE);
14137         offset += 1;
14138
14139
14140         /* if there were any setup bytes, put them in a tvb for later */
14141         if(sc){
14142                 if((2*sc)>tvb_length_remaining(tvb, offset)){
14143                         s_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), 2*sc);
14144                 } else {
14145                         s_tvb = tvb_new_subset(tvb, offset, 2*sc, 2*sc);
14146                 }
14147                 sp_tvb = tvb_new_subset(tvb, offset, -1, -1);
14148         } else {
14149                 s_tvb = NULL;
14150                 sp_tvb=NULL;
14151         }
14152         offset += 2*sc;
14153
14154
14155         BYTE_COUNT;
14156
14157
14158         /* reassembly of SMB Transaction data payload.
14159            In this section we do reassembly of both the data and parameters
14160            blocks of the SMB transaction command.
14161         */
14162         save_fragmented = pinfo->fragmented;
14163         /* do we need reassembly? */
14164         if( (td!=dc) || (tp!=pc) ){
14165                 /* oh yeah, either data or parameter section needs
14166                    reassembly
14167                 */
14168                 pinfo->fragmented = TRUE;
14169                 if(smb_trans_reassembly){
14170                         /* ...and we were told to do reassembly */
14171                         if(pc && (tvb_length_remaining(tvb, po)>=pc) ){
14172                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14173                                                              po, pc, pd, td+tp);
14174
14175                         }
14176                         if((r_fd==NULL) && dc && (tvb_length_remaining(tvb, od)>=dc) ){
14177                                 r_fd = smb_trans_defragment(tree, pinfo, tvb,
14178                                                              od, dc, dd+tp, td+tp);
14179                         }
14180                 }
14181         }
14182
14183         /* if we got a reassembled fd structure from the reassembly routine we must
14184            create pd_tvb from it
14185         */
14186         if(r_fd){
14187                 pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
14188                                              r_fd->datalen);
14189                 tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
14190                 add_new_data_source(pinfo, pd_tvb, "Reassembled SMB");
14191                 show_fragment_tree(r_fd, &smb_frag_items, tree, pinfo, pd_tvb);
14192         }
14193
14194
14195         if(pd_tvb){
14196                 /* OK we have reassembled data, extract d_tvb and p_tvb from it */
14197                 if(tp){
14198                         p_tvb = tvb_new_subset(pd_tvb, 0, tp, tp);
14199                 }
14200                 if(td){
14201                         d_tvb = tvb_new_subset(pd_tvb, tp, td, td);
14202                 }
14203         } else {
14204                 /* It was not reassembled. Do as best as we can.
14205                  * in this case we always try to dissect the stuff if
14206                  * data and param displacement is 0. i.e. for the first
14207                  * (and maybe only) packet.
14208                  */
14209                 if( (pd==0) && (dd==0) ){
14210                         int min;
14211                         int reported_min;
14212                         min = MIN(pc,tvb_length_remaining(tvb,po));
14213                         reported_min = MIN(pc,tvb_reported_length_remaining(tvb,po));
14214                         if(min && reported_min) {
14215                                 p_tvb = tvb_new_subset(tvb, po, min, reported_min);
14216                         }
14217                         min = MIN(dc,tvb_length_remaining(tvb,od));
14218                         reported_min = MIN(dc,tvb_reported_length_remaining(tvb,od));
14219                         if(min && reported_min) {
14220                                 d_tvb = tvb_new_subset(tvb, od, min, reported_min);
14221                         }
14222                         /*
14223                          * A tvbuff containing the parameters
14224                          * and the data.
14225                          * XXX - check pc and dc as well?
14226                          */
14227                         if (tvb_length_remaining(tvb, po)){
14228                                 pd_tvb = tvb_new_subset(tvb, po, -1, -1);
14229                         }
14230                 }
14231         }
14232
14233
14234
14235         /* parameters */
14236         if(po>offset){
14237                 /* We have some padding bytes.
14238                 */
14239                 padcnt = po-offset;
14240                 if (padcnt > bc)
14241                         padcnt = bc;
14242                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14243                 COUNT_BYTES(padcnt);
14244         }
14245         if(si->cmd==SMB_COM_TRANSACTION2 && p_tvb){
14246                 /* TRANSACTION2 parameters*/
14247                 dissect_transaction2_response_parameters(p_tvb, pinfo, tree);
14248         }
14249         COUNT_BYTES(pc);
14250
14251
14252         /* data */
14253         if(od>offset){
14254                 /* We have some initial padding bytes.
14255                 */
14256                 padcnt = od-offset;
14257                 if (padcnt > bc)
14258                         padcnt = bc;
14259                 proto_tree_add_item(tree, hf_smb_padding, tvb, offset, padcnt, TRUE);
14260                 COUNT_BYTES(padcnt);
14261         }
14262         /*
14263          * If the data count is bigger than the count of bytes
14264          * remaining, clamp it so that the count of bytes remaining
14265          * doesn't go negative.
14266          */
14267         if (dc > bc)
14268                 dc = bc;
14269         COUNT_BYTES(dc);
14270
14271
14272
14273         /* from now on, everything is in separate tvbuffs so we dont count
14274            the bytes with COUNT_BYTES any more.
14275            neither do we reference offset any more (which by now points to the
14276            first byte AFTER this PDU */
14277
14278
14279         if(si->cmd==SMB_COM_TRANSACTION2 && d_tvb){
14280                 /* TRANSACTION2 parameters*/
14281                 dissect_transaction2_response_data(d_tvb, pinfo, tree);
14282         }
14283
14284
14285         if(si->cmd==SMB_COM_TRANSACTION){
14286                 smb_transact_info_t *tri;
14287
14288                 dissected_trans = FALSE;
14289                 if (si->sip != NULL)
14290                         tri = si->sip->extra_info;
14291                 else
14292                         tri = NULL;
14293                 if (tri != NULL) {
14294                         switch(tri->subcmd){
14295
14296                         case TRANSACTION_PIPE:
14297                                 /* This function is safe to call for
14298                                    s_tvb==sp_tvb==NULL, i.e. if we don't
14299                                    know them at this point.
14300                                    It's also safe to call if "p_tvb"
14301                                    or "d_tvb" are null.
14302                                 */
14303                                 if( pd_tvb) {
14304                                         dissected_trans = dissect_pipe_smb(
14305                                                 sp_tvb, s_tvb, pd_tvb, p_tvb,
14306                                                 d_tvb, NULL, pinfo, top_tree);
14307                                 }
14308                                 break;
14309
14310                         case TRANSACTION_MAILSLOT:
14311                                 /* This one should be safe to call
14312                                    even if s_tvb and sp_tvb is NULL
14313                                 */
14314                                 if(d_tvb){
14315                                         dissected_trans = dissect_mailslot_smb(
14316                                                 sp_tvb, s_tvb, d_tvb, NULL, pinfo,
14317                                                 top_tree);
14318                                 }
14319                                 break;
14320                         }
14321                 }
14322                 if (!dissected_trans) {
14323                         /* This one is safe to call for s_tvb==p_tvb==d_tvb==NULL */
14324                         dissect_trans_data(s_tvb, p_tvb, d_tvb, tree);
14325                 }
14326         }
14327
14328
14329         if( (p_tvb==0) && (d_tvb==0) ){
14330                 if(check_col(pinfo->cinfo, COL_INFO)){
14331                         col_append_str(pinfo->cinfo, COL_INFO,
14332                                        "[transact continuation]");
14333                 }
14334         }
14335
14336         pinfo->fragmented = save_fragmented;
14337         END_OF_SMB
14338
14339         return offset;
14340 }
14341
14342
14343 static int
14344 dissect_find_notify_close(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14345 {
14346         guint8 wc;
14347         guint16 bc;
14348
14349         WORD_COUNT;
14350
14351         /* Monitor handle */
14352         proto_tree_add_item(tree, hf_smb_monitor_handle, tvb, offset, 2, TRUE);
14353         offset += 2;
14354
14355         BYTE_COUNT;
14356
14357         END_OF_SMB
14358
14359         return offset;
14360 }
14361
14362 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14363    END Transaction/Transaction2 Primary and secondary requests
14364    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14365
14366
14367 static int
14368 dissect_unknown(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, proto_tree *smb_tree _U_)
14369 {
14370         guint8 wc;
14371         guint16 bc;
14372
14373         WORD_COUNT;
14374
14375         if (wc != 0) {
14376                 proto_tree_add_text(tree, tvb, offset, wc*2, "Word parameters");
14377                 offset += wc*2;
14378         }
14379
14380         BYTE_COUNT;
14381
14382         if (bc != 0) {
14383                 proto_tree_add_text(tree, tvb, offset, bc, "Byte parameters");
14384                 offset += bc;
14385                 bc = 0;
14386         }
14387
14388         END_OF_SMB
14389
14390         return offset;
14391 }
14392
14393 typedef struct _smb_function {
14394        int (*request)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14395        int (*response)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14396 } smb_function;
14397
14398 static smb_function smb_dissector[256] = {
14399   /* 0x00 Create Dir*/  {dissect_old_dir_request, dissect_empty},
14400   /* 0x01 Delete Dir*/  {dissect_old_dir_request, dissect_empty},
14401   /* 0x02 Open File*/  {dissect_open_file_request, dissect_open_file_response},
14402   /* 0x03 Create File*/  {dissect_create_file_request, dissect_fid},
14403   /* 0x04 Close File*/  {dissect_close_file_request, dissect_empty},
14404   /* 0x05 Flush File*/  {dissect_fid, dissect_empty},
14405   /* 0x06 Delete File*/  {dissect_delete_file_request, dissect_empty},
14406   /* 0x07 Rename File*/  {dissect_rename_file_request, dissect_empty},
14407   /* 0x08 Query Info*/  {dissect_query_information_request, dissect_query_information_response},
14408   /* 0x09 Set Info*/  {dissect_set_information_request, dissect_empty},
14409   /* 0x0a Read File*/  {dissect_read_file_request, dissect_read_file_response},
14410   /* 0x0b Write File*/  {dissect_write_file_request, dissect_write_file_response},
14411   /* 0x0c Lock Byte Range*/  {dissect_lock_request, dissect_empty},
14412   /* 0x0d Unlock Byte Range*/  {dissect_lock_request, dissect_empty},
14413   /* 0x0e Create Temp*/  {dissect_create_temporary_request, dissect_create_temporary_response},
14414   /* 0x0f Create New*/  {dissect_create_file_request, dissect_fid},
14415
14416   /* 0x10 Check Dir*/  {dissect_old_dir_request, dissect_empty},
14417   /* 0x11 Process Exit*/  {dissect_empty, dissect_empty},
14418   /* 0x12 Seek File*/  {dissect_seek_file_request, dissect_seek_file_response},
14419   /* 0x13 Lock And Read*/  {dissect_read_file_request, dissect_lock_and_read_response},
14420   /* 0x14 Write And Unlock*/  {dissect_write_file_request, dissect_write_file_response},
14421   /* 0x15 */  {dissect_unknown, dissect_unknown},
14422   /* 0x16 */  {dissect_unknown, dissect_unknown},
14423   /* 0x17 */  {dissect_unknown, dissect_unknown},
14424   /* 0x18 */  {dissect_unknown, dissect_unknown},
14425   /* 0x19 */  {dissect_unknown, dissect_unknown},
14426   /* 0x1a Read Raw*/  {dissect_read_raw_request, dissect_unknown},
14427   /* 0x1b Read MPX*/  {dissect_read_mpx_request, dissect_read_mpx_response},
14428   /* 0x1c Read MPX Secondary*/  {dissect_unknown, dissect_unknown},
14429   /* 0x1d Write Raw*/  {dissect_write_raw_request, dissect_write_raw_response},
14430   /* 0x1e Write MPX*/  {dissect_write_mpx_request, dissect_write_mpx_response},
14431   /* 0x1f Write MPX Secondary*/  {dissect_unknown, dissect_unknown},
14432
14433   /* 0x20 Write Complete*/  {dissect_unknown, dissect_write_and_close_response},
14434   /* 0x21 */  {dissect_unknown, dissect_unknown},
14435   /* 0x22 Set Info2*/  {dissect_set_information2_request, dissect_empty},
14436   /* 0x23 Query Info2*/  {dissect_fid, dissect_query_information2_response},
14437   /* 0x24 Locking And X*/  {dissect_locking_andx_request, dissect_locking_andx_response},
14438   /* 0x25 Transaction*/         {dissect_transaction_request, dissect_transaction_response},
14439   /* 0x26 Transaction Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14440   /* 0x27 IOCTL*/  {dissect_unknown, dissect_unknown},
14441   /* 0x28 IOCTL Secondary*/  {dissect_unknown, dissect_unknown},
14442   /* 0x29 Copy File*/  {dissect_copy_request, dissect_move_copy_response},
14443   /* 0x2a Move File*/  {dissect_move_request, dissect_move_copy_response},
14444   /* 0x2b Echo*/  {dissect_echo_request, dissect_echo_response},
14445   /* 0x2c Write And Close*/  {dissect_write_and_close_request, dissect_write_and_close_response},
14446   /* 0x2d Open And X*/  {dissect_open_andx_request, dissect_open_andx_response},
14447   /* 0x2e Read And X*/  {dissect_read_andx_request, dissect_read_andx_response},
14448   /* 0x2f Write And X*/  {dissect_write_andx_request, dissect_write_andx_response},
14449
14450   /* 0x30 */  {dissect_unknown, dissect_unknown},
14451   /* 0x31 Close And Tree Disconnect */  {dissect_close_file_request, dissect_empty},
14452   /* 0x32 Transaction2*/                {dissect_transaction_request, dissect_transaction_response},
14453   /* 0x33 Transaction2 Secondary*/  {dissect_transaction_request, dissect_unknown}, /*This SMB has no response */
14454   /* 0x34 Find Close2*/  {dissect_sid, dissect_empty},
14455   /* 0x35 Find Notify Close*/  {dissect_find_notify_close, dissect_empty},
14456   /* 0x36 */  {dissect_unknown, dissect_unknown},
14457   /* 0x37 */  {dissect_unknown, dissect_unknown},
14458   /* 0x38 */  {dissect_unknown, dissect_unknown},
14459   /* 0x39 */  {dissect_unknown, dissect_unknown},
14460   /* 0x3a */  {dissect_unknown, dissect_unknown},
14461   /* 0x3b */  {dissect_unknown, dissect_unknown},
14462   /* 0x3c */  {dissect_unknown, dissect_unknown},
14463   /* 0x3d */  {dissect_unknown, dissect_unknown},
14464   /* 0x3e */  {dissect_unknown, dissect_unknown},
14465   /* 0x3f */  {dissect_unknown, dissect_unknown},
14466
14467   /* 0x40 */  {dissect_unknown, dissect_unknown},
14468   /* 0x41 */  {dissect_unknown, dissect_unknown},
14469   /* 0x42 */  {dissect_unknown, dissect_unknown},
14470   /* 0x43 */  {dissect_unknown, dissect_unknown},
14471   /* 0x44 */  {dissect_unknown, dissect_unknown},
14472   /* 0x45 */  {dissect_unknown, dissect_unknown},
14473   /* 0x46 */  {dissect_unknown, dissect_unknown},
14474   /* 0x47 */  {dissect_unknown, dissect_unknown},
14475   /* 0x48 */  {dissect_unknown, dissect_unknown},
14476   /* 0x49 */  {dissect_unknown, dissect_unknown},
14477   /* 0x4a */  {dissect_unknown, dissect_unknown},
14478   /* 0x4b */  {dissect_unknown, dissect_unknown},
14479   /* 0x4c */  {dissect_unknown, dissect_unknown},
14480   /* 0x4d */  {dissect_unknown, dissect_unknown},
14481   /* 0x4e */  {dissect_unknown, dissect_unknown},
14482   /* 0x4f */  {dissect_unknown, dissect_unknown},
14483
14484   /* 0x50 */  {dissect_unknown, dissect_unknown},
14485   /* 0x51 */  {dissect_unknown, dissect_unknown},
14486   /* 0x52 */  {dissect_unknown, dissect_unknown},
14487   /* 0x53 */  {dissect_unknown, dissect_unknown},
14488   /* 0x54 */  {dissect_unknown, dissect_unknown},
14489   /* 0x55 */  {dissect_unknown, dissect_unknown},
14490   /* 0x56 */  {dissect_unknown, dissect_unknown},
14491   /* 0x57 */  {dissect_unknown, dissect_unknown},
14492   /* 0x58 */  {dissect_unknown, dissect_unknown},
14493   /* 0x59 */  {dissect_unknown, dissect_unknown},
14494   /* 0x5a */  {dissect_unknown, dissect_unknown},
14495   /* 0x5b */  {dissect_unknown, dissect_unknown},
14496   /* 0x5c */  {dissect_unknown, dissect_unknown},
14497   /* 0x5d */  {dissect_unknown, dissect_unknown},
14498   /* 0x5e */  {dissect_unknown, dissect_unknown},
14499   /* 0x5f */  {dissect_unknown, dissect_unknown},
14500
14501   /* 0x60 */  {dissect_unknown, dissect_unknown},
14502   /* 0x61 */  {dissect_unknown, dissect_unknown},
14503   /* 0x62 */  {dissect_unknown, dissect_unknown},
14504   /* 0x63 */  {dissect_unknown, dissect_unknown},
14505   /* 0x64 */  {dissect_unknown, dissect_unknown},
14506   /* 0x65 */  {dissect_unknown, dissect_unknown},
14507   /* 0x66 */  {dissect_unknown, dissect_unknown},
14508   /* 0x67 */  {dissect_unknown, dissect_unknown},
14509   /* 0x68 */  {dissect_unknown, dissect_unknown},
14510   /* 0x69 */  {dissect_unknown, dissect_unknown},
14511   /* 0x6a */  {dissect_unknown, dissect_unknown},
14512   /* 0x6b */  {dissect_unknown, dissect_unknown},
14513   /* 0x6c */  {dissect_unknown, dissect_unknown},
14514   /* 0x6d */  {dissect_unknown, dissect_unknown},
14515   /* 0x6e */  {dissect_unknown, dissect_unknown},
14516   /* 0x6f */  {dissect_unknown, dissect_unknown},
14517
14518   /* 0x70 Tree Connect*/  {dissect_tree_connect_request, dissect_tree_connect_response},
14519   /* 0x71 Tree Disconnect*/  {dissect_empty, dissect_empty},
14520   /* 0x72 Negotiate Protocol*/  {dissect_negprot_request, dissect_negprot_response},
14521   /* 0x73 Session Setup And X*/  {dissect_session_setup_andx_request, dissect_session_setup_andx_response},
14522   /* 0x74 Logoff And X*/  {dissect_empty_andx, dissect_empty_andx},
14523   /* 0x75 Tree Connect And X*/  {dissect_tree_connect_andx_request, dissect_tree_connect_andx_response},
14524   /* 0x76 */  {dissect_unknown, dissect_unknown},
14525   /* 0x77 */  {dissect_unknown, dissect_unknown},
14526   /* 0x78 */  {dissect_unknown, dissect_unknown},
14527   /* 0x79 */  {dissect_unknown, dissect_unknown},
14528   /* 0x7a */  {dissect_unknown, dissect_unknown},
14529   /* 0x7b */  {dissect_unknown, dissect_unknown},
14530   /* 0x7c */  {dissect_unknown, dissect_unknown},
14531   /* 0x7d */  {dissect_unknown, dissect_unknown},
14532   /* 0x7e */  {dissect_unknown, dissect_unknown},
14533   /* 0x7f */  {dissect_unknown, dissect_unknown},
14534
14535   /* 0x80 Query Info Disk*/  {dissect_empty, dissect_query_information_disk_response},
14536   /* 0x81 Search Dir*/  {dissect_search_dir_request, dissect_search_dir_response},
14537   /* 0x82 Find*/  {dissect_find_request, dissect_find_response},
14538   /* 0x83 Find Unique*/  {dissect_find_request, dissect_find_response},
14539   /* 0x84 Find Close*/  {dissect_find_close_request, dissect_find_close_response},
14540   /* 0x85 */  {dissect_unknown, dissect_unknown},
14541   /* 0x86 */  {dissect_unknown, dissect_unknown},
14542   /* 0x87 */  {dissect_unknown, dissect_unknown},
14543   /* 0x88 */  {dissect_unknown, dissect_unknown},
14544   /* 0x89 */  {dissect_unknown, dissect_unknown},
14545   /* 0x8a */  {dissect_unknown, dissect_unknown},
14546   /* 0x8b */  {dissect_unknown, dissect_unknown},
14547   /* 0x8c */  {dissect_unknown, dissect_unknown},
14548   /* 0x8d */  {dissect_unknown, dissect_unknown},
14549   /* 0x8e */  {dissect_unknown, dissect_unknown},
14550   /* 0x8f */  {dissect_unknown, dissect_unknown},
14551
14552   /* 0x90 */  {dissect_unknown, dissect_unknown},
14553   /* 0x91 */  {dissect_unknown, dissect_unknown},
14554   /* 0x92 */  {dissect_unknown, dissect_unknown},
14555   /* 0x93 */  {dissect_unknown, dissect_unknown},
14556   /* 0x94 */  {dissect_unknown, dissect_unknown},
14557   /* 0x95 */  {dissect_unknown, dissect_unknown},
14558   /* 0x96 */  {dissect_unknown, dissect_unknown},
14559   /* 0x97 */  {dissect_unknown, dissect_unknown},
14560   /* 0x98 */  {dissect_unknown, dissect_unknown},
14561   /* 0x99 */  {dissect_unknown, dissect_unknown},
14562   /* 0x9a */  {dissect_unknown, dissect_unknown},
14563   /* 0x9b */  {dissect_unknown, dissect_unknown},
14564   /* 0x9c */  {dissect_unknown, dissect_unknown},
14565   /* 0x9d */  {dissect_unknown, dissect_unknown},
14566   /* 0x9e */  {dissect_unknown, dissect_unknown},
14567   /* 0x9f */  {dissect_unknown, dissect_unknown},
14568
14569   /* 0xa0 NT Transaction*/      {dissect_nt_transaction_request, dissect_nt_transaction_response},
14570   /* 0xa1 NT Trans secondary*/  {dissect_nt_transaction_request, dissect_nt_transaction_response},
14571   /* 0xa2 NT CreateAndX*/               {dissect_nt_create_andx_request, dissect_nt_create_andx_response},
14572   /* 0xa3 */  {dissect_unknown, dissect_unknown},
14573   /* 0xa4 NT Cancel*/           {dissect_nt_cancel_request, dissect_unknown}, /*no response to this one*/
14574   /* 0xa5 NT Rename*/  {dissect_nt_rename_file_request, dissect_empty},
14575   /* 0xa6 */  {dissect_unknown, dissect_unknown},
14576   /* 0xa7 */  {dissect_unknown, dissect_unknown},
14577   /* 0xa8 */  {dissect_unknown, dissect_unknown},
14578   /* 0xa9 */  {dissect_unknown, dissect_unknown},
14579   /* 0xaa */  {dissect_unknown, dissect_unknown},
14580   /* 0xab */  {dissect_unknown, dissect_unknown},
14581   /* 0xac */  {dissect_unknown, dissect_unknown},
14582   /* 0xad */  {dissect_unknown, dissect_unknown},
14583   /* 0xae */  {dissect_unknown, dissect_unknown},
14584   /* 0xaf */  {dissect_unknown, dissect_unknown},
14585
14586   /* 0xb0 */  {dissect_unknown, dissect_unknown},
14587   /* 0xb1 */  {dissect_unknown, dissect_unknown},
14588   /* 0xb2 */  {dissect_unknown, dissect_unknown},
14589   /* 0xb3 */  {dissect_unknown, dissect_unknown},
14590   /* 0xb4 */  {dissect_unknown, dissect_unknown},
14591   /* 0xb5 */  {dissect_unknown, dissect_unknown},
14592   /* 0xb6 */  {dissect_unknown, dissect_unknown},
14593   /* 0xb7 */  {dissect_unknown, dissect_unknown},
14594   /* 0xb8 */  {dissect_unknown, dissect_unknown},
14595   /* 0xb9 */  {dissect_unknown, dissect_unknown},
14596   /* 0xba */  {dissect_unknown, dissect_unknown},
14597   /* 0xbb */  {dissect_unknown, dissect_unknown},
14598   /* 0xbc */  {dissect_unknown, dissect_unknown},
14599   /* 0xbd */  {dissect_unknown, dissect_unknown},
14600   /* 0xbe */  {dissect_unknown, dissect_unknown},
14601   /* 0xbf */  {dissect_unknown, dissect_unknown},
14602
14603   /* 0xc0 Open Print File*/     {dissect_open_print_file_request, dissect_fid},
14604   /* 0xc1 Write Print File*/    {dissect_write_print_file_request, dissect_empty},
14605   /* 0xc2 Close Print File*/  {dissect_fid, dissect_empty},
14606   /* 0xc3 Get Print Queue*/     {dissect_get_print_queue_request, dissect_get_print_queue_response},
14607   /* 0xc4 */  {dissect_unknown, dissect_unknown},
14608   /* 0xc5 */  {dissect_unknown, dissect_unknown},
14609   /* 0xc6 */  {dissect_unknown, dissect_unknown},
14610   /* 0xc7 */  {dissect_unknown, dissect_unknown},
14611   /* 0xc8 */  {dissect_unknown, dissect_unknown},
14612   /* 0xc9 */  {dissect_unknown, dissect_unknown},
14613   /* 0xca */  {dissect_unknown, dissect_unknown},
14614   /* 0xcb */  {dissect_unknown, dissect_unknown},
14615   /* 0xcc */  {dissect_unknown, dissect_unknown},
14616   /* 0xcd */  {dissect_unknown, dissect_unknown},
14617   /* 0xce */  {dissect_unknown, dissect_unknown},
14618   /* 0xcf */  {dissect_unknown, dissect_unknown},
14619
14620   /* 0xd0 Send Single Block Message*/  {dissect_send_single_block_message_request, dissect_empty},
14621   /* 0xd1 Send Broadcast Message*/  {dissect_send_single_block_message_request, dissect_empty},
14622   /* 0xd2 Forward User Name*/  {dissect_forwarded_name, dissect_empty},
14623   /* 0xd3 Cancel Forward*/  {dissect_forwarded_name, dissect_empty},
14624   /* 0xd4 Get Machine Name*/  {dissect_empty, dissect_get_machine_name_response},
14625   /* 0xd5 Send Start of Multi-block Message*/  {dissect_send_multi_block_message_start_request, dissect_message_group_id},
14626   /* 0xd6 Send End of Multi-block Message*/  {dissect_message_group_id, dissect_empty},
14627   /* 0xd7 Send Text of Multi-block Message*/  {dissect_send_multi_block_message_text_request, dissect_empty},
14628   /* 0xd8 SMBreadbulk*/  {dissect_unknown, dissect_unknown},
14629   /* 0xd9 SMBwritebulk*/  {dissect_unknown, dissect_unknown},
14630   /* 0xda SMBwritebulkdata*/  {dissect_unknown, dissect_unknown},
14631   /* 0xdb */  {dissect_unknown, dissect_unknown},
14632   /* 0xdc */  {dissect_unknown, dissect_unknown},
14633   /* 0xdd */  {dissect_unknown, dissect_unknown},
14634   /* 0xde */  {dissect_unknown, dissect_unknown},
14635   /* 0xdf */  {dissect_unknown, dissect_unknown},
14636
14637   /* 0xe0 */  {dissect_unknown, dissect_unknown},
14638   /* 0xe1 */  {dissect_unknown, dissect_unknown},
14639   /* 0xe2 */  {dissect_unknown, dissect_unknown},
14640   /* 0xe3 */  {dissect_unknown, dissect_unknown},
14641   /* 0xe4 */  {dissect_unknown, dissect_unknown},
14642   /* 0xe5 */  {dissect_unknown, dissect_unknown},
14643   /* 0xe6 */  {dissect_unknown, dissect_unknown},
14644   /* 0xe7 */  {dissect_unknown, dissect_unknown},
14645   /* 0xe8 */  {dissect_unknown, dissect_unknown},
14646   /* 0xe9 */  {dissect_unknown, dissect_unknown},
14647   /* 0xea */  {dissect_unknown, dissect_unknown},
14648   /* 0xeb */  {dissect_unknown, dissect_unknown},
14649   /* 0xec */  {dissect_unknown, dissect_unknown},
14650   /* 0xed */  {dissect_unknown, dissect_unknown},
14651   /* 0xee */  {dissect_unknown, dissect_unknown},
14652   /* 0xef */  {dissect_unknown, dissect_unknown},
14653
14654   /* 0xf0 */  {dissect_unknown, dissect_unknown},
14655   /* 0xf1 */  {dissect_unknown, dissect_unknown},
14656   /* 0xf2 */  {dissect_unknown, dissect_unknown},
14657   /* 0xf3 */  {dissect_unknown, dissect_unknown},
14658   /* 0xf4 */  {dissect_unknown, dissect_unknown},
14659   /* 0xf5 */  {dissect_unknown, dissect_unknown},
14660   /* 0xf6 */  {dissect_unknown, dissect_unknown},
14661   /* 0xf7 */  {dissect_unknown, dissect_unknown},
14662   /* 0xf8 */  {dissect_unknown, dissect_unknown},
14663   /* 0xf9 */  {dissect_unknown, dissect_unknown},
14664   /* 0xfa */  {dissect_unknown, dissect_unknown},
14665   /* 0xfb */  {dissect_unknown, dissect_unknown},
14666   /* 0xfc */  {dissect_unknown, dissect_unknown},
14667   /* 0xfd */  {dissect_unknown, dissect_unknown},
14668   /* 0xfe */  {dissect_unknown, dissect_unknown},
14669   /* 0xff */  {dissect_unknown, dissect_unknown},
14670 };
14671
14672 static int
14673 dissect_smb_command(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *smb_tree, guint8 cmd, gboolean first_pdu)
14674 {
14675         smb_info_t *si;
14676
14677         si = pinfo->private_data;
14678         if(cmd!=0xff){
14679                 proto_item *cmd_item;
14680                 proto_tree *cmd_tree;
14681                 int (*dissector)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree);
14682
14683                 if (check_col(pinfo->cinfo, COL_INFO)) {
14684                         if(first_pdu){
14685                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14686                                         "%s %s",
14687                                         decode_smb_name(cmd),
14688                                         (si->request)? "Request" : "Response");
14689                         } else {
14690                                 col_append_fstr(pinfo->cinfo, COL_INFO,
14691                                         "; %s",
14692                                         decode_smb_name(cmd));
14693                         }
14694
14695                 }
14696
14697                 cmd_item = proto_tree_add_text(smb_tree, tvb, offset, -1,
14698                         "%s %s (0x%02x)",
14699                         decode_smb_name(cmd),
14700                         (si->request)?"Request":"Response",
14701                         cmd);
14702
14703                 cmd_tree = proto_item_add_subtree(cmd_item, ett_smb_command);
14704
14705                 dissector = (si->request)?
14706                         smb_dissector[cmd].request:smb_dissector[cmd].response;
14707
14708                 offset = (*dissector)(tvb, pinfo, cmd_tree, offset, smb_tree);
14709                 proto_item_set_end(cmd_item, tvb, offset);
14710         }
14711         return offset;
14712 }
14713
14714
14715 /* NOTE: this value_string array will also be used to access data directly by
14716  * index instead of val_to_str() since
14717  * 1, the array will always span every value from 0x00 to 0xff and
14718  * 2, smb_cmd_vals[i].strptr  is much cheaper than  val_to_str(i, smb_cmd_vals,)
14719  * This means that this value_string array MUST always
14720  * 1, contain all entries 0x00 to 0xff
14721  * 2, all entries must be in order.
14722  */
14723 const value_string smb_cmd_vals[] = {
14724   { 0x00, "Create Directory" },
14725   { 0x01, "Delete Directory" },
14726   { 0x02, "Open" },
14727   { 0x03, "Create" },
14728   { 0x04, "Close" },
14729   { 0x05, "Flush" },
14730   { 0x06, "Delete" },
14731   { 0x07, "Rename" },
14732   { 0x08, "Query Information" },
14733   { 0x09, "Set Information" },
14734   { 0x0A, "Read" },
14735   { 0x0B, "Write" },
14736   { 0x0C, "Lock Byte Range" },
14737   { 0x0D, "Unlock Byte Range" },
14738   { 0x0E, "Create Temp" },
14739   { 0x0F, "Create New" },
14740   { 0x10, "Check Directory" },
14741   { 0x11, "Process Exit" },
14742   { 0x12, "Seek" },
14743   { 0x13, "Lock And Read" },
14744   { 0x14, "Write And Unlock" },
14745   { 0x15, "unknown-0x15" },
14746   { 0x16, "unknown-0x16" },
14747   { 0x17, "unknown-0x17" },
14748   { 0x18, "unknown-0x18" },
14749   { 0x19, "unknown-0x19" },
14750   { 0x1A, "Read Raw" },
14751   { 0x1B, "Read MPX" },
14752   { 0x1C, "Read MPX Secondary" },
14753   { 0x1D, "Write Raw" },
14754   { 0x1E, "Write MPX" },
14755   { 0x1F, "Write MPX Secondary" },
14756   { 0x20, "Write Complete" },
14757   { 0x21, "unknown-0x21" },
14758   { 0x22, "Set Information2" },
14759   { 0x23, "Query Information2" },
14760   { 0x24, "Locking AndX" },
14761   { 0x25, "Trans" },
14762   { 0x26, "Trans Secondary" },
14763   { 0x27, "IOCTL" },
14764   { 0x28, "IOCTL Secondary" },
14765   { 0x29, "Copy" },
14766   { 0x2A, "Move" },
14767   { 0x2B, "Echo" },
14768   { 0x2C, "Write And Close" },
14769   { 0x2D, "Open AndX" },
14770   { 0x2E, "Read AndX" },
14771   { 0x2F, "Write AndX" },
14772   { 0x30, "unknown-0x30" },
14773   { 0x31, "Close And Tree Disconnect" },
14774   { 0x32, "Trans2" },
14775   { 0x33, "Trans2 Secondary" },
14776   { 0x34, "Find Close2" },
14777   { 0x35, "Find Notify Close" },
14778   { 0x36, "unknown-0x36" },
14779   { 0x37, "unknown-0x37" },
14780   { 0x38, "unknown-0x38" },
14781   { 0x39, "unknown-0x39" },
14782   { 0x3A, "unknown-0x3A" },
14783   { 0x3B, "unknown-0x3B" },
14784   { 0x3C, "unknown-0x3C" },
14785   { 0x3D, "unknown-0x3D" },
14786   { 0x3E, "unknown-0x3E" },
14787   { 0x3F, "unknown-0x3F" },
14788   { 0x40, "unknown-0x40" },
14789   { 0x41, "unknown-0x41" },
14790   { 0x42, "unknown-0x42" },
14791   { 0x43, "unknown-0x43" },
14792   { 0x44, "unknown-0x44" },
14793   { 0x45, "unknown-0x45" },
14794   { 0x46, "unknown-0x46" },
14795   { 0x47, "unknown-0x47" },
14796   { 0x48, "unknown-0x48" },
14797   { 0x49, "unknown-0x49" },
14798   { 0x4A, "unknown-0x4A" },
14799   { 0x4B, "unknown-0x4B" },
14800   { 0x4C, "unknown-0x4C" },
14801   { 0x4D, "unknown-0x4D" },
14802   { 0x4E, "unknown-0x4E" },
14803   { 0x4F, "unknown-0x4F" },
14804   { 0x50, "unknown-0x50" },
14805   { 0x51, "unknown-0x51" },
14806   { 0x52, "unknown-0x52" },
14807   { 0x53, "unknown-0x53" },
14808   { 0x54, "unknown-0x54" },
14809   { 0x55, "unknown-0x55" },
14810   { 0x56, "unknown-0x56" },
14811   { 0x57, "unknown-0x57" },
14812   { 0x58, "unknown-0x58" },
14813   { 0x59, "unknown-0x59" },
14814   { 0x5A, "unknown-0x5A" },
14815   { 0x5B, "unknown-0x5B" },
14816   { 0x5C, "unknown-0x5C" },
14817   { 0x5D, "unknown-0x5D" },
14818   { 0x5E, "unknown-0x5E" },
14819   { 0x5F, "unknown-0x5F" },
14820   { 0x60, "unknown-0x60" },
14821   { 0x61, "unknown-0x61" },
14822   { 0x62, "unknown-0x62" },
14823   { 0x63, "unknown-0x63" },
14824   { 0x64, "unknown-0x64" },
14825   { 0x65, "unknown-0x65" },
14826   { 0x66, "unknown-0x66" },
14827   { 0x67, "unknown-0x67" },
14828   { 0x68, "unknown-0x68" },
14829   { 0x69, "unknown-0x69" },
14830   { 0x6A, "unknown-0x6A" },
14831   { 0x6B, "unknown-0x6B" },
14832   { 0x6C, "unknown-0x6C" },
14833   { 0x6D, "unknown-0x6D" },
14834   { 0x6E, "unknown-0x6E" },
14835   { 0x6F, "unknown-0x6F" },
14836   { 0x70, "Tree Connect" },
14837   { 0x71, "Tree Disconnect" },
14838   { 0x72, "Negotiate Protocol" },
14839   { 0x73, "Session Setup AndX" },
14840   { 0x74, "Logoff AndX" },
14841   { 0x75, "Tree Connect AndX" },
14842   { 0x76, "unknown-0x76" },
14843   { 0x77, "unknown-0x77" },
14844   { 0x78, "unknown-0x78" },
14845   { 0x79, "unknown-0x79" },
14846   { 0x7A, "unknown-0x7A" },
14847   { 0x7B, "unknown-0x7B" },
14848   { 0x7C, "unknown-0x7C" },
14849   { 0x7D, "unknown-0x7D" },
14850   { 0x7E, "unknown-0x7E" },
14851   { 0x7F, "unknown-0x7F" },
14852   { 0x80, "Query Information Disk" },
14853   { 0x81, "Search" },
14854   { 0x82, "Find" },
14855   { 0x83, "Find Unique" },
14856   { 0x84, "Find Close" },
14857   { 0x85, "unknown-0x85" },
14858   { 0x86, "unknown-0x86" },
14859   { 0x87, "unknown-0x87" },
14860   { 0x88, "unknown-0x88" },
14861   { 0x89, "unknown-0x89" },
14862   { 0x8A, "unknown-0x8A" },
14863   { 0x8B, "unknown-0x8B" },
14864   { 0x8C, "unknown-0x8C" },
14865   { 0x8D, "unknown-0x8D" },
14866   { 0x8E, "unknown-0x8E" },
14867   { 0x8F, "unknown-0x8F" },
14868   { 0x90, "unknown-0x90" },
14869   { 0x91, "unknown-0x91" },
14870   { 0x92, "unknown-0x92" },
14871   { 0x93, "unknown-0x93" },
14872   { 0x94, "unknown-0x94" },
14873   { 0x95, "unknown-0x95" },
14874   { 0x96, "unknown-0x96" },
14875   { 0x97, "unknown-0x97" },
14876   { 0x98, "unknown-0x98" },
14877   { 0x99, "unknown-0x99" },
14878   { 0x9A, "unknown-0x9A" },
14879   { 0x9B, "unknown-0x9B" },
14880   { 0x9C, "unknown-0x9C" },
14881   { 0x9D, "unknown-0x9D" },
14882   { 0x9E, "unknown-0x9E" },
14883   { 0x9F, "unknown-0x9F" },
14884   { 0xA0, "NT Trans" },
14885   { 0xA1, "NT Trans Secondary" },
14886   { 0xA2, "NT Create AndX" },
14887   { 0xA3, "unknown-0xA3" },
14888   { 0xA4, "NT Cancel" },
14889   { 0xA5, "NT Rename" },
14890   { 0xA6, "unknown-0xA6" },
14891   { 0xA7, "unknown-0xA7" },
14892   { 0xA8, "unknown-0xA8" },
14893   { 0xA9, "unknown-0xA9" },
14894   { 0xAA, "unknown-0xAA" },
14895   { 0xAB, "unknown-0xAB" },
14896   { 0xAC, "unknown-0xAC" },
14897   { 0xAD, "unknown-0xAD" },
14898   { 0xAE, "unknown-0xAE" },
14899   { 0xAF, "unknown-0xAF" },
14900   { 0xB0, "unknown-0xB0" },
14901   { 0xB1, "unknown-0xB1" },
14902   { 0xB2, "unknown-0xB2" },
14903   { 0xB3, "unknown-0xB3" },
14904   { 0xB4, "unknown-0xB4" },
14905   { 0xB5, "unknown-0xB5" },
14906   { 0xB6, "unknown-0xB6" },
14907   { 0xB7, "unknown-0xB7" },
14908   { 0xB8, "unknown-0xB8" },
14909   { 0xB9, "unknown-0xB9" },
14910   { 0xBA, "unknown-0xBA" },
14911   { 0xBB, "unknown-0xBB" },
14912   { 0xBC, "unknown-0xBC" },
14913   { 0xBD, "unknown-0xBD" },
14914   { 0xBE, "unknown-0xBE" },
14915   { 0xBF, "unknown-0xBF" },
14916   { 0xC0, "Open Print File" },
14917   { 0xC1, "Write Print File" },
14918   { 0xC2, "Close Print File" },
14919   { 0xC3, "Get Print Queue" },
14920   { 0xC4, "unknown-0xC4" },
14921   { 0xC5, "unknown-0xC5" },
14922   { 0xC6, "unknown-0xC6" },
14923   { 0xC7, "unknown-0xC7" },
14924   { 0xC8, "unknown-0xC8" },
14925   { 0xC9, "unknown-0xC9" },
14926   { 0xCA, "unknown-0xCA" },
14927   { 0xCB, "unknown-0xCB" },
14928   { 0xCC, "unknown-0xCC" },
14929   { 0xCD, "unknown-0xCD" },
14930   { 0xCE, "unknown-0xCE" },
14931   { 0xCF, "unknown-0xCF" },
14932   { 0xD0, "Send Single Block Message" },
14933   { 0xD1, "Send Broadcast Message" },
14934   { 0xD2, "Forward User Name" },
14935   { 0xD3, "Cancel Forward" },
14936   { 0xD4, "Get Machine Name" },
14937   { 0xD5, "Send Start of Multi-block Message" },
14938   { 0xD6, "Send End of Multi-block Message" },
14939   { 0xD7, "Send Text of Multi-block Message" },
14940   { 0xD8, "SMBreadbulk" },
14941   { 0xD9, "SMBwritebulk" },
14942   { 0xDA, "SMBwritebulkdata" },
14943   { 0xDB, "unknown-0xDB" },
14944   { 0xDC, "unknown-0xDC" },
14945   { 0xDD, "unknown-0xDD" },
14946   { 0xDE, "unknown-0xDE" },
14947   { 0xDF, "unknown-0xDF" },
14948   { 0xE0, "unknown-0xE0" },
14949   { 0xE1, "unknown-0xE1" },
14950   { 0xE2, "unknown-0xE2" },
14951   { 0xE3, "unknown-0xE3" },
14952   { 0xE4, "unknown-0xE4" },
14953   { 0xE5, "unknown-0xE5" },
14954   { 0xE6, "unknown-0xE6" },
14955   { 0xE7, "unknown-0xE7" },
14956   { 0xE8, "unknown-0xE8" },
14957   { 0xE9, "unknown-0xE9" },
14958   { 0xEA, "unknown-0xEA" },
14959   { 0xEB, "unknown-0xEB" },
14960   { 0xEC, "unknown-0xEC" },
14961   { 0xED, "unknown-0xED" },
14962   { 0xEE, "unknown-0xEE" },
14963   { 0xEF, "unknown-0xEF" },
14964   { 0xF0, "unknown-0xF0" },
14965   { 0xF1, "unknown-0xF1" },
14966   { 0xF2, "unknown-0xF2" },
14967   { 0xF3, "unknown-0xF3" },
14968   { 0xF4, "unknown-0xF4" },
14969   { 0xF5, "unknown-0xF5" },
14970   { 0xF6, "unknown-0xF6" },
14971   { 0xF7, "unknown-0xF7" },
14972   { 0xF8, "unknown-0xF8" },
14973   { 0xF9, "unknown-0xF9" },
14974   { 0xFA, "unknown-0xFA" },
14975   { 0xFB, "unknown-0xFB" },
14976   { 0xFC, "unknown-0xFC" },
14977   { 0xFD, "unknown-0xFD" },
14978   { 0xFE, "SMBinvalid" },
14979   { 0xFF, "unknown-0xFF" },
14980   { 0x00, NULL },
14981 };
14982
14983 static char *decode_smb_name(guint8 cmd)
14984 {
14985   return(smb_cmd_vals[cmd].strptr);
14986 }
14987
14988
14989
14990 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14991  * Everything TVBUFFIFIED above this line
14992  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
14993
14994
14995 static void
14996 free_hash_tables(gpointer ctarg, gpointer user_data _U_)
14997 {
14998         conv_tables_t *ct = ctarg;
14999
15000         if (ct->unmatched)
15001                 g_hash_table_destroy(ct->unmatched);
15002         if (ct->matched)
15003                 g_hash_table_destroy(ct->matched);
15004         if (ct->tid_service)
15005                 g_hash_table_destroy(ct->tid_service);
15006 }
15007
15008 static void
15009 smb_init_protocol(void)
15010 {
15011         if (smb_saved_info_key_chunk)
15012                 g_mem_chunk_destroy(smb_saved_info_key_chunk);
15013         if (smb_saved_info_chunk)
15014                 g_mem_chunk_destroy(smb_saved_info_chunk);
15015         if (smb_nt_transact_info_chunk)
15016                 g_mem_chunk_destroy(smb_nt_transact_info_chunk);
15017         if (smb_transact2_info_chunk)
15018                 g_mem_chunk_destroy(smb_transact2_info_chunk);
15019         if (smb_transact_info_chunk)
15020                 g_mem_chunk_destroy(smb_transact_info_chunk);
15021
15022         /*
15023          * Free the hash tables attached to the conversation table
15024          * structures, and then free the list of conversation table
15025          * data structures (which doesn't free the data structures
15026          * themselves; that's done by destroying the chunk from
15027          * which they were allocated).
15028          */
15029         if (conv_tables) {
15030                 g_slist_foreach(conv_tables, free_hash_tables, NULL);
15031                 g_slist_free(conv_tables);
15032                 conv_tables = NULL;
15033         }
15034
15035         /*
15036          * Now destroy the chunk from which the conversation table
15037          * structures were allocated.
15038          */
15039         if (conv_tables_chunk)
15040                 g_mem_chunk_destroy(conv_tables_chunk);
15041
15042         smb_saved_info_chunk = g_mem_chunk_new("smb_saved_info_chunk",
15043             sizeof(smb_saved_info_t),
15044             smb_saved_info_init_count * sizeof(smb_saved_info_t),
15045             G_ALLOC_ONLY);
15046         smb_saved_info_key_chunk = g_mem_chunk_new("smb_saved_info_key_chunk",
15047             sizeof(smb_saved_info_key_t),
15048             smb_saved_info_init_count * sizeof(smb_saved_info_key_t),
15049             G_ALLOC_ONLY);
15050         smb_nt_transact_info_chunk = g_mem_chunk_new("smb_nt_transact_info_chunk",
15051             sizeof(smb_nt_transact_info_t),
15052             smb_nt_transact_info_init_count * sizeof(smb_nt_transact_info_t),
15053             G_ALLOC_ONLY);
15054         smb_transact2_info_chunk = g_mem_chunk_new("smb_transact2_info_chunk",
15055             sizeof(smb_transact2_info_t),
15056             smb_transact2_info_init_count * sizeof(smb_transact2_info_t),
15057             G_ALLOC_ONLY);
15058         smb_transact_info_chunk = g_mem_chunk_new("smb_transact_info_chunk",
15059             sizeof(smb_transact_info_t),
15060             smb_transact_info_init_count * sizeof(smb_transact_info_t),
15061             G_ALLOC_ONLY);
15062         conv_tables_chunk = g_mem_chunk_new("conv_tables_chunk",
15063             sizeof(conv_tables_t),
15064             conv_tables_count * sizeof(conv_tables_t),
15065             G_ALLOC_ONLY);
15066 }
15067
15068 static const value_string errcls_types[] = {
15069   { SMB_SUCCESS, "Success"},
15070   { SMB_ERRDOS, "DOS Error"},
15071   { SMB_ERRSRV, "Server Error"},
15072   { SMB_ERRHRD, "Hardware Error"},
15073   { SMB_ERRCMD, "Command Error - Not an SMB format command"},
15074   { 0, NULL }
15075 };
15076
15077 const value_string DOS_errors[] = {
15078   {0, "Success"},
15079   {SMBE_insufficientbuffer, "Insufficient buffer"},
15080   {SMBE_badfunc, "Invalid function (or system call)"},
15081   {SMBE_badfile, "File not found (pathname error)"},
15082   {SMBE_badpath, "Directory not found"},
15083   {SMBE_nofids, "Too many open files"},
15084   {SMBE_noaccess, "Access denied"},
15085   {SMBE_badfid, "Invalid fid"},
15086   {SMBE_nomem,  "Out of memory"},
15087   {SMBE_badmem, "Invalid memory block address"},
15088   {SMBE_badenv, "Invalid environment"},
15089   {SMBE_badaccess, "Invalid open mode"},
15090   {SMBE_baddata, "Invalid data (only from ioctl call)"},
15091   {SMBE_res, "Reserved error code?"},
15092   {SMBE_baddrive, "Invalid drive"},
15093   {SMBE_remcd, "Attempt to delete current directory"},
15094   {SMBE_diffdevice, "Rename/move across different filesystems"},
15095   {SMBE_nofiles, "No more files found in file search"},
15096   {SMBE_badshare, "Share mode on file conflict with open mode"},
15097   {SMBE_lock, "Lock request conflicts with existing lock"},
15098   {SMBE_unsup, "Request unsupported, returned by Win 95"},
15099   {SMBE_nosuchshare, "Requested share does not exist"},
15100   {SMBE_filexists, "File in operation already exists"},
15101   {SMBE_cannotopen, "Cannot open the file specified"},
15102   {SMBE_unknownlevel, "Unknown info level"},
15103   {SMBE_invalidname, "Invalid name"},
15104   {SMBE_badpipe, "Named pipe invalid"},
15105   {SMBE_pipebusy, "All instances of pipe are busy"},
15106   {SMBE_pipeclosing, "Named pipe close in progress"},
15107   {SMBE_notconnected, "No process on other end of named pipe"},
15108   {SMBE_moredata, "More data to be returned"},
15109   {SMBE_baddirectory,  "Invalid directory name in a path."},
15110   {SMBE_eas_didnt_fit, "Extended attributes didn't fit"},
15111   {SMBE_eas_nsup, "Extended attributes not supported"},
15112   {SMBE_notify_buf_small, "Buffer too small to return change notify."},
15113   {SMBE_unknownipc, "Unknown IPC Operation"},
15114   {SMBE_noipc, "Don't support ipc"},
15115   {SMBE_alreadyexists, "File already exists"},
15116   {SMBE_unknownprinterdriver, "Unknown printer driver"},
15117   {SMBE_invalidprintername, "Invalid printer name"},
15118   {SMBE_printeralreadyexists, "Printer already exists"},
15119   {SMBE_invaliddatatype, "Invalid data type"},
15120   {SMBE_invalidenvironment, "Invalid environment"},
15121   {SMBE_printerdriverinuse, "Printer driver in use"},
15122   {SMBE_invalidparam, "Invalid parameter"},
15123   {SMBE_invalidformsize, "Invalid form size"},
15124   {SMBE_invalidsecuritydescriptor, "Invalid security descriptor"},
15125   {SMBE_invalidowner, "Invalid owner"},
15126   {SMBE_nomoreitems, "No more items"},
15127   {SMBE_serverunavailable, "Server unavailable"},
15128   {0, NULL}
15129   };
15130
15131 /* Error codes for the ERRSRV class */
15132
15133 static const value_string SRV_errors[] = {
15134   {SMBE_error, "Non specific error code"},
15135   {SMBE_badpw, "Bad password"},
15136   {SMBE_badtype, "Reserved"},
15137   {SMBE_access, "No permissions to perform the requested operation"},
15138   {SMBE_invnid, "TID invalid"},
15139   {SMBE_invnetname, "Invalid network name. Service not found"},
15140   {SMBE_invdevice, "Invalid device"},
15141   {SMBE_unknownsmb, "Unknown SMB, from NT 3.5 response"},
15142   {SMBE_qfull, "Print queue full"},
15143   {SMBE_qtoobig, "Queued item too big"},
15144   {SMBE_qeof, "EOF on print queue dump"},
15145   {SMBE_invpfid, "Invalid print file in smb_fid"},
15146   {SMBE_smbcmd, "Unrecognised command"},
15147   {SMBE_srverror, "SMB server internal error"},
15148   {SMBE_filespecs, "Fid and pathname invalid combination"},
15149   {SMBE_badlink, "Bad link in request ???"},
15150   {SMBE_badpermits, "Access specified for a file is not valid"},
15151   {SMBE_badpid, "Bad process id in request"},
15152   {SMBE_setattrmode, "Attribute mode invalid"},
15153   {SMBE_paused, "Message server paused"},
15154   {SMBE_msgoff, "Not receiving messages"},
15155   {SMBE_noroom, "No room for message"},
15156   {SMBE_rmuns, "Too many remote usernames"},
15157   {SMBE_timeout, "Operation timed out"},
15158   {SMBE_noresource, "No resources currently available for request."},
15159   {SMBE_toomanyuids, "Too many userids"},
15160   {SMBE_baduid, "Bad userid"},
15161   {SMBE_useMPX, "Temporarily unable to use raw mode, use MPX mode"},
15162   {SMBE_useSTD, "Temporarily unable to use raw mode, use standard mode"},
15163   {SMBE_contMPX, "Resume MPX mode"},
15164   {SMBE_badPW, "Bad Password???"},
15165   {SMBE_nosupport, "Operation not supported"},
15166   { 0, NULL}
15167 };
15168
15169 /* Error codes for the ERRHRD class */
15170
15171 static const value_string HRD_errors[] = {
15172   {SMBE_nowrite, "Read only media"},
15173   {SMBE_badunit, "Unknown device"},
15174   {SMBE_notready, "Drive not ready"},
15175   {SMBE_badcmd, "Unknown command"},
15176   {SMBE_data, "Data (CRC) error"},
15177   {SMBE_badreq, "Bad request structure length"},
15178   {SMBE_seek, "Seek error"},
15179   {SMBE_badmedia, "Unknown media type"},
15180   {SMBE_badsector, "Sector not found"},
15181   {SMBE_nopaper, "Printer out of paper"},
15182   {SMBE_write, "Write fault"},
15183   {SMBE_read, "Read fault"},
15184   {SMBE_general, "General failure"},
15185   {SMBE_badshare, "A open conflicts with an existing open"},
15186   {SMBE_lock, "Lock conflict/invalid mode, or unlock of another process's lock"},
15187   {SMBE_wrongdisk,  "The wrong disk was found in a drive"},
15188   {SMBE_FCBunavail, "No FCBs are available to process request"},
15189   {SMBE_sharebufexc, "A sharing buffer has been exceeded"},
15190   {SMBE_diskfull, "Disk full???"},
15191   {0, NULL}
15192 };
15193
15194 static char *decode_smb_error(guint8 errcls, guint16 errcode)
15195 {
15196
15197   switch (errcls) {
15198
15199   case SMB_SUCCESS:
15200
15201     return("No Error");   /* No error ??? */
15202     break;
15203
15204   case SMB_ERRDOS:
15205
15206     return(val_to_str(errcode, DOS_errors, "Unknown DOS error (%x)"));
15207     break;
15208
15209   case SMB_ERRSRV:
15210
15211     return(val_to_str(errcode, SRV_errors, "Unknown SRV error (%x)"));
15212     break;
15213
15214   case SMB_ERRHRD:
15215
15216     return(val_to_str(errcode, HRD_errors, "Unknown HRD error (%x)"));
15217     break;
15218
15219   default:
15220
15221     return("Unknown error class!");
15222
15223   }
15224
15225 }
15226
15227
15228 /* These are the MS country codes from
15229
15230         http://www.unicode.org/unicode/onlinedat/countries.html
15231
15232    For countries that share the same number, I choose to use only the
15233    name of the largest country. Apologies for this. If this offends you,
15234    here is the table to change that.
15235
15236    This also includes the code of 0 for "Default", which isn't in
15237    that list, but is in Microsoft's SDKs and the Cygnus "winnls.h"
15238    header file.  Presumably it means "don't override the setting
15239    on the user's machine".
15240
15241    Future versions of Microsoft's "winnls.h" header file might include
15242    additional codes; the current version matches the Unicode Consortium's
15243    table.
15244 */
15245 const value_string ms_country_codes[] = {
15246         {  0,   "Default"},
15247         {  1,   "USA"},
15248         {  2,   "Canada"},
15249         {  7,   "Russia"},
15250         { 20,   "Egypt"},
15251         { 27,   "South Africa"},
15252         { 30,   "Greece"},
15253         { 31,   "Netherlands"},
15254         { 32,   "Belgium"},
15255         { 33,   "France"},
15256         { 34,   "Spain"},
15257         { 36,   "Hungary"},
15258         { 39,   "Italy"},
15259         { 40,   "Romania"},
15260         { 41,   "Switzerland"},
15261         { 43,   "Austria"},
15262         { 44,   "United Kingdom"},
15263         { 45,   "Denmark"},
15264         { 46,   "Sweden"},
15265         { 47,   "Norway"},
15266         { 48,   "Poland"},
15267         { 49,   "Germany"},
15268         { 51,   "Peru"},
15269         { 52,   "Mexico"},
15270         { 54,   "Argentina"},
15271         { 55,   "Brazil"},
15272         { 56,   "Chile"},
15273         { 57,   "Colombia"},
15274         { 58,   "Venezuela"},
15275         { 60,   "Malaysia"},
15276         { 61,   "Australia"},
15277         { 62,   "Indonesia"},
15278         { 63,   "Philippines"},
15279         { 64,   "New Zealand"},
15280         { 65,   "Singapore"},
15281         { 66,   "Thailand"},
15282         { 81,   "Japan"},
15283         { 82,   "South Korea"},
15284         { 84,   "Viet Nam"},
15285         { 86,   "China"},
15286         { 90,   "Turkey"},
15287         { 91,   "India"},
15288         { 92,   "Pakistan"},
15289         {212,   "Morocco"},
15290         {213,   "Algeria"},
15291         {216,   "Tunisia"},
15292         {218,   "Libya"},
15293         {254,   "Kenya"},
15294         {263,   "Zimbabwe"},
15295         {298,   "Faroe Islands"},
15296         {351,   "Portugal"},
15297         {352,   "Luxembourg"},
15298         {353,   "Ireland"},
15299         {354,   "Iceland"},
15300         {355,   "Albania"},
15301         {358,   "Finland"},
15302         {359,   "Bulgaria"},
15303         {370,   "Lithuania"},
15304         {371,   "Latvia"},
15305         {372,   "Estonia"},
15306         {374,   "Armenia"},
15307         {375,   "Belarus"},
15308         {380,   "Ukraine"},
15309         {381,   "Serbia"},
15310         {385,   "Croatia"},
15311         {386,   "Slovenia"},
15312         {389,   "Macedonia"},
15313         {420,   "Czech Republic"},
15314         {421,   "Slovak Republic"},
15315         {501,   "Belize"},
15316         {502,   "Guatemala"},
15317         {503,   "El Salvador"},
15318         {504,   "Honduras"},
15319         {505,   "Nicaragua"},
15320         {506,   "Costa Rica"},
15321         {507,   "Panama"},
15322         {591,   "Bolivia"},
15323         {593,   "Ecuador"},
15324         {595,   "Paraguay"},
15325         {598,   "Uruguay"},
15326         {673,   "Brunei Darussalam"},
15327         {852,   "Hong Kong"},
15328         {853,   "Macau"},
15329         {886,   "Taiwan"},
15330         {960,   "Maldives"},
15331         {961,   "Lebanon"},
15332         {962,   "Jordan"},
15333         {963,   "Syria"},
15334         {964,   "Iraq"},
15335         {965,   "Kuwait"},
15336         {966,   "Saudi Arabia"},
15337         {967,   "Yemen"},
15338         {968,   "Oman"},
15339         {971,   "United Arab Emirates"},
15340         {972,   "Israel"},
15341         {973,   "Bahrain"},
15342         {974,   "Qatar"},
15343         {976,   "Mongolia"},
15344         {981,   "Iran"},
15345         {994,   "Azerbaijan"},
15346         {995,   "Georgia"},
15347         {996,   "Kyrgyzstan"},
15348
15349         {0,     NULL}
15350 };
15351
15352 /*
15353  * NT error codes.
15354  *
15355  * From
15356  *
15357  *      http://www.wildpackets.com/elements/SMB_NT_Status_Codes.txt
15358  */
15359 const value_string NT_errors[] = {
15360   { 0x00000000, "STATUS_SUCCESS" },
15361   { 0x00000000, "STATUS_WAIT_0" },
15362   { 0x00000001, "STATUS_WAIT_1" },
15363   { 0x00000002, "STATUS_WAIT_2" },
15364   { 0x00000003, "STATUS_WAIT_3" },
15365   { 0x0000003F, "STATUS_WAIT_63" },
15366   { 0x00000080, "STATUS_ABANDONED" },
15367   { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
15368   { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
15369   { 0x000000C0, "STATUS_USER_APC" },
15370   { 0x00000100, "STATUS_KERNEL_APC" },
15371   { 0x00000101, "STATUS_ALERTED" },
15372   { 0x00000102, "STATUS_TIMEOUT" },
15373   { 0x00000103, "STATUS_PENDING" },
15374   { 0x00000104, "STATUS_REPARSE" },
15375   { 0x00000105, "STATUS_MORE_ENTRIES" },
15376   { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
15377   { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
15378   { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
15379   { 0x00000109, "STATUS_VOLUME_MOUNTED" },
15380   { 0x0000010A, "STATUS_RXACT_COMMITTED" },
15381   { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
15382   { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
15383   { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
15384   { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
15385   { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
15386   { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
15387   { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
15388   { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
15389   { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
15390   { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
15391   { 0x00000116, "STATUS_CRASH_DUMP" },
15392   { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
15393   { 0x00000118, "STATUS_REPARSE_OBJECT" },
15394   { 0x0000045C, "STATUS_NO_SHUTDOWN_IN_PROGRESS" },
15395   { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
15396   { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
15397   { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
15398   { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
15399   { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
15400   { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
15401   { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
15402   { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
15403   { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
15404   { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
15405   { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
15406   { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
15407   { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
15408   { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
15409   { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
15410   { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
15411   { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
15412   { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
15413   { 0x40000012, "STATUS_EVENT_DONE" },
15414   { 0x40000013, "STATUS_EVENT_PENDING" },
15415   { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
15416   { 0x40000015, "STATUS_FATAL_APP_EXIT" },
15417   { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
15418   { 0x40000017, "STATUS_WAS_UNLOCKED" },
15419   { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
15420   { 0x40000019, "STATUS_WAS_LOCKED" },
15421   { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
15422   { 0x4000001B, "STATUS_ALREADY_WIN32" },
15423   { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
15424   { 0x4000001D, "STATUS_WX86_CONTINUE" },
15425   { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
15426   { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
15427   { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
15428   { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
15429   { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
15430   { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
15431   { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
15432   { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
15433   { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
15434   { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
15435   { 0x80000003, "STATUS_BREAKPOINT" },
15436   { 0x80000004, "STATUS_SINGLE_STEP" },
15437   { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
15438   { 0x80000006, "STATUS_NO_MORE_FILES" },
15439   { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
15440   { 0x8000000A, "STATUS_HANDLES_CLOSED" },
15441   { 0x8000000B, "STATUS_NO_INHERITANCE" },
15442   { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
15443   { 0x8000000D, "STATUS_PARTIAL_COPY" },
15444   { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
15445   { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
15446   { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
15447   { 0x80000011, "STATUS_DEVICE_BUSY" },
15448   { 0x80000012, "STATUS_NO_MORE_EAS" },
15449   { 0x80000013, "STATUS_INVALID_EA_NAME" },
15450   { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
15451   { 0x80000015, "STATUS_INVALID_EA_FLAG" },
15452   { 0x80000016, "STATUS_VERIFY_REQUIRED" },
15453   { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
15454   { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
15455   { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
15456   { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
15457   { 0x8000001C, "STATUS_MEDIA_CHANGED" },
15458   { 0x8000001D, "STATUS_BUS_RESET" },
15459   { 0x8000001E, "STATUS_END_OF_MEDIA" },
15460   { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
15461   { 0x80000020, "STATUS_MEDIA_CHECK" },
15462   { 0x80000021, "STATUS_SETMARK_DETECTED" },
15463   { 0x80000022, "STATUS_NO_DATA_DETECTED" },
15464   { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
15465   { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
15466   { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
15467   { 0x80000026, "STATUS_LONGJUMP" },
15468   { 0x80040111, "MAPI_E_LOGON_FAILED" },
15469   { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
15470   { 0x80090301, "SEC_E_INVALID_HANDLE" },
15471   { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
15472   { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
15473   { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
15474   { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
15475   { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
15476   { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
15477   { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
15478   { 0xC0000001, "STATUS_UNSUCCESSFUL" },
15479   { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
15480   { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
15481   { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
15482   { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
15483   { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
15484   { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
15485   { 0xC0000008, "STATUS_INVALID_HANDLE" },
15486   { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
15487   { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
15488   { 0xC000000B, "STATUS_INVALID_CID" },
15489   { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
15490   { 0xC000000D, "STATUS_INVALID_PARAMETER" },
15491   { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
15492   { 0xC000000F, "STATUS_NO_SUCH_FILE" },
15493   { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
15494   { 0xC0000011, "STATUS_END_OF_FILE" },
15495   { 0xC0000012, "STATUS_WRONG_VOLUME" },
15496   { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
15497   { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
15498   { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
15499   { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
15500   { 0xC0000017, "STATUS_NO_MEMORY" },
15501   { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
15502   { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
15503   { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
15504   { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
15505   { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
15506   { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
15507   { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
15508   { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
15509   { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
15510   { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
15511   { 0xC0000022, "STATUS_ACCESS_DENIED" },
15512   { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
15513   { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
15514   { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
15515   { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
15516   { 0xC0000027, "STATUS_UNWIND" },
15517   { 0xC0000028, "STATUS_BAD_STACK" },
15518   { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
15519   { 0xC000002A, "STATUS_NOT_LOCKED" },
15520   { 0xC000002B, "STATUS_PARITY_ERROR" },
15521   { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
15522   { 0xC000002D, "STATUS_NOT_COMMITTED" },
15523   { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
15524   { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
15525   { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
15526   { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
15527   { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
15528   { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
15529   { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
15530   { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
15531   { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
15532   { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
15533   { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
15534   { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
15535   { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
15536   { 0xC000003C, "STATUS_DATA_OVERRUN" },
15537   { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
15538   { 0xC000003E, "STATUS_DATA_ERROR" },
15539   { 0xC000003F, "STATUS_CRC_ERROR" },
15540   { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
15541   { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
15542   { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
15543   { 0xC0000043, "STATUS_SHARING_VIOLATION" },
15544   { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
15545   { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
15546   { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
15547   { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
15548   { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
15549   { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
15550   { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
15551   { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
15552   { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
15553   { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
15554   { 0xC000004E, "STATUS_SECTION_PROTECTION" },
15555   { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
15556   { 0xC0000050, "STATUS_EA_TOO_LARGE" },
15557   { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
15558   { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
15559   { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
15560   { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
15561   { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
15562   { 0xC0000056, "STATUS_DELETE_PENDING" },
15563   { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
15564   { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
15565   { 0xC0000059, "STATUS_REVISION_MISMATCH" },
15566   { 0xC000005A, "STATUS_INVALID_OWNER" },
15567   { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
15568   { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
15569   { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
15570   { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
15571   { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
15572   { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
15573   { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
15574   { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
15575   { 0xC0000063, "STATUS_USER_EXISTS" },
15576   { 0xC0000064, "STATUS_NO_SUCH_USER" },
15577   { 0xC0000065, "STATUS_GROUP_EXISTS" },
15578   { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
15579   { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
15580   { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
15581   { 0xC0000069, "STATUS_LAST_ADMIN" },
15582   { 0xC000006A, "STATUS_WRONG_PASSWORD" },
15583   { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
15584   { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
15585   { 0xC000006D, "STATUS_LOGON_FAILURE" },
15586   { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
15587   { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
15588   { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
15589   { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
15590   { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
15591   { 0xC0000073, "STATUS_NONE_MAPPED" },
15592   { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
15593   { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
15594   { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
15595   { 0xC0000077, "STATUS_INVALID_ACL" },
15596   { 0xC0000078, "STATUS_INVALID_SID" },
15597   { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
15598   { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
15599   { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
15600   { 0xC000007C, "STATUS_NO_TOKEN" },
15601   { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
15602   { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
15603   { 0xC000007F, "STATUS_DISK_FULL" },
15604   { 0xC0000080, "STATUS_SERVER_DISABLED" },
15605   { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
15606   { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
15607   { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
15608   { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
15609   { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
15610   { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
15611   { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
15612   { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
15613   { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
15614   { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
15615   { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
15616   { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
15617   { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
15618   { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
15619   { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
15620   { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
15621   { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
15622   { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
15623   { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
15624   { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
15625   { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
15626   { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
15627   { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
15628   { 0xC0000098, "STATUS_FILE_INVALID" },
15629   { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
15630   { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
15631   { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
15632   { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
15633   { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
15634   { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
15635   { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
15636   { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
15637   { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
15638   { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
15639   { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
15640   { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
15641   { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
15642   { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
15643   { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
15644   { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
15645   { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
15646   { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
15647   { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
15648   { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
15649   { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
15650   { 0xC00000AE, "STATUS_PIPE_BUSY" },
15651   { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
15652   { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
15653   { 0xC00000B1, "STATUS_PIPE_CLOSING" },
15654   { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
15655   { 0xC00000B3, "STATUS_PIPE_LISTENING" },
15656   { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
15657   { 0xC00000B5, "STATUS_IO_TIMEOUT" },
15658   { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
15659   { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
15660   { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
15661   { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
15662   { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
15663   { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
15664   { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
15665   { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
15666   { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
15667   { 0xC00000BF, "STATUS_NETWORK_BUSY" },
15668   { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
15669   { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
15670   { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
15671   { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
15672   { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
15673   { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
15674   { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
15675   { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
15676   { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
15677   { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
15678   { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
15679   { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
15680   { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
15681   { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
15682   { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
15683   { 0xC00000CF, "STATUS_SHARING_PAUSED" },
15684   { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
15685   { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
15686   { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
15687   { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
15688   { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
15689   { 0xC00000D5, "STATUS_FILE_RENAMED" },
15690   { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
15691   { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
15692   { 0xC00000D8, "STATUS_CANT_WAIT" },
15693   { 0xC00000D9, "STATUS_PIPE_EMPTY" },
15694   { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
15695   { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
15696   { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
15697   { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
15698   { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
15699   { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
15700   { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
15701   { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
15702   { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
15703   { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
15704   { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
15705   { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
15706   { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
15707   { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
15708   { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
15709   { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
15710   { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
15711   { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
15712   { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
15713   { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
15714   { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
15715   { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
15716   { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
15717   { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
15718   { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
15719   { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
15720   { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
15721   { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
15722   { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
15723   { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
15724   { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
15725   { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
15726   { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
15727   { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
15728   { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
15729   { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
15730   { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
15731   { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
15732   { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
15733   { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
15734   { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
15735   { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
15736   { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
15737   { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
15738   { 0xC0000106, "STATUS_NAME_TOO_LONG" },
15739   { 0xC0000107, "STATUS_FILES_OPEN" },
15740   { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
15741   { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
15742   { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
15743   { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
15744   { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
15745   { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
15746   { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
15747   { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
15748   { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
15749   { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
15750   { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
15751   { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
15752   { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
15753   { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
15754   { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
15755   { 0xC0000117, "STATUS_NO_LDT" },
15756   { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
15757   { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
15758   { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
15759   { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
15760   { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
15761   { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
15762   { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
15763   { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
15764   { 0xC0000120, "STATUS_CANCELLED" },
15765   { 0xC0000121, "STATUS_CANNOT_DELETE" },
15766   { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
15767   { 0xC0000123, "STATUS_FILE_DELETED" },
15768   { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
15769   { 0xC0000125, "STATUS_SPECIAL_GROUP" },
15770   { 0xC0000126, "STATUS_SPECIAL_USER" },
15771   { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
15772   { 0xC0000128, "STATUS_FILE_CLOSED" },
15773   { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
15774   { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
15775   { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
15776   { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
15777   { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
15778   { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
15779   { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
15780   { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
15781   { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
15782   { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
15783   { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
15784   { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
15785   { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
15786   { 0xC0000136, "STATUS_OPEN_FAILED" },
15787   { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
15788   { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
15789   { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
15790   { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
15791   { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
15792   { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
15793   { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
15794   { 0xC000013E, "STATUS_LINK_FAILED" },
15795   { 0xC000013F, "STATUS_LINK_TIMEOUT" },
15796   { 0xC0000140, "STATUS_INVALID_CONNECTION" },
15797   { 0xC0000141, "STATUS_INVALID_ADDRESS" },
15798   { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
15799   { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
15800   { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
15801   { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
15802   { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
15803   { 0xC0000147, "STATUS_NO_PAGEFILE" },
15804   { 0xC0000148, "STATUS_INVALID_LEVEL" },
15805   { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
15806   { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
15807   { 0xC000014B, "STATUS_PIPE_BROKEN" },
15808   { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
15809   { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
15810   { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
15811   { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
15812   { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
15813   { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
15814   { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
15815   { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
15816   { 0xC0000154, "STATUS_ALIAS_EXISTS" },
15817   { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
15818   { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
15819   { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
15820   { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
15821   { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
15822   { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
15823   { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
15824   { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
15825   { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
15826   { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
15827   { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
15828   { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
15829   { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
15830   { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
15831   { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
15832   { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
15833   { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
15834   { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
15835   { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
15836   { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
15837   { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
15838   { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
15839   { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
15840   { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
15841   { 0xC000016D, "STATUS_FT_ORPHANING" },
15842   { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
15843   { 0xC0000172, "STATUS_PARTITION_FAILURE" },
15844   { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
15845   { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
15846   { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
15847   { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
15848   { 0xC0000177, "STATUS_EOM_OVERFLOW" },
15849   { 0xC0000178, "STATUS_NO_MEDIA" },
15850   { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
15851   { 0xC000017B, "STATUS_INVALID_MEMBER" },
15852   { 0xC000017C, "STATUS_KEY_DELETED" },
15853   { 0xC000017D, "STATUS_NO_LOG_SPACE" },
15854   { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
15855   { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
15856   { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
15857   { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
15858   { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
15859   { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
15860   { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
15861   { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
15862   { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
15863   { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
15864   { 0xC0000188, "STATUS_LOG_FILE_FULL" },
15865   { 0xC0000189, "STATUS_TOO_LATE" },
15866   { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
15867   { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
15868   { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
15869   { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
15870   { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
15871   { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
15872   { 0xC0000190, "STATUS_TRUST_FAILURE" },
15873   { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
15874   { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
15875   { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
15876   { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
15877   { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
15878   { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
15879   { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
15880   { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
15881   { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
15882   { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
15883   { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
15884   { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
15885   { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
15886   { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
15887   { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
15888   { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
15889   { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
15890   { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
15891   { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
15892   { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
15893   { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
15894   { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
15895   { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
15896   { 0xC000020D, "STATUS_CONNECTION_RESET" },
15897   { 0xC000020E, "STATUS_TOO_MANY_NODES" },
15898   { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
15899   { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
15900   { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
15901   { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
15902   { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
15903   { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
15904   { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
15905   { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
15906   { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
15907   { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
15908   { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
15909   { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
15910   { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
15911   { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
15912   { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
15913   { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
15914   { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
15915   { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
15916   { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
15917   { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
15918   { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
15919   { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
15920   { 0xC0000225, "STATUS_NOT_FOUND" },
15921   { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
15922   { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
15923   { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
15924   { 0xC0000229, "STATUS_FAIL_CHECK" },
15925   { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
15926   { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
15927   { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
15928   { 0xC000022D, "STATUS_RETRY" },
15929   { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
15930   { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
15931   { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
15932   { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
15933   { 0xC0000232, "STATUS_INVALID_VARIANT" },
15934   { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
15935   { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
15936   { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
15937   { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
15938   { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
15939   { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
15940   { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
15941   { 0xC000023A, "STATUS_CONNECTION_INVALID" },
15942   { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
15943   { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
15944   { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
15945   { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
15946   { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
15947   { 0xC0000240, "STATUS_REQUEST_ABORTED" },
15948   { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
15949   { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
15950   { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
15951   { 0xC0000244, "STATUS_AUDIT_FAILED" },
15952   { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
15953   { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
15954   { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
15955   { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
15956   { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
15957   { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
15958   { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
15959   { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
15960   { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
15961   { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
15962   { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
15963   { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
15964   { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
15965   { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
15966   { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
15967   { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
15968   { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
15969   { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
15970   { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
15971   { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
15972   { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
15973   { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
15974   { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
15975   { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
15976   { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
15977   { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
15978   { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
15979   { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
15980   { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
15981   { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
15982   { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
15983   { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
15984   { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
15985   { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
15986   { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
15987   { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
15988   { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
15989   { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
15990   { 0xC0000272, "STATUS_NO_MATCH" },
15991   { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
15992   { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
15993   { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
15994   { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
15995   { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
15996   { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
15997   { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
15998   { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
15999   { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
16000   { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
16001   { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
16002   { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
16003   { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
16004   { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
16005   { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
16006   { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
16007   { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
16008   { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
16009   { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
16010   { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
16011   { 0xC000028E, "STATUS_NO_EFS" },
16012   { 0xC000028F, "STATUS_WRONG_EFS" },
16013   { 0xC0000290, "STATUS_NO_USER_KEYS" },
16014   { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
16015   { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
16016   { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
16017   { 0x40000294, "STATUS_WAKE_SYSTEM" },
16018   { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
16019   { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
16020   { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
16021   { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
16022   { 0xC0000299, "STATUS_SHARED_POLICY" },
16023   { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
16024   { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
16025   { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
16026   { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
16027   { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
16028   { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
16029   { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
16030   { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
16031   { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
16032   { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
16033   { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
16034   { 0xC00002A5, "STATUS_DS_BUSY" },
16035   { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
16036   { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
16037   { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
16038   { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
16039   { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
16040   { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
16041   { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
16042   { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
16043   { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
16044   { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
16045   { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
16046   { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
16047   { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
16048   { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
16049   { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
16050   { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
16051   { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
16052   { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
16053   { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
16054   { 0xC00002B9, "STATUS_NOINTERFACE" },
16055   { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
16056   { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
16057   { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
16058   { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
16059   { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
16060   { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
16061   { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
16062   { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
16063   { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
16064   { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
16065   { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
16066   { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
16067   { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
16068   { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
16069   { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
16070   { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
16071   { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
16072   { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
16073   { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
16074   { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
16075   { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
16076   { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
16077   { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
16078   { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
16079   { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
16080   { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
16081   { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
16082   { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
16083   { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
16084   { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
16085   { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
16086   { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
16087   { 0xC00002E1, "STATUS_DS_CANT_START" },
16088   { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
16089   { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
16090   { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
16091   { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
16092   { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
16093   { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
16094   { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
16095   { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
16096   { 0xC0009898, "STATUS_WOW_ASSERTION" },
16097   { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
16098   { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
16099   { 0xC0020003, "RPC_NT_INVALID_BINDING" },
16100   { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
16101   { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
16102   { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
16103   { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
16104   { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
16105   { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
16106   { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
16107   { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
16108   { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
16109   { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
16110   { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
16111   { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
16112   { 0xC0020010, "RPC_NT_NOT_LISTENING" },
16113   { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
16114   { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
16115   { 0xC0020013, "RPC_NT_NO_BINDINGS" },
16116   { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
16117   { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
16118   { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
16119   { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
16120   { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
16121   { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
16122   { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
16123   { 0xC002001B, "RPC_NT_CALL_FAILED" },
16124   { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
16125   { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
16126   { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
16127   { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
16128   { 0xC0020022, "RPC_NT_INVALID_TAG" },
16129   { 0xC0020023, "RPC_NT_INVALID_BOUND" },
16130   { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
16131   { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
16132   { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
16133   { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
16134   { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
16135   { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
16136   { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
16137   { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
16138   { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
16139   { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
16140   { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
16141   { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
16142   { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
16143   { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
16144   { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
16145   { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
16146   { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
16147   { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
16148   { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
16149   { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
16150   { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
16151   { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
16152   { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
16153   { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
16154   { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
16155   { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
16156   { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
16157   { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
16158   { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
16159   { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
16160   { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
16161   { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
16162   { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
16163   { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
16164   { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
16165   { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
16166   { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
16167   { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
16168   { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
16169   { 0xC002100A, "RPC_P_SEND_FAILED" },
16170   { 0xC002100B, "RPC_P_TIMEOUT" },
16171   { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
16172   { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
16173   { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
16174   { 0xC0021015, "RPC_P_THREAD_LISTENING" },
16175   { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
16176   { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
16177   { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
16178   { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
16179   { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
16180   { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
16181   { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
16182   { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
16183   { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
16184   { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
16185   { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
16186   { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
16187   { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
16188   { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
16189   { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
16190   { 0xC002004C, "EPT_NT_CANT_CREATE" },
16191   { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
16192   { 0xC002004F, "RPC_NT_NO_INTERFACES" },
16193   { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
16194   { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
16195   { 0xC0020052, "RPC_NT_COMM_FAILURE" },
16196   { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
16197   { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
16198   { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
16199   { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
16200   { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
16201   { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
16202   { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
16203   { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
16204   { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
16205   { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
16206   { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
16207   { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
16208   { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
16209   { 0,          NULL }
16210 };
16211
16212
16213
16214 static const true_false_string tfs_smb_flags_lock = {
16215         "Lock&Read, Write&Unlock are supported",
16216         "Lock&Read, Write&Unlock are not supported"
16217 };
16218 static const true_false_string tfs_smb_flags_receive_buffer = {
16219         "Receive buffer has been posted",
16220         "Receive buffer has not been posted"
16221 };
16222 static const true_false_string tfs_smb_flags_caseless = {
16223         "Path names are caseless",
16224         "Path names are case sensitive"
16225 };
16226 static const true_false_string tfs_smb_flags_canon = {
16227         "Pathnames are canonicalized",
16228         "Pathnames are not canonicalized"
16229 };
16230 static const true_false_string tfs_smb_flags_oplock = {
16231         "OpLock requested/granted",
16232         "OpLock not requested/granted"
16233 };
16234 static const true_false_string tfs_smb_flags_notify = {
16235         "Notify client on all modifications",
16236         "Notify client only on open"
16237 };
16238 static const true_false_string tfs_smb_flags_response = {
16239         "Message is a response to the client/redirector",
16240         "Message is a request to the server"
16241 };
16242
16243 static int
16244 dissect_smb_flags(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16245 {
16246         guint8 mask;
16247         proto_item *item = NULL;
16248         proto_tree *tree = NULL;
16249
16250         mask = tvb_get_guint8(tvb, offset);
16251
16252         if(parent_tree){
16253                 item = proto_tree_add_text(parent_tree, tvb, offset, 1,
16254                         "Flags: 0x%02x", mask);
16255                 tree = proto_item_add_subtree(item, ett_smb_flags);
16256         }
16257         proto_tree_add_boolean(tree, hf_smb_flags_response,
16258                 tvb, offset, 1, mask);
16259         proto_tree_add_boolean(tree, hf_smb_flags_notify,
16260                 tvb, offset, 1, mask);
16261         proto_tree_add_boolean(tree, hf_smb_flags_oplock,
16262                 tvb, offset, 1, mask);
16263         proto_tree_add_boolean(tree, hf_smb_flags_canon,
16264                 tvb, offset, 1, mask);
16265         proto_tree_add_boolean(tree, hf_smb_flags_caseless,
16266                 tvb, offset, 1, mask);
16267         proto_tree_add_boolean(tree, hf_smb_flags_receive_buffer,
16268                 tvb, offset, 1, mask);
16269         proto_tree_add_boolean(tree, hf_smb_flags_lock,
16270                 tvb, offset, 1, mask);
16271         offset += 1;
16272         return offset;
16273 }
16274
16275
16276
16277 static const true_false_string tfs_smb_flags2_long_names_allowed = {
16278         "Long file names are allowed in the response",
16279         "Long file names are not allowed in the response"
16280 };
16281 static const true_false_string tfs_smb_flags2_ea = {
16282         "Extended attributes are supported",
16283         "Extended attributes are not supported"
16284 };
16285 static const true_false_string tfs_smb_flags2_sec_sig = {
16286         "Security signatures are supported",
16287         "Security signatures are not supported"
16288 };
16289 static const true_false_string tfs_smb_flags2_long_names_used = {
16290         "Path names in request are long file names",
16291         "Path names in request are not long file names"
16292 };
16293 static const true_false_string tfs_smb_flags2_esn = {
16294         "Extended security negotiation is supported",
16295         "Extended security negotiation is not supported"
16296 };
16297 static const true_false_string tfs_smb_flags2_dfs = {
16298         "Resolve pathnames with Dfs",
16299         "Don't resolve pathnames with Dfs"
16300 };
16301 static const true_false_string tfs_smb_flags2_roe = {
16302         "Permit reads if execute-only",
16303         "Don't permit reads if execute-only"
16304 };
16305 static const true_false_string tfs_smb_flags2_nt_error = {
16306         "Error codes are NT error codes",
16307         "Error codes are DOS error codes"
16308 };
16309 static const true_false_string tfs_smb_flags2_string = {
16310         "Strings are Unicode",
16311         "Strings are ASCII"
16312 };
16313 static int
16314 dissect_smb_flags2(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
16315 {
16316         guint16 mask;
16317         proto_item *item = NULL;
16318         proto_tree *tree = NULL;
16319
16320         mask = tvb_get_letohs(tvb, offset);
16321
16322         if(parent_tree){
16323                 item = proto_tree_add_text(parent_tree, tvb, offset, 2,
16324                         "Flags2: 0x%04x", mask);
16325                 tree = proto_item_add_subtree(item, ett_smb_flags2);
16326         }
16327
16328         proto_tree_add_boolean(tree, hf_smb_flags2_string,
16329                 tvb, offset, 2, mask);
16330         proto_tree_add_boolean(tree, hf_smb_flags2_nt_error,
16331                 tvb, offset, 2, mask);
16332         proto_tree_add_boolean(tree, hf_smb_flags2_roe,
16333                 tvb, offset, 2, mask);
16334         proto_tree_add_boolean(tree, hf_smb_flags2_dfs,
16335                 tvb, offset, 2, mask);
16336         proto_tree_add_boolean(tree, hf_smb_flags2_esn,
16337                 tvb, offset, 2, mask);
16338         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_used,
16339                 tvb, offset, 2, mask);
16340         proto_tree_add_boolean(tree, hf_smb_flags2_sec_sig,
16341                 tvb, offset, 2, mask);
16342         proto_tree_add_boolean(tree, hf_smb_flags2_ea,
16343                 tvb, offset, 2, mask);
16344         proto_tree_add_boolean(tree, hf_smb_flags2_long_names_allowed,
16345                 tvb, offset, 2, mask);
16346
16347         offset += 2;
16348         return offset;
16349 }
16350
16351
16352
16353 #define SMB_FLAGS_DIRN 0x80
16354
16355
16356 static void
16357 dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16358 {
16359         int offset = 0;
16360         proto_item *item = NULL, *hitem = NULL;
16361         proto_tree *tree = NULL, *htree = NULL;
16362         guint8          flags;
16363         guint16         flags2;
16364         static smb_info_t       si_arr[20];
16365         static int si_counter=0;
16366         smb_info_t              *si;
16367         smb_saved_info_t *sip = NULL;
16368         smb_saved_info_key_t key;
16369         smb_saved_info_key_t *new_key;
16370         guint32 nt_status = 0;
16371         guint8 errclass = 0;
16372         guint16 errcode = 0;
16373         guint32 pid_mid;
16374         conversation_t *conversation;
16375         nstime_t ns;
16376
16377         si_counter++;
16378         if(si_counter==20){
16379                 si_counter=0;
16380         }
16381         si=&si_arr[si_counter];
16382
16383         top_tree=parent_tree;
16384
16385         if (check_col(pinfo->cinfo, COL_PROTOCOL)){
16386                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB");
16387         }
16388         if (check_col(pinfo->cinfo, COL_INFO)){
16389                 col_clear(pinfo->cinfo, COL_INFO);
16390         }
16391
16392         /* start off using the local variable, we will allocate a new one if we
16393            need to*/
16394         si->cmd = tvb_get_guint8(tvb, offset+4);
16395         flags = tvb_get_guint8(tvb, offset+9);
16396         /*
16397          * XXX - in some SMB-over-OSI-transport and SMB-over-Vines traffic,
16398          * the direction flag appears never to be set, even for what appear
16399          * to be replies.  Do some SMB servers fail to set that flag,
16400          * under the assumption that the client knows it's a reply because
16401          * it received it?
16402          */
16403         si->request = !(flags&SMB_FLAGS_DIRN);
16404         flags2 = tvb_get_letohs(tvb, offset+10);
16405         if(flags2 & 0x8000){
16406                 si->unicode = TRUE; /* Mark them as Unicode */
16407         } else {
16408                 si->unicode = FALSE;
16409         }
16410         si->tid = tvb_get_letohs(tvb, offset+24);
16411         si->pid = tvb_get_letohs(tvb, offset+26);
16412         si->uid = tvb_get_letohs(tvb, offset+28);
16413         si->mid = tvb_get_letohs(tvb, offset+30);
16414         pid_mid = (si->pid << 16) | si->mid;
16415         si->info_level = -1;
16416         si->info_count = -1;
16417
16418         if (parent_tree) {
16419                 item = proto_tree_add_item(parent_tree, proto_smb, tvb, offset,
16420                         -1, FALSE);
16421                 tree = proto_item_add_subtree(item, ett_smb);
16422
16423                 hitem = proto_tree_add_text(tree, tvb, offset, 32,
16424                         "SMB Header");
16425
16426                 htree = proto_item_add_subtree(hitem, ett_smb_hdr);
16427         }
16428
16429         proto_tree_add_text(htree, tvb, offset, 4, "Server Component: SMB");
16430         offset += 4;  /* Skip the marker */
16431
16432         /* find which conversation we are part of and get the tables for that
16433            conversation*/
16434         conversation = find_conversation(&pinfo->src, &pinfo->dst,
16435                  pinfo->ptype,  pinfo->srcport, pinfo->destport, 0);
16436         if(!conversation){
16437                 /* OK this is a new conversation so lets create it */
16438                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
16439                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
16440         }
16441         /* see if we already have the smb data for this conversation */
16442         si->ct=conversation_get_proto_data(conversation, proto_smb);
16443         if(!si->ct){
16444                 /* No, not yet. create it and attach it to the conversation */
16445                 si->ct = g_mem_chunk_alloc(conv_tables_chunk);
16446                 conv_tables = g_slist_prepend(conv_tables, si->ct);
16447                 si->ct->matched= g_hash_table_new(smb_saved_info_hash_matched,
16448                         smb_saved_info_equal_matched);
16449                 si->ct->unmatched= g_hash_table_new(smb_saved_info_hash_unmatched,
16450                         smb_saved_info_equal_unmatched);
16451                 si->ct->tid_service=g_hash_table_new(
16452                         smb_saved_info_hash_unmatched,
16453                         smb_saved_info_equal_unmatched);
16454                 conversation_add_proto_data(conversation, proto_smb, si->ct);
16455         }
16456
16457         if( (si->request)
16458             &&  (si->mid==0)
16459             &&  (si->uid==0)
16460             &&  (si->pid==0)
16461             &&  (si->tid==0) ){
16462                 /* this is a broadcast SMB packet, there will not be a reply.
16463                    We dont need to do anything
16464                 */
16465                 si->unidir = TRUE;
16466         } else if( (si->cmd==SMB_COM_NT_CANCEL)     /* NT Cancel */
16467                    ||(si->cmd==SMB_COM_TRANSACTION_SECONDARY)   /* Transaction Secondary */
16468                    ||(si->cmd==SMB_COM_TRANSACTION2_SECONDARY)   /* Transaction2 Secondary */
16469                    ||(si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)){ /* NT Transaction Secondary */
16470                 /* Ok, we got a special request type. This request is either
16471                    an NT Cancel or a continuation relative to a real request
16472                    in an earlier packet.  In either case, we don't expect any
16473                    responses to this packet.  For continuations, any later
16474                    responses we see really just belong to the original request.
16475                    Anyway, we want to remember this packet somehow and
16476                    remember which original request it is associated with so
16477                    we can say nice things such as "This is a Cancellation to
16478                    the request in frame x", but we don't want the
16479                    request/response matching to get messed up.
16480
16481                    The only thing we do in this case is trying to find which original
16482                    request we match with and insert an entry for this "special"
16483                    request for later reference. We continue to reference the original
16484                    requests smb_saved_info_t but we dont touch it or change anything
16485                    in it.
16486                 */
16487
16488                 si->unidir = TRUE;  /*we dont expect an answer to this one*/
16489
16490                 if(!pinfo->fd->flags.visited){
16491                         /* try to find which original call we match and if we
16492                            find it add us to the matched table. Dont touch
16493                            anything else since we dont want this one to mess
16494                            up the request/response matching. We still consider
16495                            the initial call the real request and this is only
16496                            some sort of continuation.
16497                         */
16498                         /* we only check the unmatched table and assume that the
16499                            last seen MID matching ours is the right one.
16500                            This can fail but is better than nothing
16501                         */
16502                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16503                         if(sip!=NULL){
16504                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16505                                 new_key->frame = pinfo->fd->num;
16506                                 new_key->pid_mid = pid_mid;
16507                                 g_hash_table_insert(si->ct->matched, new_key,
16508                                     sip);
16509                         }
16510                 } else {
16511                         /* we have seen this packet before; check the
16512                            matching table
16513                         */
16514                         key.frame = pinfo->fd->num;
16515                         key.pid_mid = pid_mid;
16516                         sip=g_hash_table_lookup(si->ct->matched, &key);
16517                         if(sip==NULL){
16518                         /*
16519                           We didn't find it.
16520                           Too bad, unfortunately there is not really much we can
16521                           do now since this means that we never saw the initial
16522                           request.
16523                          */
16524                         }
16525                 }
16526
16527
16528                 if(sip && sip->frame_req){
16529                         switch(si->cmd){
16530                         case SMB_COM_NT_CANCEL:
16531                                 proto_tree_add_uint(htree, hf_smb_cancel_to,
16532                                                     tvb, 0, 0, sip->frame_req);
16533                                 break;
16534                         case SMB_COM_TRANSACTION_SECONDARY:
16535                         case SMB_COM_TRANSACTION2_SECONDARY:
16536                         case SMB_COM_NT_TRANSACT_SECONDARY:
16537                                 proto_tree_add_uint(htree, hf_smb_continuation_to,
16538                                                     tvb, 0, 0, sip->frame_req);
16539                                 break;
16540                         }
16541                 } else {
16542                         switch(si->cmd){
16543                         case SMB_COM_NT_CANCEL:
16544                                 proto_tree_add_text(htree, tvb, 0, 0,
16545                                                     "Cancellation to: <unknown frame>");
16546                                 break;
16547                         case SMB_COM_TRANSACTION_SECONDARY:
16548                         case SMB_COM_TRANSACTION2_SECONDARY:
16549                         case SMB_COM_NT_TRANSACT_SECONDARY:
16550                                 proto_tree_add_text(htree, tvb, 0, 0,
16551                                                     "Continuation to: <unknown frame>");
16552                                 break;
16553                         }
16554                 }
16555         } else { /* normal bidirectional request or response */
16556                 si->unidir = FALSE;
16557
16558                 if(!pinfo->fd->flags.visited){
16559                         /* first see if we find an unmatched smb "equal" to
16560                            the current one
16561                         */
16562                         sip=g_hash_table_lookup(si->ct->unmatched, (void *)pid_mid);
16563                         if(sip!=NULL){
16564                                 gboolean cmd_match=FALSE;
16565
16566                                 /*
16567                                  * Make sure the SMB we found was the
16568                                  * same command, or a different command
16569                                  * that's another valid type of reply
16570                                  * to that command.
16571                                  */
16572                                 if(si->cmd==sip->cmd){
16573                                         cmd_match=TRUE;
16574                                 }
16575                                 else if(si->cmd==SMB_COM_NT_CANCEL){
16576                                         cmd_match=TRUE;
16577                                 }
16578                                 else if((si->cmd==SMB_COM_TRANSACTION_SECONDARY)
16579                                      && (sip->cmd==SMB_COM_TRANSACTION)){
16580                                         cmd_match=TRUE;
16581                                 }
16582                                 else if((si->cmd==SMB_COM_TRANSACTION2_SECONDARY)
16583                                      && (sip->cmd==SMB_COM_TRANSACTION2)){
16584                                         cmd_match=TRUE;
16585                                 }
16586                                 else if((si->cmd==SMB_COM_NT_TRANSACT_SECONDARY)
16587                                      && (sip->cmd==SMB_COM_NT_TRANSACT)){
16588                                         cmd_match=TRUE;
16589                                 }
16590
16591                                 if( (si->request) || (!cmd_match) ) {
16592                                         /* If we are processing an SMB request but there was already
16593                                            another "identical" smb resuest we had not matched yet.
16594                                            This must mean that either we have a retransmission or that the
16595                                            response to the previous one was lost and the client has reused
16596                                            the MID for this conversation. In either case it's not much more
16597                                            we can do than forget the old request and concentrate on the
16598                                            present one instead.
16599
16600                                            We also do this cleanup if we see that the cmd in the original
16601                                            request in sip->cmd is not compatible with the current cmd.
16602                                            This is to prevent matching errors such as if there were two
16603                                            SMBs of different cmds but with identical MID and PID values and
16604                                            if ethereal lost the first reply and the second request.
16605                                         */
16606                                         g_hash_table_remove(si->ct->unmatched, (void *)pid_mid);
16607                                         sip=NULL; /* XXX should free it as well */
16608                                 } else {
16609                                         /* we have found a response to some request we have seen earlier.
16610                                            What we do now depends on whether this is the first response
16611                                            to that request we see (id frame_res==0) or not.
16612                                         */
16613                                         if(sip->frame_res==0){
16614                                                 /* ok it is the first response we have seen to this packet */
16615                                                 sip->frame_res = pinfo->fd->num;
16616                                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16617                                                 new_key->frame = sip->frame_res;
16618                                                 new_key->pid_mid = pid_mid;
16619                                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16620                                         } else {
16621                                                 /* We have already seen another response to this MID.
16622                                                    Since the MID in reality is only something like 10 bits
16623                                                    this probably means that we just have a MID that is being
16624                                                    reused due to the small MID space and that this is a new
16625                                                    command we did not see the original request for.
16626                                                 */
16627                                                 sip=NULL;
16628                                         }
16629                                 }
16630                         }
16631                         if(si->request){
16632                                 sip = g_mem_chunk_alloc(smb_saved_info_chunk);
16633                                 sip->frame_req = pinfo->fd->num;
16634                                 sip->frame_res = 0;
16635                                 sip->req_time.secs=pinfo->fd->abs_secs;
16636                                 sip->req_time.nsecs=pinfo->fd->abs_usecs*1000;
16637                                 sip->flags = 0;
16638                                 if(g_hash_table_lookup(si->ct->tid_service, (void *)si->tid)
16639                                     == (void *)TID_IPC) {
16640                                         sip->flags |= SMB_SIF_TID_IS_IPC;
16641                                 }
16642                                 sip->cmd = si->cmd;
16643                                 sip->extra_info = NULL;
16644                                 g_hash_table_insert(si->ct->unmatched, (void *)pid_mid, sip);
16645                                 new_key = g_mem_chunk_alloc(smb_saved_info_key_chunk);
16646                                 new_key->frame = sip->frame_req;
16647                                 new_key->pid_mid = pid_mid;
16648                                 g_hash_table_insert(si->ct->matched, new_key, sip);
16649                         }
16650                 } else {
16651                         /* we have seen this packet before; check the
16652                            matching table.
16653                            If we haven't yet seen the reply, we won't
16654                            find the info for it; we don't need it, as
16655                            we only use it to save information, and, as
16656                            we've seen this packet before, we've already
16657                            saved the information.
16658                         */
16659                         key.frame = pinfo->fd->num;
16660                         key.pid_mid = pid_mid;
16661                         sip=g_hash_table_lookup(si->ct->matched, &key);
16662                 }
16663         }
16664
16665         /*
16666          * Pass the "sip" on to subdissectors through "si".
16667          */
16668         si->sip = sip;
16669
16670         if (sip != NULL) {
16671                 /*
16672                  * Put in fields for the frame number of the frame to which
16673                  * this is a response or the frame with the response to this
16674                  * frame - if we know the frame number (i.e., it's not 0).
16675                  */
16676                 if(si->request){
16677                         if (sip->frame_res != 0)
16678                                 proto_tree_add_uint(htree, hf_smb_response_in, tvb, 0, 0, sip->frame_res);
16679                 } else {
16680                         if (sip->frame_req != 0) {
16681                                 proto_tree_add_uint(htree, hf_smb_response_to, tvb, 0, 0, sip->frame_req);
16682                                 ns.secs = pinfo->fd->abs_secs - sip->req_time.secs;
16683                                 ns.nsecs = pinfo->fd->abs_usecs*1000 - sip->req_time.nsecs;
16684                                 if(ns.nsecs<0){
16685                                         ns.nsecs+=1000000000;
16686                                         ns.secs--;
16687                                 }
16688                                 proto_tree_add_time(htree, hf_smb_time, tvb,
16689                                     0, 0, &ns);
16690                         }
16691                 }
16692         }
16693
16694         /* smb command */
16695         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);
16696         offset += 1;
16697
16698         if(flags2 & 0x4000){
16699                 /* handle NT 32 bit error code */
16700
16701                 nt_status = tvb_get_letohl(tvb, offset);
16702
16703                 proto_tree_add_item(htree, hf_smb_nt_status, tvb, offset, 4,
16704                         TRUE);
16705                 offset += 4;
16706
16707         } else {
16708                 /* handle DOS error code & class */
16709                 errclass = tvb_get_guint8(tvb, offset);
16710                 proto_tree_add_uint(htree, hf_smb_error_class, tvb, offset, 1,
16711                         errclass);
16712                 offset += 1;
16713
16714                 /* reserved byte */
16715                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 1, TRUE);
16716                 offset += 1;
16717
16718                 /* error code */
16719                 /* XXX - the type of this field depends on the value of
16720                  * "errcls", so there is isn't a single value_string array
16721                  * fo it, so there can't be a single field for it.
16722                  */
16723                 errcode = tvb_get_letohs(tvb, offset);
16724                 proto_tree_add_uint_format(htree, hf_smb_error_code, tvb,
16725                         offset, 2, errcode, "Error Code: %s",
16726                         decode_smb_error(errclass, errcode));
16727                 offset += 2;
16728         }
16729
16730         /* flags */
16731         offset = dissect_smb_flags(tvb, htree, offset);
16732
16733         /* flags2 */
16734         offset = dissect_smb_flags2(tvb, htree, offset);
16735
16736         /*
16737          * The document at
16738          *
16739          *      http://www.samba.org/samba/ftp/specs/smbpub.txt
16740          *
16741          * (a text version of "Microsoft Networks SMB FILE SHARING
16742          * PROTOCOL, Document Version 6.0p") says that:
16743          *
16744          *      the first 2 bytes of these 12 bytes are, for NT Create and X,
16745          *      the "High Part of PID";
16746          *
16747          *      the next four bytes are reserved;
16748          *
16749          *      the next four bytes are, for SMB-over-IPX (with no
16750          *      NetBIOS involved) two bytes of Session ID and two bytes
16751          *      of SequenceNumber.
16752          *
16753          * Network Monitor 2.x dissects the four bytes before the Session ID
16754          * as a "Key", and the two bytes after the SequenceNumber as
16755          * a "Group ID".
16756          *
16757          * The "High Part of PID" has been seen in calls other than NT
16758          * Create and X, although most of them appear to be I/O on DCE RPC
16759          * pipes opened with the NT Create and X in question.
16760          */
16761         proto_tree_add_item(htree, hf_smb_pid_high, tvb, offset, 2, TRUE);
16762         offset += 2;
16763
16764         if (pinfo->ptype == PT_IPX &&
16765             (pinfo->match_port == IPX_SOCKET_NWLINK_SMB_SERVER ||
16766              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_REDIR ||
16767              pinfo->match_port == IPX_SOCKET_NWLINK_SMB_MESSENGER)) {
16768                 /*
16769                  * This is SMB-over-IPX.
16770                  * XXX - do we have to worry about "sequenced commands",
16771                  * as per the Samba document?  They say that for
16772                  * "unsequenced commands" (with a sequence number of 0),
16773                  * the Mid must be unique, but perhaps the Mid doesn't
16774                  * have to be unique for sequenced commands.  In at least
16775                  * one capture with SMB-over-IPX, however, the Mids
16776                  * are unique even for sequenced commands.
16777                  */
16778                 /* Key */
16779                 proto_tree_add_item(htree, hf_smb_key, tvb, offset, 4,
16780                     TRUE);
16781                 offset += 4;
16782
16783                 /* Session ID */
16784                 proto_tree_add_item(htree, hf_smb_session_id, tvb, offset, 2,
16785                     TRUE);
16786                 offset += 2;
16787
16788                 /* Sequence number */
16789                 proto_tree_add_item(htree, hf_smb_sequence_num, tvb, offset, 2,
16790                     TRUE);
16791                 offset += 2;
16792
16793                 /* Group ID */
16794                 proto_tree_add_item(htree, hf_smb_group_id, tvb, offset, 2,
16795                     TRUE);
16796                 offset += 2;
16797         } else {
16798                 /*
16799                  * According to http://ubiqx.org/cifs/SMB.html#SMB.4.2.1
16800                  * and http://ubiqx.org/cifs/SMB.html#SMB.5.5.1 the 8
16801                  * bytes after the "High part of PID" are an 8-byte
16802                  * signature ...
16803                  */
16804                 proto_tree_add_item(htree, hf_smb_sig, tvb, offset, 8, TRUE);
16805                 offset += 8;
16806
16807                 proto_tree_add_item(htree, hf_smb_reserved, tvb, offset, 2, TRUE);
16808                 offset += 2;
16809         }
16810
16811         /* TID */
16812         proto_tree_add_uint(htree, hf_smb_tid, tvb, offset, 2, si->tid);
16813         offset += 2;
16814
16815         /* PID */
16816         proto_tree_add_uint(htree, hf_smb_pid, tvb, offset, 2, si->pid);
16817         offset += 2;
16818
16819         /* UID */
16820         proto_tree_add_uint(htree, hf_smb_uid, tvb, offset, 2, si->uid);
16821         offset += 2;
16822
16823         /* MID */
16824         proto_tree_add_uint(htree, hf_smb_mid, tvb, offset, 2, si->mid);
16825         offset += 2;
16826
16827         pinfo->private_data = si;
16828
16829         /* tap the packet before the dissectors are called so we still get
16830            the tap listener called even if there is an exception.
16831         */
16832         tap_queue_packet(smb_tap, pinfo, si);
16833         dissect_smb_command(tvb, pinfo, offset, tree, si->cmd, TRUE);
16834
16835         /* Append error info from this packet to info string. */
16836         if (!si->request && check_col(pinfo->cinfo, COL_INFO)) {
16837                 if (flags2 & 0x4000) {
16838                         /*
16839                          * The status is an NT status code; was there
16840                          * an error?
16841                          */
16842                         if ((nt_status & 0xC0000000) == 0xC0000000) {
16843                                 /*
16844                                  * Yes.
16845                                  */
16846                                 col_append_fstr(
16847                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16848                                         val_to_str(nt_status, NT_errors,
16849                                             "Unknown (0x%08X)"));
16850                         }
16851                 } else {
16852                         /*
16853                          * The status is a DOS error class and code; was
16854                          * there an error?
16855                          */
16856                         if (errclass != SMB_SUCCESS) {
16857                                 /*
16858                                  * Yes.
16859                                  */
16860                                 col_append_fstr(
16861                                         pinfo->cinfo, COL_INFO, ", Error: %s",
16862                                         decode_smb_error(errclass, errcode));
16863                         }
16864                 }
16865         }
16866 }
16867
16868 static gboolean
16869 dissect_smb_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
16870 {
16871         /* must check that this really is a smb packet */
16872         if (!tvb_bytes_exist(tvb, 0, 4))
16873                 return FALSE;
16874
16875         if( (tvb_get_guint8(tvb, 0) != 0xff)
16876             || (tvb_get_guint8(tvb, 1) != 'S')
16877             || (tvb_get_guint8(tvb, 2) != 'M')
16878             || (tvb_get_guint8(tvb, 3) != 'B') ){
16879                 return FALSE;
16880         }
16881
16882         dissect_smb(tvb, pinfo, parent_tree);
16883         return TRUE;
16884 }
16885
16886 void
16887 proto_register_smb(void)
16888 {
16889         static hf_register_info hf[] = {
16890         { &hf_smb_cmd,
16891                 { "SMB Command", "smb.cmd", FT_UINT8, BASE_HEX,
16892                 VALS(smb_cmd_vals), 0x0, "SMB Command", HFILL }},
16893
16894         { &hf_smb_word_count,
16895                 { "Word Count (WCT)", "smb.wct", FT_UINT8, BASE_DEC,
16896                 NULL, 0x0, "Word Count, count of parameter words", HFILL }},
16897
16898         { &hf_smb_byte_count,
16899                 { "Byte Count (BCC)", "smb.bcc", FT_UINT16, BASE_DEC,
16900                 NULL, 0x0, "Byte Count, count of data bytes", HFILL }},
16901
16902         { &hf_smb_response_to,
16903                 { "Response to", "smb.response_to", FT_FRAMENUM, BASE_NONE,
16904                 NULL, 0, "This packet is a response to the packet in this frame", HFILL }},
16905
16906         { &hf_smb_time,
16907                 { "Time from request", "smb.time", FT_RELATIVE_TIME, BASE_NONE,
16908                 NULL, 0, "Time between Request and Response for SMB cmds", HFILL }},
16909
16910         { &hf_smb_response_in,
16911                 { "Response in", "smb.response_in", FT_FRAMENUM, BASE_NONE,
16912                 NULL, 0, "The response to this packet is in this packet", HFILL }},
16913
16914         { &hf_smb_continuation_to,
16915                 { "Continuation to", "smb.continuation_to", FT_FRAMENUM, BASE_NONE,
16916                 NULL, 0, "This packet is a continuation to the packet in this frame", HFILL }},
16917
16918         { &hf_smb_nt_status,
16919                 { "NT Status", "smb.nt_status", FT_UINT32, BASE_HEX,
16920                 VALS(NT_errors), 0, "NT Status code", HFILL }},
16921
16922         { &hf_smb_error_class,
16923                 { "Error Class", "smb.error_class", FT_UINT8, BASE_HEX,
16924                 VALS(errcls_types), 0, "DOS Error Class", HFILL }},
16925
16926         { &hf_smb_error_code,
16927                 { "Error Code", "smb.error_code", FT_UINT16, BASE_HEX,
16928                 NULL, 0, "DOS Error Code", HFILL }},
16929
16930         { &hf_smb_reserved,
16931                 { "Reserved", "smb.reserved", FT_BYTES, BASE_HEX,
16932                 NULL, 0, "Reserved bytes, must be zero", HFILL }},
16933
16934         { &hf_smb_sig,
16935                 { "Signature", "smb.signature", FT_BYTES, BASE_HEX,
16936                 NULL, 0, "Signature bytes", HFILL }},
16937
16938         { &hf_smb_key,
16939                 { "Key", "smb.key", FT_UINT32, BASE_HEX,
16940                 NULL, 0, "SMB-over-IPX Key", HFILL }},
16941
16942         { &hf_smb_session_id,
16943                 { "Session ID", "smb.sessid", FT_UINT16, BASE_DEC,
16944                 NULL, 0, "SMB-over-IPX Session ID", HFILL }},
16945
16946         { &hf_smb_sequence_num,
16947                 { "Sequence Number", "smb.sequence_num", FT_UINT16, BASE_DEC,
16948                 NULL, 0, "SMB-over-IPX Sequence Number", HFILL }},
16949
16950         { &hf_smb_group_id,
16951                 { "Group ID", "smb.group_id", FT_UINT16, BASE_DEC,
16952                 NULL, 0, "SMB-over-IPX Group ID", HFILL }},
16953
16954         { &hf_smb_pid,
16955                 { "Process ID", "smb.pid", FT_UINT16, BASE_DEC,
16956                 NULL, 0, "Process ID", HFILL }},
16957
16958         { &hf_smb_pid_high,
16959                 { "Process ID High", "smb.pid.high", FT_UINT16, BASE_DEC,
16960                 NULL, 0, "Process ID High Bytes", HFILL }},
16961
16962         { &hf_smb_tid,
16963                 { "Tree ID", "smb.tid", FT_UINT16, BASE_DEC,
16964                 NULL, 0, "Tree ID", HFILL }},
16965
16966         { &hf_smb_uid,
16967                 { "User ID", "smb.uid", FT_UINT16, BASE_DEC,
16968                 NULL, 0, "User ID", HFILL }},
16969
16970         { &hf_smb_mid,
16971                 { "Multiplex ID", "smb.mid", FT_UINT16, BASE_DEC,
16972                 NULL, 0, "Multiplex ID", HFILL }},
16973
16974         { &hf_smb_flags_lock,
16975                 { "Lock and Read", "smb.flags.lock", FT_BOOLEAN, 8,
16976                 TFS(&tfs_smb_flags_lock), 0x01, "Are Lock&Read and Write&Unlock operations supported?", HFILL }},
16977
16978         { &hf_smb_flags_receive_buffer,
16979                 { "Receive Buffer Posted", "smb.flags.receive_buffer", FT_BOOLEAN, 8,
16980                 TFS(&tfs_smb_flags_receive_buffer), 0x02, "Have receive buffers been reported?", HFILL }},
16981
16982         { &hf_smb_flags_caseless,
16983                 { "Case Sensitivity", "smb.flags.caseless", FT_BOOLEAN, 8,
16984                 TFS(&tfs_smb_flags_caseless), 0x08, "Are pathnames caseless or casesensitive?", HFILL }},
16985
16986         { &hf_smb_flags_canon,
16987                 { "Canonicalized Pathnames", "smb.flags.canon", FT_BOOLEAN, 8,
16988                 TFS(&tfs_smb_flags_canon), 0x10, "Are pathnames canonicalized?", HFILL }},
16989
16990         { &hf_smb_flags_oplock,
16991                 { "Oplocks", "smb.flags.oplock", FT_BOOLEAN, 8,
16992                 TFS(&tfs_smb_flags_oplock), 0x20, "Is an oplock requested/granted?", HFILL }},
16993
16994         { &hf_smb_flags_notify,
16995                 { "Notify", "smb.flags.notify", FT_BOOLEAN, 8,
16996                 TFS(&tfs_smb_flags_notify), 0x40, "Notify on open or all?", HFILL }},
16997
16998         { &hf_smb_flags_response,
16999                 { "Request/Response", "smb.flags.response", FT_BOOLEAN, 8,
17000                 TFS(&tfs_smb_flags_response), 0x80, "Is this a request or a response?", HFILL }},
17001
17002         { &hf_smb_flags2_long_names_allowed,
17003                 { "Long Names Allowed", "smb.flags2.long_names_allowed", FT_BOOLEAN, 16,
17004                 TFS(&tfs_smb_flags2_long_names_allowed), 0x0001, "Are long file names allowed in the response?", HFILL }},
17005
17006         { &hf_smb_flags2_ea,
17007                 { "Extended Attributes", "smb.flags2.ea", FT_BOOLEAN, 16,
17008                 TFS(&tfs_smb_flags2_ea), 0x0002, "Are extended attributes supported?", HFILL }},
17009
17010         { &hf_smb_flags2_sec_sig,
17011                 { "Security Signatures", "smb.flags2.sec_sig", FT_BOOLEAN, 16,
17012                 TFS(&tfs_smb_flags2_sec_sig), 0x0004, "Are security signatures supported?", HFILL }},
17013
17014         { &hf_smb_flags2_long_names_used,
17015                 { "Long Names Used", "smb.flags2.long_names_used", FT_BOOLEAN, 16,
17016                 TFS(&tfs_smb_flags2_long_names_used), 0x0040, "Are pathnames in this request long file names?", HFILL }},
17017
17018         { &hf_smb_flags2_esn,
17019                 { "Extended Security Negotiation", "smb.flags2.esn", FT_BOOLEAN, 16,
17020                 TFS(&tfs_smb_flags2_esn), 0x0800, "Is extended security negotiation supported?", HFILL }},
17021
17022         { &hf_smb_flags2_dfs,
17023                 { "Dfs", "smb.flags2.dfs", FT_BOOLEAN, 16,
17024                 TFS(&tfs_smb_flags2_dfs), 0x1000, "Can pathnames be resolved using Dfs?", HFILL }},
17025
17026         { &hf_smb_flags2_roe,
17027                 { "Execute-only Reads", "smb.flags2.roe", FT_BOOLEAN, 16,
17028                 TFS(&tfs_smb_flags2_roe), 0x2000, "Will reads be allowed for execute-only files?", HFILL }},
17029
17030         { &hf_smb_flags2_nt_error,
17031                 { "Error Code Type", "smb.flags2.nt_error", FT_BOOLEAN, 16,
17032                 TFS(&tfs_smb_flags2_nt_error), 0x4000, "Are error codes NT or DOS format?", HFILL }},
17033
17034         { &hf_smb_flags2_string,
17035                 { "Unicode Strings", "smb.flags2.string", FT_BOOLEAN, 16,
17036                 TFS(&tfs_smb_flags2_string), 0x8000, "Are strings ASCII or Unicode?", HFILL }},
17037
17038         { &hf_smb_buffer_format,
17039                 { "Buffer Format", "smb.buffer_format", FT_UINT8, BASE_DEC,
17040                 VALS(buffer_format_vals), 0x0, "Buffer Format, type of buffer", HFILL }},
17041
17042         { &hf_smb_dialect_name,
17043                 { "Name", "smb.dialect.name", FT_STRING, BASE_NONE,
17044                 NULL, 0, "Name of dialect", HFILL }},
17045
17046         { &hf_smb_dialect_index,
17047                 { "Selected Index", "smb.dialect.index", FT_UINT16, BASE_DEC,
17048                 NULL, 0, "Index of selected dialect", HFILL }},
17049
17050         { &hf_smb_max_trans_buf_size,
17051                 { "Max Buffer Size", "smb.max_bufsize", FT_UINT32, BASE_DEC,
17052                 NULL, 0, "Maximum transmit buffer size", HFILL }},
17053
17054         { &hf_smb_max_mpx_count,
17055                 { "Max Mpx Count", "smb.max_mpx_count", FT_UINT16, BASE_DEC,
17056                 NULL, 0, "Maximum pending multiplexed requests", HFILL }},
17057
17058         { &hf_smb_max_vcs_num,
17059                 { "Max VCs", "smb.max_vcs", FT_UINT16, BASE_DEC,
17060                 NULL, 0, "Maximum VCs between client and server", HFILL }},
17061
17062         { &hf_smb_session_key,
17063                 { "Session Key", "smb.session_key", FT_UINT32, BASE_HEX,
17064                 NULL, 0, "Unique token identifying this session", HFILL }},
17065
17066         { &hf_smb_server_timezone,
17067                 { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
17068                 NULL, 0, "Current timezone at server.", HFILL }},
17069
17070         { &hf_smb_encryption_key_length,
17071                 { "Key Length", "smb.encryption_key_length", FT_UINT16, BASE_DEC,
17072                 NULL, 0, "Encryption key length (must be 0 if not LM2.1 dialect)", HFILL }},
17073
17074         { &hf_smb_encryption_key,
17075                 { "Encryption Key", "smb.encryption_key", FT_BYTES, BASE_HEX,
17076                 NULL, 0, "Challenge/Response Encryption Key (for LM2.1 dialect)", HFILL }},
17077
17078         { &hf_smb_primary_domain,
17079                 { "Primary Domain", "smb.primary_domain", FT_STRING, BASE_NONE,
17080                 NULL, 0, "The server's primary domain", HFILL }},
17081
17082         { &hf_smb_server,
17083                 { "Server", "smb.server", FT_STRING, BASE_NONE,
17084                 NULL, 0, "The name of the DC/server", HFILL }},
17085
17086         { &hf_smb_max_raw_buf_size,
17087                 { "Max Raw Buffer", "smb.max_raw", FT_UINT32, BASE_DEC,
17088                 NULL, 0, "Maximum raw buffer size", HFILL }},
17089
17090         { &hf_smb_server_guid,
17091                 { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
17092                 NULL, 0, "Globally unique identifier for this server", HFILL }},
17093
17094         { &hf_smb_security_blob_len,
17095                 { "Security Blob Length", "smb.security_blob_len", FT_UINT16, BASE_DEC,
17096                 NULL, 0, "Security blob length", HFILL }},
17097
17098         { &hf_smb_security_blob,
17099                 { "Security Blob", "smb.security_blob", FT_BYTES, BASE_HEX,
17100                 NULL, 0, "Security blob", HFILL }},
17101
17102         { &hf_smb_sm_mode16,
17103                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 16,
17104                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17105
17106         { &hf_smb_sm_password16,
17107                 { "Password", "smb.sm.password", FT_BOOLEAN, 16,
17108                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17109
17110         { &hf_smb_sm_mode,
17111                 { "Mode", "smb.sm.mode", FT_BOOLEAN, 8,
17112                 TFS(&tfs_sm_mode), SECURITY_MODE_MODE, "User or Share security mode?", HFILL }},
17113
17114         { &hf_smb_sm_password,
17115                 { "Password", "smb.sm.password", FT_BOOLEAN, 8,
17116                 TFS(&tfs_sm_password), SECURITY_MODE_PASSWORD, "Encrypted or plaintext passwords?", HFILL }},
17117
17118         { &hf_smb_sm_signatures,
17119                 { "Signatures", "smb.sm.signatures", FT_BOOLEAN, 8,
17120                 TFS(&tfs_sm_signatures), SECURITY_MODE_SIGNATURES, "Are security signatures enabled?", HFILL }},
17121
17122         { &hf_smb_sm_sig_required,
17123                 { "Sig Req", "smb.sm.sig_required", FT_BOOLEAN, 8,
17124                 TFS(&tfs_sm_sig_required), SECURITY_MODE_SIG_REQUIRED, "Are security signatures required?", HFILL }},
17125
17126         { &hf_smb_rm_read,
17127                 { "Read Raw", "smb.rm.read", FT_BOOLEAN, 16,
17128                 TFS(&tfs_rm_read), RAWMODE_READ, "Is Read Raw supported?", HFILL }},
17129
17130         { &hf_smb_rm_write,
17131                 { "Write Raw", "smb.rm.write", FT_BOOLEAN, 16,
17132                 TFS(&tfs_rm_write), RAWMODE_WRITE, "Is Write Raw supported?", HFILL }},
17133
17134         { &hf_smb_server_date_time,
17135                 { "Server Date and Time", "smb.server_date_time", FT_ABSOLUTE_TIME, BASE_NONE,
17136                 NULL, 0, "Current date and time at server", HFILL }},
17137
17138         { &hf_smb_server_smb_date,
17139                 { "Server Date", "smb.server_date_time.smb_date", FT_UINT16, BASE_HEX,
17140                 NULL, 0, "Current date at server, SMB_DATE format", HFILL }},
17141
17142         { &hf_smb_server_smb_time,
17143                 { "Server Time", "smb.server_date_time.smb_time", FT_UINT16, BASE_HEX,
17144                 NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
17145
17146         { &hf_smb_server_cap_raw_mode,
17147                 { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
17148                 TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
17149
17150         { &hf_smb_server_cap_mpx_mode,
17151                 { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
17152                 TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
17153
17154         { &hf_smb_server_cap_unicode,
17155                 { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
17156                 TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
17157
17158         { &hf_smb_server_cap_large_files,
17159                 { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
17160                 TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
17161
17162         { &hf_smb_server_cap_nt_smbs,
17163                 { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
17164                 TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
17165
17166         { &hf_smb_server_cap_rpc_remote_apis,
17167                 { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
17168                 TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
17169
17170         { &hf_smb_server_cap_nt_status,
17171                 { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
17172                 TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
17173
17174         { &hf_smb_server_cap_level_ii_oplocks,
17175                 { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
17176                 TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
17177
17178         { &hf_smb_server_cap_lock_and_read,
17179                 { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
17180                 TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
17181
17182         { &hf_smb_server_cap_nt_find,
17183                 { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
17184                 TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
17185
17186         { &hf_smb_server_cap_dfs,
17187                 { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
17188                 TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
17189
17190         { &hf_smb_server_cap_infolevel_passthru,
17191                 { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
17192                 TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
17193
17194         { &hf_smb_server_cap_large_readx,
17195                 { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
17196                 TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
17197
17198         { &hf_smb_server_cap_large_writex,
17199                 { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
17200                 TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
17201
17202         { &hf_smb_server_cap_unix,
17203                 { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
17204                 TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
17205
17206         { &hf_smb_server_cap_reserved,
17207                 { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
17208                 TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
17209
17210         { &hf_smb_server_cap_bulk_transfer,
17211                 { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
17212                 TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
17213
17214         { &hf_smb_server_cap_compressed_data,
17215                 { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
17216                 TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
17217
17218         { &hf_smb_server_cap_extended_security,
17219                 { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
17220                 TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
17221
17222         { &hf_smb_system_time,
17223                 { "System Time", "smb.system.time", FT_ABSOLUTE_TIME, BASE_NONE,
17224                 NULL, 0, "System Time", HFILL }},
17225
17226         { &hf_smb_unknown,
17227                 { "Unknown Data", "smb.unknown", FT_BYTES, BASE_HEX,
17228                 NULL, 0, "Unknown Data. Should be implemented by someone", HFILL }},
17229
17230         { &hf_smb_dir_name,
17231                 { "Directory", "smb.dir_name", FT_STRING, BASE_NONE,
17232                 NULL, 0, "SMB Directory Name", HFILL }},
17233
17234         { &hf_smb_echo_count,
17235                 { "Echo Count", "smb.echo.count", FT_UINT16, BASE_DEC,
17236                 NULL, 0, "Number of times to echo data back", HFILL }},
17237
17238         { &hf_smb_echo_data,
17239                 { "Echo Data", "smb.echo.data", FT_BYTES, BASE_HEX,
17240                 NULL, 0, "Data for SMB Echo Request/Response", HFILL }},
17241
17242         { &hf_smb_echo_seq_num,
17243                 { "Echo Seq Num", "smb.echo.seq_num", FT_UINT16, BASE_DEC,
17244                 NULL, 0, "Sequence number for this echo response", HFILL }},
17245
17246         { &hf_smb_max_buf_size,
17247                 { "Max Buffer", "smb.max_buf", FT_UINT16, BASE_DEC,
17248                 NULL, 0, "Max client buffer size", HFILL }},
17249
17250         { &hf_smb_path,
17251                 { "Path", "smb.path", FT_STRING, BASE_NONE,
17252                 NULL, 0, "Path. Server name and share name", HFILL }},
17253
17254         { &hf_smb_service,
17255                 { "Service", "smb.service", FT_STRING, BASE_NONE,
17256                 NULL, 0, "Service name", HFILL }},
17257
17258         { &hf_smb_password,
17259                 { "Password", "smb.password", FT_BYTES, BASE_NONE,
17260                 NULL, 0, "Password", HFILL }},
17261
17262         { &hf_smb_ansi_password,
17263                 { "ANSI Password", "smb.ansi_password", FT_BYTES, BASE_NONE,
17264                 NULL, 0, "ANSI Password", HFILL }},
17265
17266         { &hf_smb_unicode_password,
17267                 { "Unicode Password", "smb.unicode_password", FT_BYTES, BASE_NONE,
17268                 NULL, 0, "Unicode Password", HFILL }},
17269
17270         { &hf_smb_move_flags_file,
17271                 { "Must be file", "smb.move.flags.file", FT_BOOLEAN, 16,
17272                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17273
17274         { &hf_smb_move_flags_dir,
17275                 { "Must be directory", "smb.move.flags.dir", FT_BOOLEAN, 16,
17276                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17277
17278         { &hf_smb_move_flags_verify,
17279                 { "Verify writes", "smb.move.flags.verify", FT_BOOLEAN, 16,
17280                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17281
17282         { &hf_smb_files_moved,
17283                 { "Files Moved", "smb.files_moved", FT_UINT16, BASE_DEC,
17284                 NULL, 0, "Number of files moved", HFILL }},
17285
17286         { &hf_smb_copy_flags_file,
17287                 { "Must be file", "smb.copy.flags.file", FT_BOOLEAN, 16,
17288                 TFS(&tfs_mf_file), 0x0001, "Must target be a file?", HFILL }},
17289
17290         { &hf_smb_copy_flags_dir,
17291                 { "Must be directory", "smb.copy.flags.dir", FT_BOOLEAN, 16,
17292                 TFS(&tfs_mf_dir), 0x0002, "Must target be a directory?", HFILL }},
17293
17294         { &hf_smb_copy_flags_dest_mode,
17295                 { "Destination mode", "smb.copy.flags.dest_mode", FT_BOOLEAN, 16,
17296                 TFS(&tfs_cf_mode), 0x0004, "Is destination in ASCII?", HFILL }},
17297
17298         { &hf_smb_copy_flags_source_mode,
17299                 { "Source mode", "smb.copy.flags.source_mode", FT_BOOLEAN, 16,
17300                 TFS(&tfs_cf_mode), 0x0008, "Is source in ASCII?", HFILL }},
17301
17302         { &hf_smb_copy_flags_verify,
17303                 { "Verify writes", "smb.copy.flags.verify", FT_BOOLEAN, 16,
17304                 TFS(&tfs_mf_verify), 0x0010, "Verify all writes?", HFILL }},
17305
17306         { &hf_smb_copy_flags_tree_copy,
17307                 { "Tree copy", "smb.copy.flags.tree_copy", FT_BOOLEAN, 16,
17308                 TFS(&tfs_cf_tree_copy), 0x0010, "Is copy a tree copy?", HFILL }},
17309
17310         { &hf_smb_copy_flags_ea_action,
17311                 { "EA action if EAs not supported on dest", "smb.copy.flags.ea_action", FT_BOOLEAN, 16,
17312                 TFS(&tfs_cf_ea_action), 0x0010, "Fail copy if source file has EAs and dest doesn't support EAs?", HFILL }},
17313
17314         { &hf_smb_count,
17315                 { "Count", "smb.count", FT_UINT32, BASE_DEC,
17316                 NULL, 0, "Count number of items/bytes", HFILL }},
17317
17318         { &hf_smb_count_low,
17319                 { "Count Low", "smb.count_low", FT_UINT16, BASE_DEC,
17320                 NULL, 0, "Count number of items/bytes, Low 16 bits", HFILL }},
17321
17322         { &hf_smb_count_high,
17323                 { "Count High (multiply with 64K)", "smb.count_high", FT_UINT16, BASE_DEC,
17324                 NULL, 0, "Count number of items/bytes, High 16 bits", HFILL }},
17325
17326         { &hf_smb_file_name,
17327                 { "File Name", "smb.file", FT_STRING, BASE_NONE,
17328                 NULL, 0, "File Name", HFILL }},
17329
17330         { &hf_smb_open_function_create,
17331                 { "Create", "smb.open.function.create", FT_BOOLEAN, 16,
17332                 TFS(&tfs_of_create), 0x0010, "Create file if it doesn't exist?", HFILL }},
17333
17334         { &hf_smb_open_function_open,
17335                 { "Open", "smb.open.function.open", FT_UINT16, BASE_DEC,
17336                 VALS(of_open), 0x0003, "Action to be taken on open if file exists", HFILL }},
17337
17338         { &hf_smb_fid,
17339                 { "FID", "smb.fid", FT_UINT16, BASE_HEX,
17340                 NULL, 0, "FID: File ID", HFILL }},
17341
17342         { &hf_smb_file_attr_read_only_16bit,
17343                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
17344                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17345
17346         { &hf_smb_file_attr_read_only_8bit,
17347                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
17348                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
17349
17350         { &hf_smb_file_attr_hidden_16bit,
17351                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
17352                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17353
17354         { &hf_smb_file_attr_hidden_8bit,
17355                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
17356                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
17357
17358         { &hf_smb_file_attr_system_16bit,
17359                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
17360                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17361
17362         { &hf_smb_file_attr_system_8bit,
17363                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
17364                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
17365
17366         { &hf_smb_file_attr_volume_16bit,
17367                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
17368                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
17369
17370         { &hf_smb_file_attr_volume_8bit,
17371                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
17372                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
17373
17374         { &hf_smb_file_attr_directory_16bit,
17375                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
17376                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17377
17378         { &hf_smb_file_attr_directory_8bit,
17379                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
17380                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
17381
17382         { &hf_smb_file_attr_archive_16bit,
17383                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
17384                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17385
17386         { &hf_smb_file_attr_archive_8bit,
17387                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
17388                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
17389
17390         { &hf_smb_file_attr_device,
17391                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
17392                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
17393
17394         { &hf_smb_file_attr_normal,
17395                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
17396                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
17397
17398         { &hf_smb_file_attr_temporary,
17399                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
17400                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
17401
17402         { &hf_smb_file_attr_sparse,
17403                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
17404                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
17405
17406         { &hf_smb_file_attr_reparse,
17407                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
17408                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
17409
17410         { &hf_smb_file_attr_compressed,
17411                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
17412                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
17413
17414         { &hf_smb_file_attr_offline,
17415                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
17416                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
17417
17418         { &hf_smb_file_attr_not_content_indexed,
17419                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
17420                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
17421
17422         { &hf_smb_file_attr_encrypted,
17423                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
17424                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
17425
17426         { &hf_smb_file_size,
17427                 { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
17428                 NULL, 0, "File Size", HFILL }},
17429
17430         { &hf_smb_search_attribute_read_only,
17431                 { "Read Only", "smb.search.attribute.read_only", FT_BOOLEAN, 16,
17432                 TFS(&tfs_search_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY search attribute", HFILL }},
17433
17434         { &hf_smb_search_attribute_hidden,
17435                 { "Hidden", "smb.search.attribute.hidden", FT_BOOLEAN, 16,
17436                 TFS(&tfs_search_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN search attribute", HFILL }},
17437
17438         { &hf_smb_search_attribute_system,
17439                 { "System", "smb.search.attribute.system", FT_BOOLEAN, 16,
17440                 TFS(&tfs_search_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM search attribute", HFILL }},
17441
17442         { &hf_smb_search_attribute_volume,
17443                 { "Volume ID", "smb.search.attribute.volume", FT_BOOLEAN, 16,
17444                 TFS(&tfs_search_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME ID search attribute", HFILL }},
17445
17446         { &hf_smb_search_attribute_directory,
17447                 { "Directory", "smb.search.attribute.directory", FT_BOOLEAN, 16,
17448                 TFS(&tfs_search_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY search attribute", HFILL }},
17449
17450         { &hf_smb_search_attribute_archive,
17451                 { "Archive", "smb.search.attribute.archive", FT_BOOLEAN, 16,
17452                 TFS(&tfs_search_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE search attribute", HFILL }},
17453
17454         { &hf_smb_access_mode,
17455                 { "Access Mode", "smb.access.mode", FT_UINT16, BASE_DEC,
17456                 VALS(da_access_vals), 0x0007, "Access Mode", HFILL }},
17457
17458         { &hf_smb_access_sharing,
17459                 { "Sharing Mode", "smb.access.sharing", FT_UINT16, BASE_DEC,
17460                 VALS(da_sharing_vals), 0x0070, "Sharing Mode", HFILL }},
17461
17462         { &hf_smb_access_locality,
17463                 { "Locality", "smb.access.locality", FT_UINT16, BASE_DEC,
17464                 VALS(da_locality_vals), 0x0700, "Locality of reference", HFILL }},
17465
17466         { &hf_smb_access_caching,
17467                 { "Caching", "smb.access.caching", FT_BOOLEAN, 16,
17468                 TFS(&tfs_da_caching), 0x1000, "Caching mode?", HFILL }},
17469
17470         { &hf_smb_access_writetru,
17471                 { "Writethrough", "smb.access.writethrough", FT_BOOLEAN, 16,
17472                 TFS(&tfs_da_writetru), 0x4000, "Writethrough mode?", HFILL }},
17473
17474         { &hf_smb_create_time,
17475                 { "Created", "smb.create.time", FT_ABSOLUTE_TIME, BASE_NONE,
17476                 NULL, 0, "Creation Time", HFILL }},
17477
17478         { &hf_smb_modify_time,
17479                 { "Modified", "smb.modify.time", FT_ABSOLUTE_TIME, BASE_NONE,
17480                   NULL, 0, "Modification Time", HFILL }},
17481
17482         { &hf_smb_backup_time,
17483                 { "Backed-up", "smb.backup.time", FT_ABSOLUTE_TIME, BASE_NONE,
17484                   NULL, 0, "Backup time", HFILL}},
17485
17486         { &hf_smb_mac_alloc_block_count,
17487                 { "Allocation Block Count", "smb.alloc.count", FT_UINT32, BASE_DEC,
17488                   NULL, 0, "Allocation Block Count", HFILL}},
17489
17490         { &hf_smb_mac_alloc_block_size,
17491                 { "Allocation Block Count", "smb.alloc.size", FT_UINT32, BASE_DEC,
17492                   NULL, 0, "Allocation Block Size", HFILL}},
17493
17494         { &hf_smb_mac_free_block_count,
17495                 { "Free Block Count", "smb.free_block.count", FT_UINT32, BASE_DEC,
17496                   NULL, 0, "Free Block Count", HFILL}},
17497
17498         { &hf_smb_mac_root_file_count,
17499                 { "Root File Count", "smb.root.file.count", FT_UINT32, BASE_DEC,
17500                 NULL, 0, "Root File Count", HFILL}},
17501
17502         { &hf_smb_mac_root_dir_count,
17503           { "Root Directory Count", "smb.root.dir.count", FT_UINT32, BASE_DEC,
17504             NULL, 0, "Root Directory Count", HFILL}},
17505
17506         { &hf_smb_mac_file_count,
17507           { "Root File Count", "smb.file.count", FT_UINT32, BASE_DEC,
17508             NULL, 0, "File Count", HFILL}},
17509
17510         { &hf_smb_mac_dir_count,
17511           { "Root Directory Count", "smb.dir.count", FT_UINT32, BASE_DEC,
17512             NULL, 0, "Directory Count", HFILL}},
17513
17514         { &hf_smb_mac_support_flags,
17515           { "Mac Support Flags", "smb.mac.support.flags", FT_UINT32, BASE_DEC,
17516             NULL, 0, "Mac Support Flags", HFILL}},
17517
17518         { &hf_smb_mac_sup_access_ctrl,
17519           { "Mac Access Control", "smb.mac.access_control", FT_BOOLEAN, 32,
17520             TFS(&tfs_smb_mac_access_ctrl), 0x0010, "Are Mac Access Control Supported", HFILL }},
17521
17522         { &hf_smb_mac_sup_getset_comments,
17523           { "Get Set Comments", "smb.mac.get_set_comments", FT_BOOLEAN, 32,
17524             TFS(&tfs_smb_mac_getset_comments), 0x0020, "Are Mac Get Set Comments supported?", HFILL }},
17525
17526         { &hf_smb_mac_sup_desktopdb_calls,
17527           { "Desktop DB Calls", "smb.mac.desktop_db_calls", FT_BOOLEAN, 32,
17528             TFS(&tfs_smb_mac_desktopdb_calls), 0x0040, "Are Macintosh Desktop DB Calls Supported?", HFILL }},
17529
17530         { &hf_smb_mac_sup_unique_ids,
17531           { "Macintosh Unique IDs", "smb.mac.uids", FT_BOOLEAN, 32,
17532             TFS(&tfs_smb_mac_unique_ids), 0x0080, "Are Unique IDs supported", HFILL }},
17533
17534         { &hf_smb_mac_sup_streams,
17535           { "Mac Streams", "smb.mac.streams_support", FT_BOOLEAN, 32,
17536             TFS(&tfs_smb_mac_streams), 0x0100, "Are Mac Extensions and streams supported?", HFILL }},
17537
17538         { &hf_smb_create_dos_date,
17539                 { "Create Date", "smb.create.smb.date", FT_UINT16, BASE_HEX,
17540                 NULL, 0, "Create Date, SMB_DATE format", HFILL }},
17541
17542         { &hf_smb_create_dos_time,
17543                 { "Create Time", "smb.create.smb.time", FT_UINT16, BASE_HEX,
17544                 NULL, 0, "Create Time, SMB_TIME format", HFILL }},
17545
17546         { &hf_smb_last_write_time,
17547                 { "Last Write", "smb.last_write.time", FT_ABSOLUTE_TIME, BASE_NONE,
17548                 NULL, 0, "Time this file was last written to", HFILL }},
17549
17550         { &hf_smb_last_write_dos_date,
17551                 { "Last Write Date", "smb.last_write.smb.date", FT_UINT16, BASE_HEX,
17552                 NULL, 0, "Last Write Date, SMB_DATE format", HFILL }},
17553
17554         { &hf_smb_last_write_dos_time,
17555                 { "Last Write Time", "smb.last_write.smb.time", FT_UINT16, BASE_HEX,
17556                 NULL, 0, "Last Write Time, SMB_TIME format", HFILL }},
17557
17558         { &hf_smb_old_file_name,
17559                 { "Old File Name", "smb.file", FT_STRING, BASE_NONE,
17560                 NULL, 0, "Old File Name (When renaming a file)", HFILL }},
17561
17562         { &hf_smb_offset,
17563                 { "Offset", "smb.offset", FT_UINT32, BASE_DEC,
17564                 NULL, 0, "Offset in file", HFILL }},
17565
17566         { &hf_smb_remaining,
17567                 { "Remaining", "smb.remaining", FT_UINT32, BASE_DEC,
17568                 NULL, 0, "Remaining number of bytes", HFILL }},
17569
17570         { &hf_smb_padding,
17571                 { "Padding", "smb.padding", FT_BYTES, BASE_HEX,
17572                 NULL, 0, "Padding or unknown data", HFILL }},
17573
17574         { &hf_smb_file_data,
17575                 { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
17576                 NULL, 0, "Data read/written to the file", HFILL }},
17577
17578         { &hf_smb_mac_fndrinfo,
17579                 { "Finder Info", "smb.mac.finderinfo", FT_BYTES, BASE_HEX,
17580                   NULL, 0, "Finder Info", HFILL}},
17581
17582         { &hf_smb_total_data_len,
17583                 { "Total Data Length", "smb.total_data_len", FT_UINT16, BASE_DEC,
17584                 NULL, 0, "Total length of data", HFILL }},
17585
17586         { &hf_smb_data_len,
17587                 { "Data Length", "smb.data_len", FT_UINT16, BASE_DEC,
17588                 NULL, 0, "Length of data", HFILL }},
17589
17590         { &hf_smb_data_len_low,
17591                 { "Data Length Low", "smb.data_len_low", FT_UINT16, BASE_DEC,
17592                 NULL, 0, "Length of data, Low 16 bits", HFILL }},
17593
17594         { &hf_smb_data_len_high,
17595                 { "Data Length High (multiply with 64K)", "smb.data_len_high", FT_UINT16, BASE_DEC,
17596                 NULL, 0, "Length of data, High 16 bits", HFILL }},
17597
17598         { &hf_smb_seek_mode,
17599                 { "Seek Mode", "smb.seek_mode", FT_UINT16, BASE_DEC,
17600                 VALS(seek_mode_vals), 0, "Seek Mode, what type of seek", HFILL }},
17601
17602         { &hf_smb_access_time,
17603                 { "Last Access", "smb.access.time", FT_ABSOLUTE_TIME, BASE_NONE,
17604                 NULL, 0, "Last Access Time", HFILL }},
17605
17606         { &hf_smb_access_dos_date,
17607                 { "Last Access Date", "smb.access.smb.date", FT_UINT16, BASE_HEX,
17608                 NULL, 0, "Last Access Date, SMB_DATE format", HFILL }},
17609
17610         { &hf_smb_access_dos_time,
17611                 { "Last Access Time", "smb.access.smb.time", FT_UINT16, BASE_HEX,
17612                 NULL, 0, "Last Access Time, SMB_TIME format", HFILL }},
17613
17614         { &hf_smb_data_size,
17615                 { "Data Size", "smb.data_size", FT_UINT32, BASE_DEC,
17616                 NULL, 0, "Data Size", HFILL }},
17617
17618         { &hf_smb_alloc_size,
17619                 { "Allocation Size", "smb.alloc_size", FT_UINT32, BASE_DEC,
17620                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
17621
17622         { &hf_smb_max_count,
17623                 { "Max Count", "smb.maxcount", FT_UINT16, BASE_DEC,
17624                 NULL, 0, "Maximum Count", HFILL }},
17625
17626         { &hf_smb_max_count_low,
17627                 { "Max Count Low", "smb.maxcount_low", FT_UINT16, BASE_DEC,
17628                 NULL, 0, "Maximum Count, Low 16 bits", HFILL }},
17629
17630         { &hf_smb_max_count_high,
17631                 { "Max Count High (multiply with 64K)", "smb.maxcount_high", FT_UINT16, BASE_DEC,
17632                 NULL, 0, "Maximum Count, High 16 bits", HFILL }},
17633
17634         { &hf_smb_min_count,
17635                 { "Min Count", "smb.mincount", FT_UINT16, BASE_DEC,
17636                 NULL, 0, "Minimum Count", HFILL }},
17637
17638         { &hf_smb_timeout,
17639                 { "Timeout", "smb.timeout", FT_UINT32, BASE_DEC,
17640                 NULL, 0, "Timeout in miliseconds", HFILL }},
17641
17642         { &hf_smb_high_offset,
17643                 { "High Offset", "smb.offset_high", FT_UINT32, BASE_DEC,
17644                 NULL, 0, "High 32 Bits Of File Offset", HFILL }},
17645
17646         { &hf_smb_units,
17647                 { "Total Units", "smb.units", FT_UINT16, BASE_DEC,
17648                 NULL, 0, "Total number of units at server", HFILL }},
17649
17650         { &hf_smb_bpu,
17651                 { "Blocks Per Unit", "smb.bpu", FT_UINT16, BASE_DEC,
17652                 NULL, 0, "Blocks per unit at server", HFILL }},
17653
17654         { &hf_smb_blocksize,
17655                 { "Block Size", "smb.blocksize", FT_UINT16, BASE_DEC,
17656                 NULL, 0, "Block size (in bytes) at server", HFILL }},
17657
17658         { &hf_smb_freeunits,
17659                 { "Free Units", "smb.free_units", FT_UINT16, BASE_DEC,
17660                 NULL, 0, "Number of free units at server", HFILL }},
17661
17662         { &hf_smb_data_offset,
17663                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17664                 NULL, 0, "Data Offset", HFILL }},
17665
17666         { &hf_smb_dcm,
17667                 { "Data Compaction Mode", "smb.dcm", FT_UINT16, BASE_DEC,
17668                 NULL, 0, "Data Compaction Mode", HFILL }},
17669
17670         { &hf_smb_request_mask,
17671                 { "Request Mask", "smb.request.mask", FT_UINT32, BASE_HEX,
17672                 NULL, 0, "Connectionless mode mask", HFILL }},
17673
17674         { &hf_smb_response_mask,
17675                 { "Response Mask", "smb.response.mask", FT_UINT32, BASE_HEX,
17676                 NULL, 0, "Connectionless mode mask", HFILL }},
17677
17678         { &hf_smb_search_id,
17679                 { "Search ID", "smb.search_id", FT_UINT16, BASE_HEX,
17680                 NULL, 0, "Search ID, handle for find operations", HFILL }},
17681
17682         { &hf_smb_write_mode_write_through,
17683                 { "Write Through", "smb.write.mode.write_through", FT_BOOLEAN, 16,
17684                 TFS(&tfs_write_mode_write_through), WRITE_MODE_WRITE_THROUGH, "Write through mode requested?", HFILL }},
17685
17686         { &hf_smb_write_mode_return_remaining,
17687                 { "Return Remaining", "smb.write.mode.return_remaining", FT_BOOLEAN, 16,
17688                 TFS(&tfs_write_mode_return_remaining), WRITE_MODE_RETURN_REMAINING, "Return remaining data responses?", HFILL }},
17689
17690         { &hf_smb_write_mode_raw,
17691                 { "Write Raw", "smb.write.mode.raw", FT_BOOLEAN, 16,
17692                 TFS(&tfs_write_mode_raw), WRITE_MODE_RAW, "Use WriteRawNamedPipe?", HFILL }},
17693
17694         { &hf_smb_write_mode_message_start,
17695                 { "Message Start", "smb.write.mode.message_start", FT_BOOLEAN, 16,
17696                 TFS(&tfs_write_mode_message_start), WRITE_MODE_MESSAGE_START, "Is this the start of a message?", HFILL }},
17697
17698         { &hf_smb_write_mode_connectionless,
17699                 { "Connectionless", "smb.write.mode.connectionless", FT_BOOLEAN, 16,
17700                 TFS(&tfs_write_mode_connectionless), WRITE_MODE_CONNECTIONLESS, "Connectionless mode requested?", HFILL }},
17701
17702         { &hf_smb_resume_key_len,
17703                 { "Resume Key Length", "smb.resume.key_len", FT_UINT16, BASE_DEC,
17704                 NULL, 0, "Resume Key length", HFILL }},
17705
17706         { &hf_smb_resume_find_id,
17707                 { "Find ID", "smb.resume.find_id", FT_UINT8, BASE_HEX,
17708                 NULL, 0, "Handle for Find operation", HFILL }},
17709
17710         { &hf_smb_resume_server_cookie,
17711                 { "Server Cookie", "smb.resume.server.cookie", FT_BYTES, BASE_HEX,
17712                 NULL, 0, "Cookie, must not be modified by the client", HFILL }},
17713
17714         { &hf_smb_resume_client_cookie,
17715                 { "Client Cookie", "smb.resume.client.cookie", FT_BYTES, BASE_HEX,
17716                 NULL, 0, "Cookie, must not be modified by the server", HFILL }},
17717
17718         { &hf_smb_andxoffset,
17719                 { "AndXOffset", "smb.andxoffset", FT_UINT16, BASE_DEC,
17720                 NULL, 0, "Offset to next command in this SMB packet", HFILL }},
17721
17722         { &hf_smb_lock_type_large,
17723                 { "Large Files", "smb.lock.type.large", FT_BOOLEAN, 8,
17724                 TFS(&tfs_lock_type_large), 0x10, "Large file locking requested?", HFILL }},
17725
17726         { &hf_smb_lock_type_cancel,
17727                 { "Cancel", "smb.lock.type.cancel", FT_BOOLEAN, 8,
17728                 TFS(&tfs_lock_type_cancel), 0x08, "Cancel outstanding lock requests?", HFILL }},
17729
17730         { &hf_smb_lock_type_change,
17731                 { "Change", "smb.lock.type.change", FT_BOOLEAN, 8,
17732                 TFS(&tfs_lock_type_change), 0x04, "Change type of lock?", HFILL }},
17733
17734         { &hf_smb_lock_type_oplock,
17735                 { "Oplock Break", "smb.lock.type.oplock_release", FT_BOOLEAN, 8,
17736                 TFS(&tfs_lock_type_oplock), 0x02, "Is this a notification of, or a response to, an oplock break?", HFILL }},
17737
17738         { &hf_smb_lock_type_shared,
17739                 { "Shared", "smb.lock.type.shared", FT_BOOLEAN, 8,
17740                 TFS(&tfs_lock_type_shared), 0x01, "Shared or exclusive lock requested?", HFILL }},
17741
17742         { &hf_smb_locking_ol,
17743                 { "Oplock Level", "smb.locking.oplock.level", FT_UINT8, BASE_DEC,
17744                 VALS(locking_ol_vals), 0, "Level of existing oplock at client (if any)", HFILL }},
17745
17746         { &hf_smb_number_of_locks,
17747                 { "Number of Locks", "smb.locking.num_locks", FT_UINT16, BASE_DEC,
17748                 NULL, 0, "Number of lock requests in this request", HFILL }},
17749
17750         { &hf_smb_number_of_unlocks,
17751                 { "Number of Unlocks", "smb.locking.num_unlocks", FT_UINT16, BASE_DEC,
17752                 NULL, 0, "Number of unlock requests in this request", HFILL }},
17753
17754         { &hf_smb_lock_long_length,
17755                 { "Length", "smb.lock.length", FT_STRING, BASE_DEC,
17756                 NULL, 0, "Length of lock/unlock region", HFILL }},
17757
17758         { &hf_smb_lock_long_offset,
17759                 { "Offset", "smb.lock.offset", FT_STRING, BASE_DEC,
17760                 NULL, 0, "Offset in the file of lock/unlock region", HFILL }},
17761
17762         { &hf_smb_file_type,
17763                 { "File Type", "smb.file_type", FT_UINT16, BASE_DEC,
17764                 VALS(filetype_vals), 0, "Type of file", HFILL }},
17765
17766         { &hf_smb_ipc_state_nonblocking,
17767                 { "Nonblocking", "smb.ipc_state.nonblocking", FT_BOOLEAN, 16,
17768                 TFS(&tfs_ipc_state_nonblocking), 0x8000, "Is I/O to this pipe nonblocking?", HFILL }},
17769
17770         { &hf_smb_ipc_state_endpoint,
17771                 { "Endpoint", "smb.ipc_state.endpoint", FT_UINT16, BASE_DEC,
17772                 VALS(ipc_state_endpoint_vals), 0x4000, "Which end of the pipe this is", HFILL }},
17773
17774         { &hf_smb_ipc_state_pipe_type,
17775                 { "Pipe Type", "smb.ipc_state.pipe_type", FT_UINT16, BASE_DEC,
17776                 VALS(ipc_state_pipe_type_vals), 0x0c00, "What type of pipe this is", HFILL }},
17777
17778         { &hf_smb_ipc_state_read_mode,
17779                 { "Read Mode", "smb.ipc_state.read_mode", FT_UINT16, BASE_DEC,
17780                 VALS(ipc_state_read_mode_vals), 0x0300, "How this pipe should be read", HFILL }},
17781
17782         { &hf_smb_ipc_state_icount,
17783                 { "Icount", "smb.ipc_state.icount", FT_UINT16, BASE_DEC,
17784                 NULL, 0x00FF, "Count to control pipe instancing", HFILL }},
17785
17786         { &hf_smb_server_fid,
17787                 { "Server FID", "smb.server_fid", FT_UINT32, BASE_HEX,
17788                 NULL, 0, "Server unique File ID", HFILL }},
17789
17790         { &hf_smb_open_flags_add_info,
17791                 { "Additional Info", "smb.open.flags.add_info", FT_BOOLEAN, 16,
17792                 TFS(&tfs_open_flags_add_info), 0x0001, "Additional Information Requested?", HFILL }},
17793
17794         { &hf_smb_open_flags_ex_oplock,
17795                 { "Exclusive Oplock", "smb.open.flags.ex_oplock", FT_BOOLEAN, 16,
17796                 TFS(&tfs_open_flags_ex_oplock), 0x0002, "Exclusive Oplock Requested?", HFILL }},
17797
17798         { &hf_smb_open_flags_batch_oplock,
17799                 { "Batch Oplock", "smb.open.flags.batch_oplock", FT_BOOLEAN, 16,
17800                 TFS(&tfs_open_flags_batch_oplock), 0x0004, "Batch Oplock Requested?", HFILL }},
17801
17802         { &hf_smb_open_flags_ealen,
17803                 { "Total EA Len", "smb.open.flags.ealen", FT_BOOLEAN, 16,
17804                 TFS(&tfs_open_flags_ealen), 0x0008, "Total EA Len Requested?", HFILL }},
17805
17806         { &hf_smb_open_action_open,
17807                 { "Open Action", "smb.open.action.open", FT_UINT16, BASE_DEC,
17808                 VALS(oa_open_vals), 0x0003, "Open Action, how the file was opened", HFILL }},
17809
17810         { &hf_smb_open_action_lock,
17811                 { "Exclusive Open", "smb.open.action.lock", FT_BOOLEAN, 16,
17812                 TFS(&tfs_oa_lock), 0x8000, "Is this file opened by another user?", HFILL }},
17813
17814         { &hf_smb_vc_num,
17815                 { "VC Number", "smb.vc", FT_UINT16, BASE_DEC,
17816                 NULL, 0, "VC Number", HFILL }},
17817
17818         { &hf_smb_password_len,
17819                 { "Password Length", "smb.pwlen", FT_UINT16, BASE_DEC,
17820                 NULL, 0, "Length of password", HFILL }},
17821
17822         { &hf_smb_ansi_password_len,
17823                 { "ANSI Password Length", "smb.ansi_pwlen", FT_UINT16, BASE_DEC,
17824                 NULL, 0, "Length of ANSI password", HFILL }},
17825
17826         { &hf_smb_unicode_password_len,
17827                 { "Unicode Password Length", "smb.unicode_pwlen", FT_UINT16, BASE_DEC,
17828                 NULL, 0, "Length of Unicode password", HFILL }},
17829
17830         { &hf_smb_account,
17831                 { "Account", "smb.account", FT_STRING, BASE_NONE,
17832                 NULL, 0, "Account, username", HFILL }},
17833
17834         { &hf_smb_os,
17835                 { "Native OS", "smb.native_os", FT_STRING, BASE_NONE,
17836                 NULL, 0, "Which OS we are running", HFILL }},
17837
17838         { &hf_smb_lanman,
17839                 { "Native LAN Manager", "smb.native_lanman", FT_STRING, BASE_NONE,
17840                 NULL, 0, "Which LANMAN protocol we are running", HFILL }},
17841
17842         { &hf_smb_setup_action_guest,
17843                 { "Guest", "smb.setup.action.guest", FT_BOOLEAN, 16,
17844                 TFS(&tfs_setup_action_guest), 0x0001, "Client logged in as GUEST?", HFILL }},
17845
17846         { &hf_smb_fs,
17847                 { "Native File System", "smb.native_fs", FT_STRING, BASE_NONE,
17848                 NULL, 0, "Native File System", HFILL }},
17849
17850         { &hf_smb_connect_flags_dtid,
17851                 { "Disconnect TID", "smb.connect.flags.dtid", FT_BOOLEAN, 16,
17852                 TFS(&tfs_disconnect_tid), 0x0001, "Disconnect TID?", HFILL }},
17853
17854         { &hf_smb_connect_support_search,
17855                 { "Search Bits", "smb.connect.support.search", FT_BOOLEAN, 16,
17856                 TFS(&tfs_connect_support_search), 0x0001, "Exclusive Search Bits supported?", HFILL }},
17857
17858         { &hf_smb_connect_support_in_dfs,
17859                 { "In Dfs", "smb.connect.support.dfs", FT_BOOLEAN, 16,
17860                 TFS(&tfs_connect_support_in_dfs), 0x0002, "Is this in a Dfs tree?", HFILL }},
17861
17862         { &hf_smb_max_setup_count,
17863                 { "Max Setup Count", "smb.msc", FT_UINT8, BASE_DEC,
17864                 NULL, 0, "Maximum number of setup words to return", HFILL }},
17865
17866         { &hf_smb_total_param_count,
17867                 { "Total Parameter Count", "smb.tpc", FT_UINT32, BASE_DEC,
17868                 NULL, 0, "Total number of parameter bytes", HFILL }},
17869
17870         { &hf_smb_total_data_count,
17871                 { "Total Data Count", "smb.tdc", FT_UINT32, BASE_DEC,
17872                 NULL, 0, "Total number of data bytes", HFILL }},
17873
17874         { &hf_smb_max_param_count,
17875                 { "Max Parameter Count", "smb.mpc", FT_UINT32, BASE_DEC,
17876                 NULL, 0, "Maximum number of parameter bytes to return", HFILL }},
17877
17878         { &hf_smb_max_data_count,
17879                 { "Max Data Count", "smb.mdc", FT_UINT32, BASE_DEC,
17880                 NULL, 0, "Maximum number of data bytes to return", HFILL }},
17881
17882         { &hf_smb_param_disp16,
17883                 { "Parameter Displacement", "smb.pd", FT_UINT16, BASE_DEC,
17884                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17885
17886         { &hf_smb_param_count16,
17887                 { "Parameter Count", "smb.pc", FT_UINT16, BASE_DEC,
17888                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17889
17890         { &hf_smb_param_offset16,
17891                 { "Parameter Offset", "smb.po", FT_UINT16, BASE_DEC,
17892                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17893
17894         { &hf_smb_param_disp32,
17895                 { "Parameter Displacement", "smb.pd", FT_UINT32, BASE_DEC,
17896                 NULL, 0, "Displacement of these parameter bytes", HFILL }},
17897
17898         { &hf_smb_param_count32,
17899                 { "Parameter Count", "smb.pc", FT_UINT32, BASE_DEC,
17900                 NULL, 0, "Number of parameter bytes in this buffer", HFILL }},
17901
17902         { &hf_smb_param_offset32,
17903                 { "Parameter Offset", "smb.po", FT_UINT32, BASE_DEC,
17904                 NULL, 0, "Offset (from header start) to parameters", HFILL }},
17905
17906         { &hf_smb_data_count16,
17907                 { "Data Count", "smb.dc", FT_UINT16, BASE_DEC,
17908                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17909
17910         { &hf_smb_data_disp16,
17911                 { "Data Displacement", "smb.data_disp", FT_UINT16, BASE_DEC,
17912                 NULL, 0, "Data Displacement", HFILL }},
17913
17914         { &hf_smb_data_offset16,
17915                 { "Data Offset", "smb.data_offset", FT_UINT16, BASE_DEC,
17916                 NULL, 0, "Data Offset", HFILL }},
17917
17918         { &hf_smb_data_count32,
17919                 { "Data Count", "smb.dc", FT_UINT32, BASE_DEC,
17920                 NULL, 0, "Number of data bytes in this buffer", HFILL }},
17921
17922         { &hf_smb_data_disp32,
17923                 { "Data Displacement", "smb.data_disp", FT_UINT32, BASE_DEC,
17924                 NULL, 0, "Data Displacement", HFILL }},
17925
17926         { &hf_smb_data_offset32,
17927                 { "Data Offset", "smb.data_offset", FT_UINT32, BASE_DEC,
17928                 NULL, 0, "Data Offset", HFILL }},
17929
17930         { &hf_smb_setup_count,
17931                 { "Setup Count", "smb.sc", FT_UINT8, BASE_DEC,
17932                 NULL, 0, "Number of setup words in this buffer", HFILL }},
17933
17934         { &hf_smb_nt_trans_subcmd,
17935                 { "Function", "smb.nt.function", FT_UINT16, BASE_DEC,
17936                 VALS(nt_cmd_vals), 0, "Function for NT Transaction", HFILL }},
17937
17938         { &hf_smb_nt_ioctl_function_code,
17939                 { "Function", "smb.nt.ioctl.function", FT_UINT32, BASE_HEX,
17940                 NULL, 0, "NT IOCTL function code", HFILL }},
17941
17942         { &hf_smb_nt_ioctl_isfsctl,
17943                 { "IsFSctl", "smb.nt.ioctl.isfsctl", FT_UINT8, BASE_DEC,
17944                 VALS(nt_ioctl_isfsctl_vals), 0, "Is this a device IOCTL (FALSE) or FS Control (TRUE)", HFILL }},
17945
17946         { &hf_smb_nt_ioctl_flags_root_handle,
17947                 { "Root Handle", "smb.nt.ioctl.flags.root_handle", FT_BOOLEAN, 8,
17948                 TFS(&tfs_nt_ioctl_flags_root_handle), NT_IOCTL_FLAGS_ROOT_HANDLE, "Apply to this share or root Dfs share", HFILL }},
17949
17950         { &hf_smb_nt_ioctl_data,
17951                 { "IOCTL Data", "smb.nt.ioctl.data", FT_BYTES, BASE_HEX,
17952                 NULL, 0, "Data for the IOCTL call", HFILL }},
17953
17954         { &hf_smb_nt_notify_action,
17955                 { "Action", "smb.nt.notify.action", FT_UINT32, BASE_DEC,
17956                 VALS(nt_notify_action_vals), 0, "Which action caused this notify response", HFILL }},
17957
17958         { &hf_smb_nt_notify_watch_tree,
17959                 { "Watch Tree", "smb.nt.notify.watch_tree", FT_UINT8, BASE_DEC,
17960                 VALS(watch_tree_vals), 0, "Should Notify watch subdirectories also?", HFILL }},
17961
17962         { &hf_smb_nt_notify_stream_write,
17963                 { "Stream Write", "smb.nt.notify.stream_write", FT_BOOLEAN, 32,
17964                 TFS(&tfs_nt_notify_stream_write), NT_NOTIFY_STREAM_WRITE, "Notify on stream write?", HFILL }},
17965
17966         { &hf_smb_nt_notify_stream_size,
17967                 { "Stream Size Change", "smb.nt.notify.stream_size", FT_BOOLEAN, 32,
17968                 TFS(&tfs_nt_notify_stream_size), NT_NOTIFY_STREAM_SIZE, "Notify on changes of stream size", HFILL }},
17969
17970         { &hf_smb_nt_notify_stream_name,
17971                 { "Stream Name Change", "smb.nt.notify.stream_name", FT_BOOLEAN, 32,
17972                 TFS(&tfs_nt_notify_stream_name), NT_NOTIFY_STREAM_NAME, "Notify on changes to stream name?", HFILL }},
17973
17974         { &hf_smb_nt_notify_security,
17975                 { "Security Change", "smb.nt.notify.security", FT_BOOLEAN, 32,
17976                 TFS(&tfs_nt_notify_security), NT_NOTIFY_SECURITY, "Notify on changes to security settings", HFILL }},
17977
17978         { &hf_smb_nt_notify_ea,
17979                 { "EA Change", "smb.nt.notify.ea", FT_BOOLEAN, 32,
17980                 TFS(&tfs_nt_notify_ea), NT_NOTIFY_EA, "Notify on changes to Extended Attributes", HFILL }},
17981
17982         { &hf_smb_nt_notify_creation,
17983                 { "Created Change", "smb.nt.notify.creation", FT_BOOLEAN, 32,
17984                 TFS(&tfs_nt_notify_creation), NT_NOTIFY_CREATION, "Notify on changes to creation time", HFILL }},
17985
17986         { &hf_smb_nt_notify_last_access,
17987                 { "Last Access Change", "smb.nt.notify.last_access", FT_BOOLEAN, 32,
17988                 TFS(&tfs_nt_notify_last_access), NT_NOTIFY_LAST_ACCESS, "Notify on changes to last access", HFILL }},
17989
17990         { &hf_smb_nt_notify_last_write,
17991                 { "Last Write Change", "smb.nt.notify.last_write", FT_BOOLEAN, 32,
17992                 TFS(&tfs_nt_notify_last_write), NT_NOTIFY_LAST_WRITE, "Notify on changes to last write", HFILL }},
17993
17994         { &hf_smb_nt_notify_size,
17995                 { "Size Change", "smb.nt.notify.size", FT_BOOLEAN, 32,
17996                 TFS(&tfs_nt_notify_size), NT_NOTIFY_SIZE, "Notify on changes to size", HFILL }},
17997
17998         { &hf_smb_nt_notify_attributes,
17999                 { "Attribute Change", "smb.nt.notify.attributes", FT_BOOLEAN, 32,
18000                 TFS(&tfs_nt_notify_attributes), NT_NOTIFY_ATTRIBUTES, "Notify on changes to attributes", HFILL }},
18001
18002         { &hf_smb_nt_notify_dir_name,
18003                 { "Directory Name Change", "smb.nt.notify.dir_name", FT_BOOLEAN, 32,
18004                 TFS(&tfs_nt_notify_dir_name), NT_NOTIFY_DIR_NAME, "Notify on changes to directory name", HFILL }},
18005
18006         { &hf_smb_nt_notify_file_name,
18007                 { "File Name Change", "smb.nt.notify.file_name", FT_BOOLEAN, 32,
18008                 TFS(&tfs_nt_notify_file_name), NT_NOTIFY_FILE_NAME, "Notify on changes to file name", HFILL }},
18009
18010         { &hf_smb_root_dir_fid,
18011                 { "Root FID", "smb.rfid", FT_UINT32, BASE_HEX,
18012                 NULL, 0, "Open is relative to this FID (if nonzero)", HFILL }},
18013
18014         { &hf_smb_alloc_size64,
18015                 { "Allocation Size", "smb.alloc_size", FT_UINT64, BASE_DEC,
18016                 NULL, 0, "Number of bytes to reserve on create or truncate", HFILL }},
18017
18018         { &hf_smb_nt_create_disposition,
18019                 { "Disposition", "smb.create.disposition", FT_UINT32, BASE_DEC,
18020                 VALS(create_disposition_vals), 0, "Create disposition, what to do if the file does/does not exist", HFILL }},
18021
18022         { &hf_smb_sd_length,
18023                 { "SD Length", "smb.sd.length", FT_UINT32, BASE_DEC,
18024                 NULL, 0, "Total length of security descriptor", HFILL }},
18025
18026         { &hf_smb_ea_list_length,
18027                 { "EA List Length", "smb.ea.list_length", FT_UINT32, BASE_DEC,
18028                 NULL, 0, "Total length of extended attributes", HFILL }},
18029
18030         { &hf_smb_ea_flags,
18031                 { "EA Flags", "smb.ea.flags", FT_UINT8, BASE_HEX,
18032                 NULL, 0, "EA Flags", HFILL }},
18033
18034         { &hf_smb_ea_name_length,
18035                 { "EA Name Length", "smb.ea.name_length", FT_UINT8, BASE_DEC,
18036                 NULL, 0, "EA Name Length", HFILL }},
18037
18038         { &hf_smb_ea_data_length,
18039                 { "EA Data Length", "smb.ea.data_length", FT_UINT16, BASE_DEC,
18040                 NULL, 0, "EA Data Length", HFILL }},
18041
18042         { &hf_smb_ea_name,
18043                 { "EA Name", "smb.ea.name", FT_STRING, BASE_NONE,
18044                 NULL, 0, "EA Name", HFILL }},
18045
18046         { &hf_smb_ea_data,
18047                 { "EA Data", "smb.ea.data", FT_BYTES, BASE_NONE,
18048                 NULL, 0, "EA Data", HFILL }},
18049
18050         { &hf_smb_file_name_len,
18051                 { "File Name Len", "smb.file_name_len", FT_UINT32, BASE_DEC,
18052                 NULL, 0, "Length of File Name", HFILL }},
18053
18054         { &hf_smb_nt_impersonation_level,
18055                 { "Impersonation", "smb.impersonation.level", FT_UINT32, BASE_DEC,
18056                 VALS(impersonation_level_vals), 0, "Impersonation level", HFILL }},
18057
18058         { &hf_smb_nt_security_flags_context_tracking,
18059                 { "Context Tracking", "smb.security.flags.context_tracking", FT_BOOLEAN, 8,
18060                 TFS(&tfs_nt_security_flags_context_tracking), 0x01, "Is security tracking static or dynamic?", HFILL }},
18061
18062         { &hf_smb_nt_security_flags_effective_only,
18063                 { "Effective Only", "smb.security.flags.effective_only", FT_BOOLEAN, 8,
18064                 TFS(&tfs_nt_security_flags_effective_only), 0x02, "Are only enabled or all aspects uf the users SID available?", HFILL }},
18065
18066         { &hf_smb_nt_access_mask_generic_read,
18067                 { "Generic Read", "smb.access.generic_read", FT_BOOLEAN, 32,
18068                 TFS(&tfs_nt_access_mask_generic_read), 0x80000000, "Is generic read allowed for this object?", HFILL }},
18069
18070         { &hf_smb_nt_access_mask_generic_write,
18071                 { "Generic Write", "smb.access.generic_write", FT_BOOLEAN, 32,
18072                 TFS(&tfs_nt_access_mask_generic_write), 0x40000000, "Is generic write allowed for this object?", HFILL }},
18073
18074         { &hf_smb_nt_access_mask_generic_execute,
18075                 { "Generic Execute", "smb.access.generic_execute", FT_BOOLEAN, 32,
18076                 TFS(&tfs_nt_access_mask_generic_execute), 0x20000000, "Is generic execute allowed for this object?", HFILL }},
18077
18078         { &hf_smb_nt_access_mask_generic_all,
18079                 { "Generic All", "smb.access.generic_all", FT_BOOLEAN, 32,
18080                 TFS(&tfs_nt_access_mask_generic_all), 0x10000000, "Is generic all allowed for this attribute", HFILL }},
18081
18082         { &hf_smb_nt_access_mask_maximum_allowed,
18083                 { "Maximum Allowed", "smb.access.maximum_allowed", FT_BOOLEAN, 32,
18084                 TFS(&tfs_nt_access_mask_maximum_allowed), 0x02000000, "?", HFILL }},
18085
18086         { &hf_smb_nt_access_mask_system_security,
18087                 { "System Security", "smb.access.system_security", FT_BOOLEAN, 32,
18088                 TFS(&tfs_nt_access_mask_system_security), 0x01000000, "Access to a system ACL?", HFILL }},
18089
18090         { &hf_smb_nt_access_mask_synchronize,
18091                 { "Synchronize", "smb.access.synchronize", FT_BOOLEAN, 32,
18092                 TFS(&tfs_nt_access_mask_synchronize), 0x00100000, "Windows NT: synchronize access", HFILL }},
18093
18094         { &hf_smb_nt_access_mask_write_owner,
18095                 { "Write Owner", "smb.access.write_owner", FT_BOOLEAN, 32,
18096                 TFS(&tfs_nt_access_mask_write_owner), 0x00080000, "Can owner write to the object?", HFILL }},
18097
18098         { &hf_smb_nt_access_mask_write_dac,
18099                 { "Write DAC", "smb.access.write_dac", FT_BOOLEAN, 32,
18100                 TFS(&tfs_nt_access_mask_write_dac), 0x00040000, "Is write allowed to the owner group or ACLs?", HFILL }},
18101
18102         { &hf_smb_nt_access_mask_read_control,
18103                 { "Read Control", "smb.access.read_control", FT_BOOLEAN, 32,
18104                 TFS(&tfs_nt_access_mask_read_control), 0x00020000, "Are reads allowed of owner, group and ACL data of the SID?", HFILL }},
18105
18106         { &hf_smb_nt_access_mask_delete,
18107                 { "Delete", "smb.access.delete", FT_BOOLEAN, 32,
18108                 TFS(&tfs_nt_access_mask_delete), 0x00010000, "Can object be deleted", HFILL }},
18109
18110         { &hf_smb_nt_access_mask_write_attributes,
18111                 { "Write Attributes", "smb.access.write_attributes", FT_BOOLEAN, 32,
18112                 TFS(&tfs_nt_access_mask_write_attributes), 0x00000100, "Can object's attributes be written", HFILL }},
18113
18114         { &hf_smb_nt_access_mask_read_attributes,
18115                 { "Read Attributes", "smb.access.read_attributes", FT_BOOLEAN, 32,
18116                 TFS(&tfs_nt_access_mask_read_attributes), 0x00000080, "Can object's attributes be read", HFILL }},
18117
18118         { &hf_smb_nt_access_mask_delete_child,
18119                 { "Delete Child", "smb.access.delete_child", FT_BOOLEAN, 32,
18120                 TFS(&tfs_nt_access_mask_delete_child), 0x00000040, "Can object's subdirectories be deleted", HFILL }},
18121
18122         /*
18123          * "Execute" for files, "traverse" for directories.
18124          */
18125         { &hf_smb_nt_access_mask_execute,
18126                 { "Execute", "smb.access.execute", FT_BOOLEAN, 32,
18127                 TFS(&tfs_nt_access_mask_execute), 0x00000020, "Can object be executed (if file) or traversed (if directory)", HFILL }},
18128
18129         { &hf_smb_nt_access_mask_write_ea,
18130                 { "Write EA", "smb.access.write_ea", FT_BOOLEAN, 32,
18131                 TFS(&tfs_nt_access_mask_write_ea), 0x00000010, "Can object's extended attributes be written", HFILL }},
18132
18133         { &hf_smb_nt_access_mask_read_ea,
18134                 { "Read EA", "smb.access.read_ea", FT_BOOLEAN, 32,
18135                 TFS(&tfs_nt_access_mask_read_ea), 0x00000008, "Can object's extended attributes be read", HFILL }},
18136
18137         /*
18138          * "Append data" for files, "add subdirectory" for directories,
18139          * "create pipe instance" for named pipes.
18140          */
18141         { &hf_smb_nt_access_mask_append,
18142                 { "Append", "smb.access.append", FT_BOOLEAN, 32,
18143                 TFS(&tfs_nt_access_mask_append), 0x00000004, "Can object's contents be appended to", HFILL }},
18144
18145         /*
18146          * "Write data" for files and pipes, "add file" for directory.
18147          */
18148         { &hf_smb_nt_access_mask_write,
18149                 { "Write", "smb.access.write", FT_BOOLEAN, 32,
18150                 TFS(&tfs_nt_access_mask_write), 0x00000002, "Can object's contents be written", HFILL }},
18151
18152         /*
18153          * "Read data" for files and pipes, "list directory" for directory.
18154          */
18155         { &hf_smb_nt_access_mask_read,
18156                 { "Read", "smb.access.read", FT_BOOLEAN, 32,
18157                 TFS(&tfs_nt_access_mask_read), 0x00000001, "Can object's contents be read", HFILL }},
18158
18159         { &hf_smb_nt_create_bits_oplock,
18160                 { "Exclusive Oplock", "smb.nt.create.oplock", FT_BOOLEAN, 32,
18161                 TFS(&tfs_nt_create_bits_oplock), 0x00000002, "Is an oplock requested", HFILL }},
18162
18163         { &hf_smb_nt_create_bits_boplock,
18164                 { "Batch Oplock", "smb.nt.create.batch_oplock", FT_BOOLEAN, 32,
18165                 TFS(&tfs_nt_create_bits_boplock), 0x00000004, "Is a batch oplock requested?", HFILL }},
18166
18167         { &hf_smb_nt_create_bits_dir,
18168                 { "Create Directory", "smb.nt.create.dir", FT_BOOLEAN, 32,
18169                 TFS(&tfs_nt_create_bits_dir), 0x00000008, "Must target of open be a directory?", HFILL }},
18170
18171         { &hf_smb_nt_create_bits_ext_resp,
18172           { "Extended Response", "smb.nt.create.ext", FT_BOOLEAN, 32, 
18173             TFS(&tfs_nt_create_bits_ext_resp), 0x00000010, "Extended response required?", HFILL }},
18174
18175         { &hf_smb_nt_create_options_directory_file,
18176                 { "Directory", "smb.nt.create_options.directory", FT_BOOLEAN, 32,
18177                 TFS(&tfs_nt_create_options_directory), 0x00000001, "Should file being opened/created be a directory?", HFILL }},
18178
18179         { &hf_smb_nt_create_options_write_through,
18180                 { "Write Through", "smb.nt.create_options.write_through", FT_BOOLEAN, 32,
18181                 TFS(&tfs_nt_create_options_write_through), 0x00000002, "Should writes to the file write buffered data out before completing?", HFILL }},
18182
18183         { &hf_smb_nt_create_options_sequential_only,
18184                 { "Sequential Only", "smb.nt.create_options.sequential_only", FT_BOOLEAN, 32,
18185                 TFS(&tfs_nt_create_options_sequential_only), 0x00000004, "Will accees to thsis file only be sequential?", HFILL }},
18186
18187         { &hf_smb_nt_create_options_sync_io_alert,
18188                 { "Sync I/O Alert", "smb.nt.create_options.sync_io_alert", FT_BOOLEAN, 32,
18189                 TFS(&tfs_nt_create_options_sync_io_alert), 0x00000010, "All operations are performed synchronous", HFILL}},
18190
18191         { &hf_smb_nt_create_options_sync_io_nonalert,
18192                 { "Sync I/O Nonalert", "smb.nt.create_options.sync_io_nonalert", FT_BOOLEAN, 32,
18193                 TFS(&tfs_nt_create_options_sync_io_nonalert), 0x00000020, "All operations are synchronous and may block", HFILL}},
18194
18195         { &hf_smb_nt_create_options_non_directory_file,
18196                 { "Non-Directory", "smb.nt.create_options.non_directory", FT_BOOLEAN, 32,
18197                 TFS(&tfs_nt_create_options_non_directory), 0x00000040, "Should file being opened/created be a non-directory?", HFILL }},
18198
18199         /* 0x00000080 is "tree connect", at least in "NtCreateFile()"
18200            and "NtOpenFile()"; is that sent over the wire?  Network
18201            Monitor thinks so, but its author may just have grabbed
18202            the flag bits from a system header file. */
18203
18204         /* 0x00000100 is "complete if oplocked", at least in "NtCreateFile()"
18205            and "NtOpenFile()"; is that sent over the wire?  NetMon
18206            thinks so, but see previous comment. */
18207
18208         { &hf_smb_nt_create_options_no_ea_knowledge,
18209                 { "No EA Knowledge", "smb.nt.create_options.no_ea_knowledge", FT_BOOLEAN, 32,
18210                 TFS(&tfs_nt_create_options_no_ea_knowledge), 0x00000200, "Does the client not understand extended attributes?", HFILL }},
18211
18212         { &hf_smb_nt_create_options_eight_dot_three_only,
18213                 { "8.3 Only", "smb.nt.create_options.eight_dot_three_only", FT_BOOLEAN, 32,
18214                 TFS(&tfs_nt_create_options_eight_dot_three_only), 0x00000400, "Does the client understand only 8.3 filenames?", HFILL }},
18215
18216         { &hf_smb_nt_create_options_random_access,
18217                 { "Random Access", "smb.nt.create_options.random_access", FT_BOOLEAN, 32,
18218                 TFS(&tfs_nt_create_options_random_access), 0x00000800, "Will the client be accessing the file randomly?", HFILL }},
18219
18220         { &hf_smb_nt_create_options_delete_on_close,
18221                 { "Delete On Close", "smb.nt.create_options.delete_on_close", FT_BOOLEAN, 32,
18222                 TFS(&tfs_nt_create_options_delete_on_close), 0x00001000, "Should the file be deleted when closed?", HFILL }},
18223
18224         /* 0x00002000 is "open by FID", or something such as that (which
18225            I suspect is like "open by inumber" on UNIX), at least in
18226            "NtCreateFile()" and "NtOpenFile()"; is that sent over the
18227            wire?  NetMon thinks so, but see previous comment. */
18228
18229         /* 0x00004000 is "open for backup", at least in "NtCreateFile()"
18230            and "NtOpenFile()"; is that sent over the wire?  NetMon
18231            thinks so, but see previous comment. */
18232
18233         { &hf_smb_nt_share_access_read,
18234                 { "Read", "smb.share.access.read", FT_BOOLEAN, 32,
18235                 TFS(&tfs_nt_share_access_read), 0x00000001, "Can the object be shared for reading?", HFILL }},
18236
18237         { &hf_smb_nt_share_access_write,
18238                 { "Write", "smb.share.access.write", FT_BOOLEAN, 32,
18239                 TFS(&tfs_nt_share_access_write), 0x00000002, "Can the object be shared for write?", HFILL }},
18240
18241         { &hf_smb_nt_share_access_delete,
18242                 { "Delete", "smb.share.access.delete", FT_BOOLEAN, 32,
18243                 TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
18244
18245         { &hf_smb_file_eattr_read_only,
18246                 { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
18247                 TFS(&tfs_file_attribute_read_only), SMB_FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
18248
18249         { &hf_smb_file_eattr_hidden,
18250                 { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
18251                 TFS(&tfs_file_attribute_hidden), SMB_FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
18252
18253         { &hf_smb_file_eattr_system,
18254                 { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
18255                 TFS(&tfs_file_attribute_system), SMB_FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
18256
18257         { &hf_smb_file_eattr_volume,
18258                 { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
18259                 TFS(&tfs_file_attribute_volume), SMB_FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
18260
18261         { &hf_smb_file_eattr_directory,
18262                 { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
18263                 TFS(&tfs_file_attribute_directory), SMB_FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
18264
18265         { &hf_smb_file_eattr_archive,
18266                 { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
18267                 TFS(&tfs_file_attribute_archive), SMB_FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
18268
18269         { &hf_smb_file_eattr_device,
18270                 { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
18271                 TFS(&tfs_file_attribute_device), SMB_FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
18272
18273         { &hf_smb_file_eattr_normal,
18274                 { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
18275                 TFS(&tfs_file_attribute_normal), SMB_FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
18276
18277         { &hf_smb_file_eattr_temporary,
18278                 { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
18279                 TFS(&tfs_file_attribute_temporary), SMB_FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
18280
18281         { &hf_smb_file_eattr_sparse,
18282                 { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
18283                 TFS(&tfs_file_attribute_sparse), SMB_FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
18284
18285         { &hf_smb_file_eattr_reparse,
18286                 { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
18287                 TFS(&tfs_file_attribute_reparse), SMB_FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
18288
18289         { &hf_smb_file_eattr_compressed,
18290                 { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
18291                 TFS(&tfs_file_attribute_compressed), SMB_FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
18292
18293         { &hf_smb_file_eattr_offline,
18294                 { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
18295                 TFS(&tfs_file_attribute_offline), SMB_FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
18296
18297         { &hf_smb_file_eattr_not_content_indexed,
18298                 { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
18299                 TFS(&tfs_file_attribute_not_content_indexed), SMB_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
18300
18301         { &hf_smb_file_eattr_encrypted,
18302                 { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
18303                 TFS(&tfs_file_attribute_encrypted), SMB_FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
18304
18305         { &hf_smb_sec_desc_len,
18306                 { "NT Security Descriptor Length", "smb.sec_desc_len", FT_UINT32, BASE_DEC,
18307                 NULL, 0, "Security Descriptor Length", HFILL }},
18308
18309         { &hf_smb_nt_qsd_owner,
18310                 { "Owner", "smb.nt_qsd.owner", FT_BOOLEAN, 32,
18311                 TFS(&tfs_nt_qsd_owner), NT_QSD_OWNER, "Is owner security informaton being queried?", HFILL }},
18312
18313         { &hf_smb_nt_qsd_group,
18314                 { "Group", "smb.nt_qsd.group", FT_BOOLEAN, 32,
18315                 TFS(&tfs_nt_qsd_group), NT_QSD_GROUP, "Is group security informaton being queried?", HFILL }},
18316
18317         { &hf_smb_nt_qsd_dacl,
18318                 { "DACL", "smb.nt_qsd.dacl", FT_BOOLEAN, 32,
18319                 TFS(&tfs_nt_qsd_dacl), NT_QSD_DACL, "Is DACL security informaton being queried?", HFILL }},
18320
18321         { &hf_smb_nt_qsd_sacl,
18322                 { "SACL", "smb.nt_qsd.sacl", FT_BOOLEAN, 32,
18323                 TFS(&tfs_nt_qsd_sacl), NT_QSD_SACL, "Is SACL security informaton being queried?", HFILL }},
18324
18325         { &hf_smb_extended_attributes,
18326                 { "Extended Attributes", "smb.ext_attr", FT_BYTES, BASE_HEX,
18327                 NULL, 0, "Extended Attributes", HFILL }},
18328
18329         { &hf_smb_oplock_level,
18330                 { "Oplock level", "smb.oplock.level", FT_UINT8, BASE_DEC,
18331                 VALS(oplock_level_vals), 0, "Level of oplock granted", HFILL }},
18332
18333         { &hf_smb_create_action,
18334                 { "Create action", "smb.create.action", FT_UINT32, BASE_DEC,
18335                 VALS(oa_open_vals), 0, "Type of action taken", HFILL }},
18336
18337         { &hf_smb_file_id,
18338                 { "Server unique file ID", "smb.create.file_id", FT_UINT32, BASE_HEX,
18339                 NULL, 0, "Server unique file ID", HFILL }},
18340
18341         { &hf_smb_ea_error_offset,
18342                 { "EA Error offset", "smb.ea.error_offset", FT_UINT32, BASE_DEC,
18343                 NULL, 0, "Offset into EA list if EA error", HFILL }},
18344
18345         { &hf_smb_end_of_file,
18346                 { "End Of File", "smb.end_of_file", FT_UINT64, BASE_DEC,
18347                 NULL, 0, "Offset to the first free byte in the file", HFILL }},
18348
18349         { &hf_smb_replace,
18350                 { "Replace", "smb.replace", FT_BOOLEAN, BASE_NONE,
18351                 TFS(&tfs_smb_replace), 0x0, "Remove target if it exists?", HFILL }},
18352
18353         { &hf_smb_root_dir_handle,
18354                 { "Root Directory Handle", "smb.root_dir_handle", FT_UINT32, BASE_HEX,
18355                 NULL, 0, "Root directory handle", HFILL }},
18356
18357         { &hf_smb_target_name_len,
18358                 { "Target name length", "smb.target_name_len", FT_UINT32, BASE_DEC,
18359                 NULL, 0, "Length of target file name", HFILL }},
18360
18361         { &hf_smb_target_name,
18362                 { "Target name", "smb.target_name", FT_STRING, BASE_NONE,
18363                 NULL, 0, "Target file name", HFILL }},
18364
18365         { &hf_smb_device_type,
18366                 { "Device Type", "smb.device.type", FT_UINT32, BASE_HEX,
18367                 VALS(device_type_vals), 0, "Type of device", HFILL }},
18368
18369         { &hf_smb_is_directory,
18370                 { "Is Directory", "smb.is_directory", FT_UINT8, BASE_DEC,
18371                 VALS(is_directory_vals), 0, "Is this object a directory?", HFILL }},
18372
18373         { &hf_smb_next_entry_offset,
18374                 { "Next Entry Offset", "smb.next_entry_offset", FT_UINT32, BASE_DEC,
18375                 NULL, 0, "Offset to next entry", HFILL }},
18376
18377         { &hf_smb_change_time,
18378                 { "Change", "smb.change.time", FT_ABSOLUTE_TIME, BASE_NONE,
18379                 NULL, 0, "Last Change Time", HFILL }},
18380
18381         { &hf_smb_setup_len,
18382                 { "Setup Len", "smb.print.setup.len", FT_UINT16, BASE_DEC,
18383                 NULL, 0, "Length of printer setup data", HFILL }},
18384
18385         { &hf_smb_print_mode,
18386                 { "Mode", "smb.print.mode", FT_UINT16, BASE_DEC,
18387                 VALS(print_mode_vals), 0, "Text or Graphics mode", HFILL }},
18388
18389         { &hf_smb_print_identifier,
18390                 { "Identifier", "smb.print.identifier", FT_STRING, BASE_NONE,
18391                 NULL, 0, "Identifier string for this print job", HFILL }},
18392
18393         { &hf_smb_restart_index,
18394                 { "Restart Index", "smb.print.restart_index", FT_UINT16, BASE_DEC,
18395                 NULL, 0, "Index of entry after last returned", HFILL }},
18396
18397         { &hf_smb_print_queue_date,
18398                 { "Queued", "smb.print.queued.date", FT_ABSOLUTE_TIME, BASE_NONE,
18399                 NULL, 0, "Date when this entry was queued", HFILL }},
18400
18401         { &hf_smb_print_queue_dos_date,
18402                 { "Queued Date", "smb.print.queued.smb.date", FT_UINT16, BASE_HEX,
18403                 NULL, 0, "Date when this print job was queued, SMB_DATE format", HFILL }},
18404
18405         { &hf_smb_print_queue_dos_time,
18406                 { "Queued Time", "smb.print.queued.smb.time", FT_UINT16, BASE_HEX,
18407                 NULL, 0, "Time when this print job was queued, SMB_TIME format", HFILL }},
18408
18409         { &hf_smb_print_status,
18410                 { "Status", "smb.print.status", FT_UINT8, BASE_HEX,
18411                 VALS(print_status_vals), 0, "Status of this entry", HFILL }},
18412
18413         { &hf_smb_print_spool_file_number,
18414                 { "Spool File Number", "smb.print.spool.file_number", FT_UINT16, BASE_DEC,
18415                 NULL, 0, "Spool File Number, assigned by the spooler", HFILL }},
18416
18417         { &hf_smb_print_spool_file_size,
18418                 { "Spool File Size", "smb.print.spool.file_size", FT_UINT32, BASE_DEC,
18419                 NULL, 0, "Number of bytes in spool file", HFILL }},
18420
18421         { &hf_smb_print_spool_file_name,
18422                 { "Name", "smb.print.spool.name", FT_BYTES, BASE_HEX,
18423                 NULL, 0, "Name of client that submitted this job", HFILL }},
18424
18425         { &hf_smb_start_index,
18426                 { "Start Index", "smb.print.start_index", FT_UINT16, BASE_DEC,
18427                 NULL, 0, "First queue entry to return", HFILL }},
18428
18429         { &hf_smb_originator_name,
18430                 { "Originator Name", "smb.originator_name", FT_STRINGZ, BASE_NONE,
18431                 NULL, 0, "Name of sender of message", HFILL }},
18432
18433         { &hf_smb_destination_name,
18434                 { "Destination Name", "smb.destination_name", FT_STRINGZ, BASE_NONE,
18435                 NULL, 0, "Name of recipient of message", HFILL }},
18436
18437         { &hf_smb_message_len,
18438                 { "Message Len", "smb.message.len", FT_UINT16, BASE_DEC,
18439                 NULL, 0, "Length of message", HFILL }},
18440
18441         { &hf_smb_message,
18442                 { "Message", "smb.message", FT_STRING, BASE_NONE,
18443                 NULL, 0, "Message text", HFILL }},
18444
18445         { &hf_smb_mgid,
18446                 { "Message Group ID", "smb.mgid", FT_UINT16, BASE_DEC,
18447                 NULL, 0, "Message group ID for multi-block messages", HFILL }},
18448
18449         { &hf_smb_forwarded_name,
18450                 { "Forwarded Name", "smb.forwarded_name", FT_STRINGZ, BASE_NONE,
18451                 NULL, 0, "Recipient name being forwarded", HFILL }},
18452
18453         { &hf_smb_machine_name,
18454                 { "Machine Name", "smb.machine_name", FT_STRINGZ, BASE_NONE,
18455                 NULL, 0, "Name of target machine", HFILL }},
18456
18457         { &hf_smb_cancel_to,
18458                 { "Cancel to", "smb.cancel_to", FT_FRAMENUM, BASE_NONE,
18459                 NULL, 0, "This packet is a cancellation of the packet in this frame", HFILL }},
18460
18461         { &hf_smb_trans2_subcmd,
18462                 { "Subcommand", "smb.trans2.cmd", FT_UINT16, BASE_HEX,
18463                 VALS(trans2_cmd_vals), 0, "Subcommand for TRANSACTION2", HFILL }},
18464
18465         { &hf_smb_trans_name,
18466                 { "Transaction Name", "smb.trans_name", FT_STRING, BASE_NONE,
18467                 NULL, 0, "Name of transaction", HFILL }},
18468
18469         { &hf_smb_transaction_flags_dtid,
18470                 { "Disconnect TID", "smb.transaction.flags.dtid", FT_BOOLEAN, 16,
18471                 TFS(&tfs_tf_dtid), 0x0001, "Disconnect TID?", HFILL }},
18472
18473         { &hf_smb_transaction_flags_owt,
18474                 { "One Way Transaction", "smb.transaction.flags.owt", FT_BOOLEAN, 16,
18475                 TFS(&tfs_tf_owt), 0x0002, "One Way Transaction (no response)?", HFILL }},
18476
18477         { &hf_smb_search_count,
18478                 { "Search Count", "smb.search_count", FT_UINT16, BASE_DEC,
18479                 NULL, 0, "Maximum number of search entries to return", HFILL }},
18480
18481         { &hf_smb_search_pattern,
18482                 { "Search Pattern", "smb.search_pattern", FT_STRING, BASE_NONE,
18483                 NULL, 0, "Search Pattern", HFILL }},
18484
18485         { &hf_smb_ff2_backup,
18486                 { "Backup Intent", "smb.find_first2.flags.backup", FT_BOOLEAN, 16,
18487                 TFS(&tfs_ff2_backup), 0x0010, "Find with backup intent", HFILL }},
18488
18489         { &hf_smb_ff2_continue,
18490                 { "Continue", "smb.find_first2.flags.continue", FT_BOOLEAN, 16,
18491                 TFS(&tfs_ff2_continue), 0x0008, "Continue search from previous ending place", HFILL }},
18492
18493         { &hf_smb_ff2_resume,
18494                 { "Resume", "smb.find_first2.flags.resume", FT_BOOLEAN, 16,
18495                 TFS(&tfs_ff2_resume), FF2_RESUME, "Return resume keys for each entry found", HFILL }},
18496
18497         { &hf_smb_ff2_close_eos,
18498                 { "Close on EOS", "smb.find_first2.flags.eos", FT_BOOLEAN, 16,
18499                 TFS(&tfs_ff2_close_eos), 0x0002, "Close search if end of search reached", HFILL }},
18500
18501         { &hf_smb_ff2_close,
18502                 { "Close", "smb.find_first2.flags.close", FT_BOOLEAN, 16,
18503                 TFS(&tfs_ff2_close), 0x0001, "Close search after this request", HFILL }},
18504
18505         { &hf_smb_ff2_information_level,
18506                 { "Level of Interest", "smb.ff2_loi", FT_UINT16, BASE_DEC,
18507                 VALS(ff2_il_vals), 0, "Level of interest for FIND_FIRST2 command", HFILL }},
18508
18509         { &hf_smb_qpi_loi,
18510                 { "Level of Interest", "smb.qpi_loi", FT_UINT16, BASE_DEC,
18511                 VALS(qpi_loi_vals), 0, "Level of interest for TRANSACTION[2] QUERY_{FILE,PATH}_INFO commands", HFILL }},
18512
18513         { &hf_smb_spi_loi,
18514                 { "Level of Interest", "smb.spi_loi", FT_UINT16, BASE_DEC,
18515                 VALS(spi_loi_vals), 0, "Level of interest for TRANSACTION[2] SET_{FILE,PATH}_INFO commands", HFILL }},
18516
18517 #if 0
18518         { &hf_smb_sfi_writetru,
18519                 { "Writethrough", "smb.sfi_writethrough", FT_BOOLEAN, 16,
18520                 TFS(&tfs_da_writetru), 0x0010, "Writethrough mode?", HFILL }},
18521
18522         { &hf_smb_sfi_caching,
18523                 { "Caching", "smb.sfi_caching", FT_BOOLEAN, 16,
18524                 TFS(&tfs_da_caching), 0x0020, "Caching mode?", HFILL }},
18525 #endif
18526
18527         { &hf_smb_storage_type,
18528                 { "Storage Type", "smb.storage_type", FT_UINT32, BASE_DEC,
18529                 NULL, 0, "Type of storage", HFILL }},
18530
18531         { &hf_smb_resume,
18532                 { "Resume Key", "smb.resume", FT_UINT32, BASE_DEC,
18533                 NULL, 0, "Resume Key", HFILL }},
18534
18535         { &hf_smb_max_referral_level,
18536                 { "Max Referral Level", "smb.max_referral_level", FT_UINT16, BASE_DEC,
18537                 NULL, 0, "Latest referral version number understood", HFILL }},
18538
18539         { &hf_smb_qfsi_information_level,
18540                 { "Level of Interest", "smb.qfi_loi", FT_UINT16, BASE_HEX,
18541                 VALS(qfsi_vals), 0, "Level of interest for QUERY_FS_INFORMATION2 command", HFILL }},
18542
18543         { &hf_smb_nt_rename_level,
18544                 { "Level of Interest", "smb.ntr_loi", FT_UINT16, BASE_DEC,
18545                 VALS(nt_rename_vals), 0, "NT Rename level", HFILL }},
18546
18547         { &hf_smb_cluster_count,
18548                 { "Cluster count", "smb.ntr_clu", FT_UINT32, BASE_DEC,
18549                 NULL, 0, "Number of clusters", HFILL }},
18550
18551         { &hf_smb_number_of_links,
18552                 { "Link Count", "smb.link_count", FT_UINT32, BASE_DEC,
18553                 NULL, 0, "Number of hard links to the file", HFILL }},
18554
18555         { &hf_smb_delete_pending,
18556                 { "Delete Pending", "smb.delete_pending", FT_UINT16, BASE_DEC,
18557                 VALS(delete_pending_vals), 0, "Is this object about to be deleted?", HFILL }},
18558
18559         { &hf_smb_index_number,
18560                 { "Index Number", "smb.index_number", FT_UINT64, BASE_DEC,
18561                 NULL, 0, "File system unique identifier", HFILL }},
18562
18563         { &hf_smb_current_offset,
18564                 { "Current Offset", "smb.offset", FT_UINT64, BASE_DEC,
18565                 NULL, 0, "Current offset in the file", HFILL }},
18566
18567         { &hf_smb_t2_alignment,
18568                 { "Alignment", "smb.alignment", FT_UINT32, BASE_DEC,
18569                 VALS(alignment_vals), 0, "What alignment do we require for buffers", HFILL }},
18570
18571         { &hf_smb_t2_stream_name_length,
18572                 { "Stream Name Length", "smb.stream_name_len", FT_UINT32, BASE_DEC,
18573                 NULL, 0, "Length of stream name", HFILL }},
18574
18575         { &hf_smb_t2_stream_size,
18576                 { "Stream Size", "smb.stream_size", FT_UINT64, BASE_DEC,
18577                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18578
18579         { &hf_smb_t2_stream_name,
18580                 { "Stream Name", "smb.stream_name", FT_STRING, BASE_NONE,
18581                 NULL, 0, "Name of the stream", HFILL }},
18582
18583         { &hf_smb_t2_compressed_file_size,
18584                 { "Compressed Size", "smb.compressed.file_size", FT_UINT64, BASE_DEC,
18585                 NULL, 0, "Size of the compressed file", HFILL }},
18586
18587         { &hf_smb_t2_compressed_format,
18588                 { "Compression Format", "smb.compressed.format", FT_UINT16, BASE_DEC,
18589                 NULL, 0, "Compression algorithm used", HFILL }},
18590
18591         { &hf_smb_t2_compressed_unit_shift,
18592                 { "Unit Shift", "smb.compressed.unit_shift", FT_UINT8, BASE_DEC,
18593                 NULL, 0, "Size of the stream in number of bytes", HFILL }},
18594
18595         { &hf_smb_t2_compressed_chunk_shift,
18596                 { "Chunk Shift", "smb.compressed.chunk_shift", FT_UINT8, BASE_DEC,
18597                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18598
18599         { &hf_smb_t2_compressed_cluster_shift,
18600                 { "Cluster Shift", "smb.compressed.cluster_shift", FT_UINT8, BASE_DEC,
18601                 NULL, 0, "Allocated size of the stream in number of bytes", HFILL }},
18602
18603         { &hf_smb_t2_marked_for_deletion,
18604                 { "Marked for Deletion", "smb.marked_for_deletion", FT_BOOLEAN, BASE_NONE,
18605                 TFS(&tfs_marked_for_deletion), 0x0, "Marked for deletion?", HFILL }},
18606
18607         { &hf_smb_dfs_path_consumed,
18608                 { "Path Consumed", "smb.dfs.path_consumed", FT_UINT16, BASE_DEC,
18609                 NULL, 0, "Number of RequestFilename bytes client", HFILL }},
18610
18611         { &hf_smb_dfs_num_referrals,
18612                 { "Num Referrals", "smb.dfs.num_referrals", FT_UINT16, BASE_DEC,
18613                 NULL, 0, "Number of referrals in this pdu", HFILL }},
18614
18615         { &hf_smb_get_dfs_server_hold_storage,
18616                 { "Hold Storage", "smb.dfs.flags.server_hold_storage", FT_BOOLEAN, 16,
18617                 TFS(&tfs_get_dfs_server_hold_storage), 0x02, "The servers in referrals should hold storage for the file", HFILL }},
18618
18619         { &hf_smb_get_dfs_fielding,
18620                 { "Fielding", "smb.dfs.flags.fielding", FT_BOOLEAN, 16,
18621                 TFS(&tfs_get_dfs_fielding), 0x01, "The servers in referrals are capable of fielding", HFILL }},
18622
18623         { &hf_smb_dfs_referral_version,
18624                 { "Version", "smb.dfs.referral.version", FT_UINT16, BASE_DEC,
18625                 NULL, 0, "Version of referral element", HFILL }},
18626
18627         { &hf_smb_dfs_referral_size,
18628                 { "Size", "smb.dfs.referral.size", FT_UINT16, BASE_DEC,
18629                 NULL, 0, "Size of referral element", HFILL }},
18630
18631         { &hf_smb_dfs_referral_server_type,
18632                 { "Server Type", "smb.dfs.referral.server.type", FT_UINT16, BASE_DEC,
18633                 VALS(dfs_referral_server_type_vals), 0, "Type of referral server", HFILL }},
18634
18635         { &hf_smb_dfs_referral_flags_strip,
18636                 { "Strip", "smb.dfs.referral.flags.strip", FT_BOOLEAN, 16,
18637                 TFS(&tfs_dfs_referral_flags_strip), 0x01, "Should we strip off pathconsumed characters before submitting?", HFILL }},
18638
18639         { &hf_smb_dfs_referral_node_offset,
18640                 { "Node Offset", "smb.dfs.referral.node_offset", FT_UINT16, BASE_DEC,
18641                 NULL, 0, "Offset of name of entity to visit next", HFILL }},
18642
18643         { &hf_smb_dfs_referral_node,
18644                 { "Node", "smb.dfs.referral.node", FT_STRING, BASE_NONE,
18645                 NULL, 0, "Name of entity to visit next", HFILL }},
18646
18647         { &hf_smb_dfs_referral_proximity,
18648                 { "Proximity", "smb.dfs.referral.proximity", FT_UINT16, BASE_DEC,
18649                 NULL, 0, "Hint describing proximity of this server to the client", HFILL }},
18650
18651         { &hf_smb_dfs_referral_ttl,
18652                 { "TTL", "smb.dfs.referral.ttl", FT_UINT16, BASE_DEC,
18653                 NULL, 0, "Number of seconds the client can cache this referral", HFILL }},
18654
18655         { &hf_smb_dfs_referral_path_offset,
18656                 { "Path Offset", "smb.dfs.referral.path_offset", FT_UINT16, BASE_DEC,
18657                 NULL, 0, "Offset of Dfs Path that matched pathconsumed", HFILL }},
18658
18659         { &hf_smb_dfs_referral_path,
18660                 { "Path", "smb.dfs.referral.path", FT_STRING, BASE_NONE,
18661                 NULL, 0, "Dfs Path that matched pathconsumed", HFILL }},
18662
18663         { &hf_smb_dfs_referral_alt_path_offset,
18664                 { "Alt Path Offset", "smb.dfs.referral.alt_path_offset", FT_UINT16, BASE_DEC,
18665                 NULL, 0, "Offset of alternative(8.3) Path that matched pathconsumed", HFILL }},
18666
18667         { &hf_smb_dfs_referral_alt_path,
18668                 { "Alt Path", "smb.dfs.referral.alt_path", FT_STRING, BASE_NONE,
18669                 NULL, 0, "Alternative(8.3) Path that matched pathconsumed", HFILL }},
18670
18671         { &hf_smb_end_of_search,
18672                 { "End Of Search", "smb.end_of_search", FT_UINT16, BASE_DEC,
18673                 NULL, 0, "Was last entry returned?", HFILL }},
18674
18675         { &hf_smb_last_name_offset,
18676                 { "Last Name Offset", "smb.last_name_offset", FT_UINT16, BASE_DEC,
18677                 NULL, 0, "If non-0 this is the offset into the datablock for the file name of the last entry", HFILL }},
18678
18679         { &hf_smb_fn_information_level,
18680                 { "Level of Interest", "smb.fn_loi", FT_UINT16, BASE_DEC,
18681                 NULL, 0, "Level of interest for FIND_NOTIFY command", HFILL }},
18682
18683         { &hf_smb_monitor_handle,
18684                 { "Monitor Handle", "smb.monitor_handle", FT_UINT16, BASE_HEX,
18685                 NULL, 0, "Handle for Find Notify operations", HFILL }},
18686
18687         { &hf_smb_change_count,
18688                 { "Change Count", "smb.change_count", FT_UINT16, BASE_DEC,
18689                 NULL, 0, "Number of changes to wait for", HFILL }},
18690
18691         { &hf_smb_file_index,
18692                 { "File Index", "smb.file_index", FT_UINT32, BASE_DEC,
18693                 NULL, 0, "File index", HFILL }},
18694
18695         { &hf_smb_short_file_name,
18696                 { "Short File Name", "smb.short_file", FT_STRING, BASE_NONE,
18697                 NULL, 0, "Short (8.3) File Name", HFILL }},
18698
18699         { &hf_smb_short_file_name_len,
18700                 { "Short File Name Len", "smb.short_file_name_len", FT_UINT32, BASE_DEC,
18701                 NULL, 0, "Length of Short (8.3) File Name", HFILL }},
18702
18703         { &hf_smb_fs_id,
18704                 { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
18705                 NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
18706
18707         { &hf_smb_fs_guid,
18708                 { "FS GUID", "smb.fs_guid", FT_STRING, BASE_NONE,
18709                 NULL, 0, "File System GUID", HFILL }},
18710
18711         { &hf_smb_sector_unit,
18712                 { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
18713                 NULL, 0, "Sectors per allocation unit", HFILL }},
18714
18715         { &hf_smb_fs_units,
18716                 { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
18717                 NULL, 0, "Total number of units on this filesystem", HFILL }},
18718
18719         { &hf_smb_fs_sector,
18720                 { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
18721                 NULL, 0, "Bytes per sector", HFILL }},
18722
18723         { &hf_smb_avail_units,
18724                 { "Available Units", "smb.avail.units", FT_UINT32, BASE_DEC,
18725                 NULL, 0, "Total number of available units on this filesystem", HFILL }},
18726
18727         { &hf_smb_volume_serial_num,
18728                 { "Volume Serial Number", "smb.volume.serial", FT_UINT32, BASE_HEX,
18729                 NULL, 0, "Volume serial number", HFILL }},
18730
18731         { &hf_smb_volume_label_len,
18732                 { "Label Length", "smb.volume.label.len", FT_UINT32, BASE_DEC,
18733                 NULL, 0, "Length of volume label", HFILL }},
18734
18735         { &hf_smb_volume_label,
18736                 { "Label", "smb.volume.label", FT_STRING, BASE_DEC,
18737                 NULL, 0, "Volume label", HFILL }},
18738
18739         { &hf_smb_free_alloc_units64,
18740                 { "Free Units", "smb.free_alloc_units", FT_UINT64, BASE_DEC,
18741                 NULL, 0, "Number of free allocation units", HFILL }},
18742
18743         { &hf_smb_caller_free_alloc_units64,
18744                 { "Caller Free Units", "smb.caller_free_alloc_units", FT_UINT64, BASE_DEC,
18745                 NULL, 0, "Number of caller free allocation units", HFILL }},
18746
18747         { &hf_smb_actual_free_alloc_units64,
18748                 { "Actual Free Units", "smb.actual_free_alloc_units", FT_UINT64, BASE_DEC,
18749                 NULL, 0, "Number of actual free allocation units", HFILL }},
18750
18751         { &hf_smb_soft_quota_limit,
18752                 { "(Soft) Quota Treshold", "smb.quota.soft.default", FT_UINT64, BASE_DEC,
18753                 NULL, 0, "Soft Quota treshold", HFILL }},
18754
18755         { &hf_smb_hard_quota_limit,
18756                 { "(Hard) Quota Limit", "smb.quota.hard.default", FT_UINT64, BASE_DEC,
18757                 NULL, 0, "Hard Quota limit", HFILL }},
18758
18759         { &hf_smb_user_quota_used,
18760                 { "Quota Used", "smb.quota.used", FT_UINT64, BASE_DEC,
18761                 NULL, 0, "How much Quota is used by this user", HFILL }},
18762
18763         { &hf_smb_max_name_len,
18764                 { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
18765                 NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
18766
18767         { &hf_smb_fs_name_len,
18768                 { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
18769                 NULL, 0, "Length of filesystem name in bytes", HFILL }},
18770
18771         { &hf_smb_fs_name,
18772                 { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
18773                 NULL, 0, "Name of filesystem", HFILL }},
18774
18775         { &hf_smb_device_char_removable,
18776                 { "Removable", "smb.device.removable", FT_BOOLEAN, 32,
18777                 TFS(&tfs_device_char_removable), 0x00000001, "Is this a removable device", HFILL }},
18778
18779         { &hf_smb_device_char_read_only,
18780                 { "Read Only", "smb.device.read_only", FT_BOOLEAN, 32,
18781                 TFS(&tfs_device_char_read_only), 0x00000002, "Is this a read-only device", HFILL }},
18782
18783         { &hf_smb_device_char_floppy,
18784                 { "Floppy", "smb.device.floppy", FT_BOOLEAN, 32,
18785                 TFS(&tfs_device_char_floppy), 0x00000004, "Is this a floppy disk", HFILL }},
18786
18787         { &hf_smb_device_char_write_once,
18788                 { "Write Once", "smb.device.write_once", FT_BOOLEAN, 32,
18789                 TFS(&tfs_device_char_write_once), 0x00000008, "Is this a write-once device", HFILL }},
18790
18791         { &hf_smb_device_char_remote,
18792                 { "Remote", "smb.device.remote", FT_BOOLEAN, 32,
18793                 TFS(&tfs_device_char_remote), 0x00000010, "Is this a remote device", HFILL }},
18794
18795         { &hf_smb_device_char_mounted,
18796                 { "Mounted", "smb.device.mounted", FT_BOOLEAN, 32,
18797                 TFS(&tfs_device_char_mounted), 0x00000020, "Is this a mounted device", HFILL }},
18798
18799         { &hf_smb_device_char_virtual,
18800                 { "Virtual", "smb.device.virtual", FT_BOOLEAN, 32,
18801                 TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
18802
18803         { &hf_smb_fs_attr_css,
18804                 { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
18805                 TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
18806
18807         { &hf_smb_fs_attr_cpn,
18808                 { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
18809                 TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
18810
18811         { &hf_smb_fs_attr_pacls,
18812                 { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
18813                 TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
18814
18815         { &hf_smb_fs_attr_fc,
18816                 { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
18817                 TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
18818
18819         { &hf_smb_fs_attr_vq,
18820                 { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
18821                 TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
18822
18823         { &hf_smb_fs_attr_dim,
18824                 { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
18825                 TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
18826
18827         { &hf_smb_fs_attr_vic,
18828                 { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
18829                 TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
18830
18831         { &hf_smb_sec_desc_revision,
18832                 { "Revision", "smb.sec_desc.revision", FT_UINT8, BASE_DEC,
18833                 NULL, 0, "Version of NT Security Descriptor structure", HFILL }},
18834
18835         { &hf_smb_sid,
18836                 { "SID", "smb.sid", FT_STRING, BASE_DEC,
18837                 NULL, 0, "SID: Security Identifier", HFILL }},
18838
18839         { &hf_smb_sid_revision,
18840                 { "Revision", "smb.sid.revision", FT_UINT8, BASE_DEC,
18841                 NULL, 0, "Version of SID structure", HFILL }},
18842
18843         { &hf_smb_sid_num_auth,
18844                 { "Num Auth", "smb.sid.num_auth", FT_UINT8, BASE_DEC,
18845                 NULL, 0, "Number of authorities for this SID", HFILL }},
18846
18847         { &hf_smb_acl_revision,
18848                 { "Revision", "smb.acl.revision", FT_UINT8, BASE_DEC,
18849                 NULL, 0, "Version of NT ACL structure", HFILL }},
18850
18851         { &hf_smb_acl_size,
18852                 { "Size", "smb.acl.size", FT_UINT16, BASE_DEC,
18853                 NULL, 0, "Size of NT ACL structure", HFILL }},
18854
18855         { &hf_smb_acl_num_aces,
18856                 { "Num ACEs", "smb.acl.num_aces", FT_UINT32, BASE_DEC,
18857                 NULL, 0, "Number of ACE structures for this ACL", HFILL }},
18858
18859         { &hf_smb_user_quota_offset,
18860                 { "Next Offset", "smb.quota.user.offset", FT_UINT32, BASE_DEC,
18861                 NULL, 0, "Relative offset to next user quota structure", HFILL }},
18862
18863         { &hf_smb_ace_type,
18864                 { "Type", "smb.ace.type", FT_UINT8, BASE_DEC,
18865                 VALS(ace_type_vals), 0, "Type of ACE", HFILL }},
18866
18867         { &hf_smb_pipe_write_len,
18868                 { "Pipe Write Len", "smb.pipe.write_len", FT_UINT16, BASE_DEC,
18869                 NULL, 0, "Number of bytes written to pipe", HFILL }},
18870
18871         { &hf_smb_ace_size,
18872                 { "Size", "smb.ace.size", FT_UINT16, BASE_DEC,
18873                 NULL, 0, "Size of this ACE", HFILL }},
18874
18875         { &hf_smb_ace_flags_object_inherit,
18876                 { "Object Inherit", "smb.ace.flags.object_inherit", FT_BOOLEAN, 8,
18877                 TFS(&tfs_ace_flags_object_inherit), 0x01, "Will subordinate files inherit this ACE?", HFILL }},
18878
18879         { &hf_smb_ace_flags_container_inherit,
18880                 { "Container Inherit", "smb.ace.flags.container_inherit", FT_BOOLEAN, 8,
18881                 TFS(&tfs_ace_flags_container_inherit), 0x02, "Will subordinate containers inherit this ACE?", HFILL }},
18882
18883         { &hf_smb_ace_flags_non_propagate_inherit,
18884                 { "Non-Propagate Inherit", "smb.ace.flags.non_propagate_inherit", FT_BOOLEAN, 8,
18885                 TFS(&tfs_ace_flags_non_propagate_inherit), 0x04, "Will subordinate object propagate this ACE further?", HFILL }},
18886
18887         { &hf_smb_ace_flags_inherit_only,
18888                 { "Inherit Only", "smb.ace.flags.inherit_only", FT_BOOLEAN, 8,
18889                 TFS(&tfs_ace_flags_inherit_only), 0x08, "Does this ACE apply to the current object?", HFILL }},
18890
18891         { &hf_smb_ace_flags_inherited_ace,
18892                 { "Inherited ACE", "smb.ace.flags.inherited_ace", FT_BOOLEAN, 8,
18893                 TFS(&tfs_ace_flags_inherited_ace), 0x10, "Was this ACE inherited from its parent object?", HFILL }},
18894
18895         { &hf_smb_ace_flags_successful_access,
18896                 { "Audit Successful Accesses", "smb.ace.flags.successful_access", FT_BOOLEAN, 8,
18897                 TFS(&tfs_ace_flags_successful_access), 0x40, "Should successful accesses be audited?", HFILL }},
18898
18899         { &hf_smb_ace_flags_failed_access,
18900                 { "Audit Failed Accesses", "smb.ace.flags.failed_access", FT_BOOLEAN, 8,
18901                 TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
18902
18903         { &hf_smb_sec_desc_type_owner_defaulted,
18904                 { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
18905                 TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
18906
18907         { &hf_smb_sec_desc_type_group_defaulted,
18908                 { "Group Defaulted", "smb.sec_desc.type.group_defaulted", FT_BOOLEAN, 16,
18909                 TFS(&tfs_sec_desc_type_group_defaulted), 0x0002, "Is Group Defaulted?", HFILL }},
18910
18911         { &hf_smb_sec_desc_type_dacl_present,
18912                 { "DACL Present", "smb.sec_desc.type.dacl_present", FT_BOOLEAN, 16,
18913                 TFS(&tfs_sec_desc_type_dacl_present), 0x0004, "Does this SecDesc have DACL present?", HFILL }},
18914
18915         { &hf_smb_sec_desc_type_dacl_defaulted,
18916                 { "DACL Defaulted", "smb.sec_desc.type.dacl_defaulted", FT_BOOLEAN, 16,
18917                 TFS(&tfs_sec_desc_type_dacl_defaulted), 0x0008, "Does this SecDesc have DACL Defaulted?", HFILL }},
18918
18919         { &hf_smb_sec_desc_type_sacl_present,
18920                 { "SACL Present", "smb.sec_desc.type.sacl_present", FT_BOOLEAN, 16,
18921                 TFS(&tfs_sec_desc_type_sacl_present), 0x0010, "Is the SACL present?", HFILL }},
18922
18923         { &hf_smb_sec_desc_type_sacl_defaulted,
18924                 { "SACL Defaulted", "smb.sec_desc.type.sacl_defaulted", FT_BOOLEAN, 16,
18925                 TFS(&tfs_sec_desc_type_sacl_defaulted), 0x0020, "Does this SecDesc have SACL Defaulted?", HFILL }},
18926
18927         { &hf_smb_sec_desc_type_dacl_auto_inherit_req,
18928                 { "DACL Auto Inherit Required", "smb.sec_desc.type.dacl_auto_inherit_req", FT_BOOLEAN, 16,
18929                 TFS(&tfs_sec_desc_type_dacl_auto_inherit_req), 0x0100, "Does this SecDesc have DACL Auto Inherit Required set?", HFILL }},
18930
18931         { &hf_smb_sec_desc_type_sacl_auto_inherit_req,
18932                 { "SACL Auto Inherit Required", "smb.sec_desc.type.sacl_auto_inherit_req", FT_BOOLEAN, 16,
18933                 TFS(&tfs_sec_desc_type_sacl_auto_inherit_req), 0x0200, "Does this SecDesc have SACL Auto Inherit Required set?", HFILL }},
18934
18935         { &hf_smb_sec_desc_type_dacl_auto_inherited,
18936                 { "DACL Auto Inherited", "smb.sec_desc.type.dacl_auto_inherited", FT_BOOLEAN, 16,
18937                 TFS(&tfs_sec_desc_type_dacl_auto_inherited), 0x0400, "Is this DACL auto inherited", HFILL }},
18938
18939         { &hf_smb_sec_desc_type_sacl_auto_inherited,
18940                 { "SACL Auto Inherited", "smb.sec_desc.type.sacl_auto_inherited", FT_BOOLEAN, 16,
18941                 TFS(&tfs_sec_desc_type_sacl_auto_inherited), 0x0800, "Is this SACL auto inherited", HFILL }},
18942
18943         { &hf_smb_sec_desc_type_dacl_protected,
18944                 { "DACL Protected", "smb.sec_desc.type.dacl_protected", FT_BOOLEAN, 16,
18945                 TFS(&tfs_sec_desc_type_dacl_protected), 0x1000, "Is the DACL structure protected?", HFILL }},
18946
18947         { &hf_smb_sec_desc_type_sacl_protected,
18948                 { "SACL Protected", "smb.sec_desc.type.sacl_protected", FT_BOOLEAN, 16,
18949                 TFS(&tfs_sec_desc_type_sacl_protected), 0x2000, "Is the SACL structure protected?", HFILL }},
18950
18951         { &hf_smb_sec_desc_type_self_relative,
18952                 { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
18953                 TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
18954
18955         { &hf_smb_quota_flags_deny_disk,
18956                 { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
18957                 TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
18958
18959         { &hf_smb_quota_flags_log_limit,
18960                 { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
18961                 TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
18962
18963         { &hf_smb_quota_flags_log_warning,
18964                 { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
18965                 TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
18966
18967         { &hf_smb_quota_flags_enabled,
18968                 { "Enabled", "smb.quota.flags.enabled", FT_BOOLEAN, 8,
18969                 TFS(&tfs_quota_flags_enabled), 0x01, "Is quotas enabled of this FS?", HFILL }},
18970
18971         { &hf_smb_segment_overlap,
18972                 { "Fragment overlap",   "smb.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18973                         "Fragment overlaps with other fragments", HFILL }},
18974
18975         { &hf_smb_segment_overlap_conflict,
18976                 { "Conflicting data in fragment overlap",       "smb.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18977                         "Overlapping fragments contained conflicting data", HFILL }},
18978
18979         { &hf_smb_segment_multiple_tails,
18980                 { "Multiple tail fragments found",      "smb.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18981                         "Several tails were found when defragmenting the packet", HFILL }},
18982
18983         { &hf_smb_segment_too_long_fragment,
18984                 { "Fragment too long",  "smb.segment.toolongfragment", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
18985                         "Fragment contained data past end of packet", HFILL }},
18986
18987         { &hf_smb_segment_error,
18988                 { "Defragmentation error", "smb.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18989                         "Defragmentation error due to illegal fragments", HFILL }},
18990
18991         { &hf_smb_segment,
18992                 { "SMB Segment", "smb.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
18993                         "SMB Segment", HFILL }},
18994
18995         { &hf_smb_segments,
18996                 { "SMB Segments", "smb.segment.segments", FT_NONE, BASE_NONE, NULL, 0x0,
18997                         "SMB Segments", HFILL }},
18998
18999         { &hf_smb_unix_major_version,
19000           { "Major Version", "smb.unix.major_version", FT_UINT16, BASE_DEC,
19001             NULL, 0, "UNIX Major Version", HFILL }},
19002
19003         { &hf_smb_unix_minor_version,
19004           { "Minor Version", "smb.unix.minor_version", FT_UINT16, BASE_DEC,
19005             NULL, 0, "UNIX Minor Version", HFILL }},
19006
19007         { &hf_smb_unix_capability_fcntl,
19008           { "FCNTL Capability", "smb.unix.capability.fcntl", FT_BOOLEAN, 32,
19009                 TFS(&flags_set_truth), 0x00000001, "", HFILL }},
19010
19011         { &hf_smb_unix_capability_posix_acl,
19012           { "POSIX ACL Capability", "smb.unix.capability.posix_acl", FT_BOOLEAN, 32,
19013                 TFS(&flags_set_truth), 0x00000002, "", HFILL }},
19014
19015         { &hf_smb_unix_file_size,
19016           { "File size", "smb.unix.file.size", FT_UINT64, BASE_DEC,
19017             NULL, 0, "", HFILL }},
19018
19019         { &hf_smb_unix_file_num_bytes,
19020           { "Number of bytes", "smb.unix.file.num_bytes", FT_UINT64, BASE_DEC,
19021             NULL, 0, "Number of bytes used to store the file", HFILL }},
19022
19023         { &hf_smb_unix_file_last_status,
19024           { "Last status change", "smb.unix.file.stime", FT_ABSOLUTE_TIME, BASE_NONE,
19025             NULL, 0, "", HFILL }},
19026
19027         { &hf_smb_unix_file_last_access,
19028           { "Last access", "smb.unix.file.atime", FT_ABSOLUTE_TIME, BASE_NONE,
19029             NULL, 0, "", HFILL }},
19030
19031         { &hf_smb_unix_file_last_change,
19032           { "Last modification", "smb.unix.file.mtime", FT_ABSOLUTE_TIME, BASE_NONE,
19033             NULL, 0, "", HFILL }},
19034
19035         { &hf_smb_unix_file_uid,
19036           { "UID", "smb.unix.file.uid", FT_UINT64, BASE_DEC,
19037             NULL, 0, "", HFILL }},
19038
19039         { &hf_smb_unix_file_gid,
19040           { "GID", "smb.unix.file.gid", FT_UINT64, BASE_DEC,
19041             NULL, 0, "", HFILL }},
19042
19043         { &hf_smb_unix_file_type,
19044           { "File type", "smb.unix.file.file_type", FT_UINT32, BASE_DEC,
19045             VALS(unix_file_type_vals), 0, "", HFILL }},
19046
19047         { &hf_smb_unix_file_dev_major,
19048           { "Major device", "smb.unix.file.dev_major", FT_UINT64, BASE_HEX,
19049             NULL, 0, "", HFILL }},
19050
19051         { &hf_smb_unix_file_dev_minor,
19052           { "Minor device", "smb.unix.file.dev_minor", FT_UINT64, BASE_HEX,
19053             NULL, 0, "", HFILL }},
19054
19055         { &hf_smb_unix_file_unique_id,
19056           { "Unique ID", "smb.unix.file.unique_id", FT_UINT64, BASE_HEX,
19057             NULL, 0, "", HFILL }},
19058
19059         { &hf_smb_unix_file_permissions,
19060           { "File permissions", "smb.unix.file.perms", FT_UINT64, BASE_HEX,
19061             NULL, 0, "", HFILL }},
19062
19063         { &hf_smb_unix_file_nlinks,
19064           { "Num links", "smb.unix.file.num_links", FT_UINT64, BASE_DEC,
19065             NULL, 0, "", HFILL }},
19066
19067         { &hf_smb_unix_file_link_dest,
19068           { "Link destination", "smb.unix.file.link_dest", FT_STRING, 
19069             BASE_NONE, NULL, 0, "", HFILL }},
19070
19071         { &hf_smb_unix_find_file_nextoffset,
19072           { "Next entry offset", "smb.unix.find_file.next_offset", FT_UINT32, BASE_DEC,
19073             NULL, 0, "", HFILL }},
19074
19075         { &hf_smb_unix_find_file_resumekey,
19076           { "Resume key", "smb.unix.find_file.resume_key", FT_UINT32, BASE_DEC,
19077             NULL, 0, "", HFILL }},
19078
19079                 /* Access masks */
19080
19081                 { &hf_smb_access_mask,
19082                   { "Access required", "smb.access_mask",
19083                     FT_UINT32, BASE_HEX, NULL, 0x0, "Access mask",
19084                     HFILL }},
19085                 { &hf_access_generic_read,
19086                   { "Generic read", "nt.access_mask.generic_read",
19087                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19088                     GENERIC_READ_ACCESS, "Generic read", HFILL }},
19089
19090                 { &hf_access_generic_write,
19091                   { "Generic write", "nt.access_mask.generic_write",
19092                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19093                     GENERIC_WRITE_ACCESS, "Generic write", HFILL }},
19094
19095                 { &hf_access_generic_execute,
19096                   { "Generic execute", "nt.access_mask.generic_execute",
19097                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19098                     GENERIC_EXECUTE_ACCESS, "Generic execute", HFILL }},
19099
19100                 { &hf_access_generic_all,
19101                   { "Generic all", "nt.access_mask.generic_all",
19102                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19103                     GENERIC_ALL_ACCESS, "Generic all", HFILL }},
19104
19105                 { &hf_access_maximum_allowed,
19106                   { "Maximum allowed", "nt.access_mask.maximum_allowed",
19107                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19108                     MAXIMUM_ALLOWED_ACCESS, "Maximum allowed", HFILL }},
19109
19110                 { &hf_access_sacl,
19111                   { "Access SACL", "nt.access_mask.access_sacl",
19112                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19113                     ACCESS_SACL_ACCESS, "Access SACL", HFILL }},
19114
19115                 { &hf_access_standard_read_control,
19116                   { "Read control", "nt.access_mask.read_control",
19117                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19118                     READ_CONTROL_ACCESS, "Read control", HFILL }},
19119
19120                 { &hf_access_standard_delete,
19121                   { "Delete", "nt.access_mask.delete",
19122                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19123                     DELETE_ACCESS, "Delete", HFILL }},
19124
19125                 { &hf_access_standard_synchronise,
19126                   { "Synchronise", "nt.access_mask.synchronise",
19127                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19128                     SYNCHRONIZE_ACCESS, "Synchronise", HFILL }},
19129
19130                 { &hf_access_standard_write_dac,
19131                   { "Write DAC", "nt.access_mask.write_dac",
19132                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19133                     WRITE_DAC_ACCESS, "Write DAC", HFILL }},
19134
19135                 { &hf_access_standard_write_owner,
19136                   { "Write owner", "nt.access_mask.write_owner",
19137                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19138                     WRITE_OWNER_ACCESS, "Write owner", HFILL }},
19139
19140                 { &hf_access_specific_15,
19141                   { "Specific access, bit 15", "nt.access_mask.specific_15",
19142                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19143                     0x8000, "Specific access, bit 15", HFILL }},
19144
19145                 { &hf_access_specific_14,
19146                   { "Specific access, bit 14", "nt.access_mask.specific_14",
19147                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19148                     0x4000, "Specific access, bit 14", HFILL }},
19149
19150                 { &hf_access_specific_13,
19151                   { "Specific access, bit 13", "nt.access_mask.specific_13",
19152                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19153                     0x2000, "Specific access, bit 13", HFILL }},
19154
19155                 { &hf_access_specific_12,
19156                   { "Specific access, bit 12", "nt.access_mask.specific_12",
19157                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19158                     0x1000, "Specific access, bit 12", HFILL }},
19159
19160                 { &hf_access_specific_11,
19161                   { "Specific access, bit 11", "nt.access_mask.specific_11",
19162                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19163                     0x0800, "Specific access, bit 11", HFILL }},
19164
19165                 { &hf_access_specific_10,
19166                   { "Specific access, bit 10", "nt.access_mask.specific_10",
19167                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19168                     0x0400, "Specific access, bit 10", HFILL }},
19169
19170                 { &hf_access_specific_9,
19171                   { "Specific access, bit 9", "nt.access_mask.specific_9",
19172                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19173                     0x0200, "Specific access, bit 9", HFILL }},
19174
19175                 { &hf_access_specific_8,
19176                   { "Specific access, bit 8", "nt.access_mask.specific_8",
19177                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19178                     0x0100, "Specific access, bit 8", HFILL }},
19179
19180                 { &hf_access_specific_7,
19181                   { "Specific access, bit 7", "nt.access_mask.specific_7",
19182                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19183                     0x0080, "Specific access, bit 7", HFILL }},
19184
19185                 { &hf_access_specific_6,
19186                   { "Specific access, bit 6", "nt.access_mask.specific_6",
19187                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19188                     0x0040, "Specific access, bit 6", HFILL }},
19189
19190                 { &hf_access_specific_5,
19191                   { "Specific access, bit 5", "nt.access_mask.specific_5",
19192                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19193                     0x0020, "Specific access, bit 5", HFILL }},
19194
19195                 { &hf_access_specific_4,
19196                   { "Specific access, bit 4", "nt.access_mask.specific_4",
19197                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19198                     0x0010, "Specific access, bit 4", HFILL }},
19199
19200                 { &hf_access_specific_3,
19201                   { "Specific access, bit 3", "nt.access_mask.specific_3",
19202                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19203                     0x0008, "Specific access, bit 3", HFILL }},
19204
19205                 { &hf_access_specific_2,
19206                   { "Specific access, bit 2", "nt.access_mask.specific_2",
19207                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19208                     0x0004, "Specific access, bit 2", HFILL }},
19209
19210                 { &hf_access_specific_1,
19211                   { "Specific access, bit 1", "nt.access_mask.specific_1",
19212                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19213                     0x0002, "Specific access, bit 1", HFILL }},
19214
19215                 { &hf_access_specific_0,
19216                   { "Specific access, bit 0", "nt.access_mask.specific_0",
19217                     FT_BOOLEAN, 32, TFS(&flags_set_truth),
19218                     0x0001, "Specific access, bit 0", HFILL }}
19219         };
19220
19221         static gint *ett[] = {
19222                 &ett_smb,
19223                 &ett_smb_hdr,
19224                 &ett_smb_command,
19225                 &ett_smb_fileattributes,
19226                 &ett_smb_capabilities,
19227                 &ett_smb_aflags,
19228                 &ett_smb_dialect,
19229                 &ett_smb_dialects,
19230                 &ett_smb_mode,
19231                 &ett_smb_rawmode,
19232                 &ett_smb_flags,
19233                 &ett_smb_flags2,
19234                 &ett_smb_desiredaccess,
19235                 &ett_smb_search,
19236                 &ett_smb_file,
19237                 &ett_smb_openfunction,
19238                 &ett_smb_filetype,
19239                 &ett_smb_openaction,
19240                 &ett_smb_writemode,
19241                 &ett_smb_lock_type,
19242                 &ett_smb_ssetupandxaction,
19243                 &ett_smb_optionsup,
19244                 &ett_smb_time_date,
19245                 &ett_smb_move_copy_flags,
19246                 &ett_smb_file_attributes,
19247                 &ett_smb_search_resume_key,
19248                 &ett_smb_search_dir_info,
19249                 &ett_smb_unlocks,
19250                 &ett_smb_unlock,
19251                 &ett_smb_locks,
19252                 &ett_smb_lock,
19253                 &ett_smb_open_flags,
19254                 &ett_smb_ipc_state,
19255                 &ett_smb_open_action,
19256                 &ett_smb_setup_action,
19257                 &ett_smb_connect_flags,
19258                 &ett_smb_connect_support_bits,
19259                 &ett_smb_nt_access_mask,
19260                 &ett_smb_nt_create_bits,
19261                 &ett_smb_nt_create_options,
19262                 &ett_smb_nt_share_access,
19263                 &ett_smb_nt_security_flags,
19264                 &ett_smb_nt_trans_setup,
19265                 &ett_smb_nt_trans_data,
19266                 &ett_smb_nt_trans_param,
19267                 &ett_smb_nt_notify_completion_filter,
19268                 &ett_smb_nt_ioctl_flags,
19269                 &ett_smb_security_information_mask,
19270                 &ett_smb_print_queue_entry,
19271                 &ett_smb_transaction_flags,
19272                 &ett_smb_transaction_params,
19273                 &ett_smb_find_first2_flags,
19274 #if 0
19275                 &ett_smb_ioflag,
19276 #endif
19277                 &ett_smb_transaction_data,
19278                 &ett_smb_stream_info,
19279                 &ett_smb_dfs_referrals,
19280                 &ett_smb_dfs_referral,
19281                 &ett_smb_dfs_referral_flags,
19282                 &ett_smb_get_dfs_flags,
19283                 &ett_smb_ff2_data,
19284                 &ett_smb_device_characteristics,
19285                 &ett_smb_fs_attributes,
19286                 &ett_smb_segments,
19287                 &ett_smb_segment,
19288                 &ett_smb_sec_desc,
19289                 &ett_smb_sid,
19290                 &ett_smb_acl,
19291                 &ett_smb_ace,
19292                 &ett_smb_ace_flags,
19293                 &ett_smb_sec_desc_type,
19294                 &ett_smb_quotaflags,
19295                 &ett_smb_secblob,
19296                 &ett_smb_mac_support_flags,
19297                 &ett_nt_access_mask,
19298                 &ett_nt_access_mask_generic,
19299                 &ett_nt_access_mask_standard,
19300                 &ett_nt_access_mask_specific,
19301                 &ett_smb_unicode_password,
19302                 &ett_smb_ea,
19303                 &ett_smb_unix_capabilities
19304         };
19305         module_t *smb_module;
19306
19307         proto_smb = proto_register_protocol("SMB (Server Message Block Protocol)",
19308             "SMB", "smb");
19309         proto_register_subtree_array(ett, array_length(ett));
19310         proto_register_field_array(proto_smb, hf, array_length(hf));
19311
19312         register_smb_common(proto_smb);
19313
19314         register_init_routine(&smb_init_protocol);
19315         smb_module = prefs_register_protocol(proto_smb, NULL);
19316         prefs_register_bool_preference(smb_module, "trans_reassembly",
19317                 "Reassemble SMB Transaction payload",
19318                 "Whether the dissector should reassemble the payload of SMB Transaction commands spanning multiple SMB PDUs",
19319                 &smb_trans_reassembly);
19320         prefs_register_bool_preference(smb_module, "dcerpc_reassembly",
19321                 "Reassemble DCERPC over SMB",
19322                 "Whether the dissector should reassemble DCERPC over SMB commands",
19323                 &smb_dcerpc_reassembly);
19324         prefs_register_bool_preference(smb_module, "sid_name_snooping",
19325                 "Snoop SID to Name mappings",
19326                 "Whether the dissector should snoop SMB and related CIFS protocols to discover and display Names associated with SIDs",
19327                 &sid_name_snooping);
19328
19329         register_init_routine(smb_trans_reassembly_init);
19330         smb_tap = register_tap("smb");
19331 }
19332
19333 void
19334 proto_reg_handoff_smb(void)
19335 {
19336         dissector_handle_t smb_handle;
19337
19338         gssapi_handle = find_dissector("gssapi");
19339         ntlmssp_handle = find_dissector("ntlmssp");
19340
19341         heur_dissector_add("netbios", dissect_smb_heur, proto_smb);
19342         heur_dissector_add("cotp", dissect_smb_heur, proto_smb);
19343         heur_dissector_add("vines_spp", dissect_smb_heur, proto_smb);
19344         smb_handle = create_dissector_handle(dissect_smb, proto_smb);
19345         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_SERVER, smb_handle);
19346         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_REDIR, smb_handle);
19347         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MESSENGER,
19348             smb_handle);
19349 }